0

J'utilise SWI Prolog, le code suivant est utilisé dans mes devoirs (le code est le travail à domicile, mais nécessaire pour écrire les méthodes au cours nécessite):Prolog se inifini en demandant une autre solution

nat(0). 
nat(s(X)) :- 
    nat(X). 

plus(0,N,N) :- 
    nat(N). 
plus(s(M),N,s(Z)) :- 
    plus(M,N,Z). 

times(0,N,0) :- 
    nat(N). 
times(s(M),N,Z) :- 
    times(M,N,W), 
    plus(W,N,Z). 

exp(s(M),0,0) :- 
    nat(M). 
exp(0,s(M),s(0)) :- 
    nat(M). 
exp(s(N),X,Z) :- 
    exp(N,X,Y), 
    times(X,Y,Z). 

exp(a,b,c) signifie c=b^a.

Il est copié directement à partir du livre: "L'art de Prolog: Techniques avancées de programmation".

Quand je lance la requête suivante:

exp(s(s(0)),L,s(s(s(s(0))))). 

Je reçois une réponse:

L = s(s(0)) 

Mais quand je demande une autre réponse en entrant; Je reçois une boucle infinie (se terminant par une erreur hors pile), je m'attendais à obtenir faux.

Quel est le problème dans le code? Y at-il un code qui fait la même chose (avec la même représentation des nombres naturels) mais se comporte comme je l'ai décrit? et si oui, quelques conseils ou suggestions seraient d'une grande aide.

Merci d'avance.

+0

de 'exp/3'. Moyens' exp (a, b, c) '' c = b^a'? –

+0

oui, je l'ai ajouté à la question – PrologNewb

+0

[Relié] (http://stackoverflow.com/questions/9740271/prolog-predicate-infinite-loop). – false

Répondre

0

Il est normal qu'il s'exécute dans une boucle infinie pour le programme donné: si vous appelez exp/3, alors que le second élément n'est pas instancié, il commence à se ramifier sur toutes les valeurs possibles pour L. En d'autres termes, si vous interrogez:

exp(s(s(0)),L,s(s(s(s(0))))). 

Il agit comme:

J'instancier L-s(0), est s(0) (donc 1) correcte?
Non! J'instancie L à s(s(0)) est 2 correct?
Oui return 2. Attendez, l'utilisateur demande plus de réponses ....
Est-ce que 3 est correct? Non
Est-ce que 4 est correct? Non
Est-ce que ... est-ce correct? (Vous voyez l'idée)

Chaque fois que vous faites une tentative, la pile est Ressuscité niveau plus profond (car il a besoin d'un niveau plus pour construire s(X) sur X ...

Vous pouvez essayer de d'une autre manière: il y a un upperbound logique: le résultat (troisième argument), donc vous pouvez d'abord instancier le deuxième argument comme le troisième et tester, puis décrémenter le second argument jusqu'à ce que vous trouviez le bon résultat

+0

Je vous remercie de la réponse rapide, je comprends pourquoi il va dans une boucle infinie maintenant, mais je suis un peu confus au sujet de votre suggestion, par souci de simplicité considère l'exemple que j'ai donné ci-dessus, voulez-vous dire que je comme s (s (s (s (0)))) = 4, puis je devrais tester 4^2 =? 4, non -> 3^2 =? 4, non-> 2^2 =? 4, oui. ->; -> 2^1 =? 4, non, 2^0 =? 4, non -> faux. ? – PrologNewb