Comment puis-je obtenir la somme des chiffres donnés dans le prologue?
Je suis nouveau sur prolog et je suis en train de faire quelques exercices pour la pratique. Donc, je vais essayer d'obtenir la somme des chiffres donnés dans une liste. Je suis en train d'utiliser cette:
my_last(X, [X]).
my_last(X, [_|L]) :- my_last(X, L).
(à partir de ici)
que mon guide. C'est donc mon code pour obtenir la somme:
listsum(X, []).
listsum(X, [H|L]):-
X is H + listsum(X, L).
quand je compile, il dit
pratique.pl:3: évaluables
listsum(_G139,_G140)
n'existe pas
de pratique.pl:2: Singleton variables:[X]
puis quand j'essaie listsum(0, [1,2,3]).
il retourne false
.
Je ne comprends toujours pas beaucoup sur le prologue, et la liste et la récursivité dans prolog.
Pour les 2 nombres est aussi simple que cela: swish.swi-prolog.org/p/Sum%20of%20two%20digits.pl
OriginalL'auteur Zik | 2012-07-17
Vous devez vous connecter pour publier un commentaire.
Arithmétique
Comme vous l'avez déjà découvert, l'arithmétique peut être traité dans le Prologue avec le
(is)/2
de l'opérateur. C'est parce que dans le Prologue, tout est symbolique de calcul: les choses n'ont pas une signification par défaut, de sorte que l'unification(=)/2
ne sais pas qui(+)/2
se réfère à l'ajout par exemple.Maintenant, votre problème est que vous utilisez régulièrement un prédicat à l'intérieur de
(is)/2
(ici, c'est votre appel récursif). Depuis(is)/2
n'effectue de l'arithmétique, il se complique pas d'évaluer le prédicat d'appel. Il n'a même pas le reconnaître, car il n'est pas une fonction arithmétique.Le correctif ici serait d'affecter le résultat de l'appel récursif à une variable et ensuite l'utiliser dans le
(is)/2
appel:De la Base de cas de l'exactitude
Mais si vous testez ce code, vous n'obtiendrez pas le résultat souhaité. La raison en est que vous avez un autre problème, dans votre base de cas. La somme de la liste vide n'est pas "rien", comme vous l'avez indiqué par écrit
(
X
est une variable libre, donc peut être n'importe quoi).Au lieu de cela, il est
0
:Le code résultant est:
Ordre des arguments
Maintenant, au passage, dans le Prologue de la convention est que les variables de sortie doit être placée à la fin du prédicat, tandis que les variables d'entrée doit être mis au début du prédicat, de manière à se comporter comme des voulu nous pourrions refactoriser comme suit:
Queue Appeler L'Optimisation
Maintenant, nous pouvons encore améliorer ce prédicat avec des techniques plus avancées. On pourrait par exemple introduire la queue appels afin que la Queue d'Appel d'Optimisation (googlable) a pu être effectué grâce à un langage de programmation déclarative appelé un accumulateur:
L'idée derrière tout ça est de mettre à jour un résultat intermédiaire à chaque étape de la récursion (en ajoutant la valeur de l'actuel chef de la liste), puis juste dire que lorsque la liste est vide, cette valeur intermédiaire est la valeur finale.
Obtenir plus générale des programmes
Comme vous l'avez peut-être noté dans le Prologue, très souvent, les prédicats peuvent être utilisés de plusieurs façons. Par exemple,
length/2
peuvent être utilisés pour découvrir la longueur d'une liste:ou de construire un squelette liste avec les variables libres d'une longueur souhaitée:
Ici, vous pourriez avoir de noter que vous ne pouvez pas demander à Prologue de ce que sont les listes qui ont une somme qui est
6
:C'est parce que, à "revenir en arrière", Prologue aurait à résoudre une équation quand vient l'appel à la
(is)/2
de l'opérateur. Et tandis que le vôtre est simple (uniquement des ajouts), l'arithmétique n'est pas résoluble de cette façon, dans le cas général.Pour surmonter ce problème, programmation par contraintes peut être utilisé. Une très belle bibliothèque est disponible pour SWI, clpfd.
La syntaxe serait ici:
Maintenant, nous pouvons utiliser notre prédicat de cette façon, nous avons souhaité que nous puissions l'utiliser:
On pourrait même se demander pour toutes les solutions au problème:
J'ai juste mentionné que de sorte que vous vous rendez compte que, bien souvent, l'utilisation de
(is)/2
doit être évitée et l'utilisation de la programmation par contraintes doivent être privilégiées pour obtenir la plupart des programmes généraux.oh tant pis, j'ai oublié que c'est le cas de base
L'utilisation de cet éditeur en ligne: swish.swi-prolog.org
OriginalL'auteur m09
Si possible, utiliser les clpfd à la place de la plaine de vieux
(is)/2
(et amis).clpfd propose une logique pure de prédicat
sum/3
qui pourrait s'adapter à vos besoins!OriginalL'auteur repeat