2010-10-19 47 views
0

J'ai une petite question. J'ai besoin de faire un prédicat qui compte d'un nombre naturel à un autre nombre naturel. Je dois aussi mettre en place une vérification, à savoir que le second intervalle est plus grand que le premier. Cependant je me suis coincé pendant mon chemin.Prolog, en comptant à partir d'un intervalle; (SWI-PROLOG)

Voici mon code (SWI-Prolog)

count(O, _, O). 
count(A, B, C) :- count(A, B, D), C is D+1, C =< B. 

Il genre de travaux ainsi que, je peux obtenir les résultats C=1, C=2, C=3, C=4 si je tape dans count(1, 4, C). Mais je suis coincé à la fin, il en résultera une erreur avec débordement de pile.

La question est comment puis-je faire pour arrêter? J'ai essayé presque tout. = (

Merci pour votre réponse

Répondre

0

Ce

count(A, B, C) :- count(A, B, D), ... 

provoque une récursion infinie

réordonner Juste le prédicat, comme ceci:!.

count(A, B, A) :- A =< B. 
count(A, B, C) :- A < B, A2 is A+1, count(A2, B, C). 
1

SWI-Prolog a un builtin pour cela ...

?- help(between). 
between(+Low, +High, ?Value) 
    Low and High are integers, High >=Low. If Value is an integer, 
    Low=< Value=< High. When Value is a variable it is successively 
    bound to all integers between Low and High. If High is inf 
    or infinite between/3 is true iff Value>= Low, a feature that is 
    particularly interesting for generating integers from a certain 
    value. 

true. 

?- between(1, 4, Value). 
Value = 1 ; 
Value = 2 ; 
Value = 3 ; 
Value = 4. 

?- 
0

Comme Paulo Moura souligné, réorganisation résoudra une partie du problème. L'obtenir pour se terminer gracieusement, peut être réalisé en ajoutant une clause supplémentaire pour gérer la condition de fin récursive.

Essayez ceci.

countAtoB(A,B,A) :- 
    A =:= B, !. 

countAtoB(A,B,A) :- 
    A < B. 

countAtoB(A,B,I) :- 
    A < B, 
    X is A+1, 
    countAtoB(X,B,I). 

Les requêtes ressembleraient à ceci. Par souci de comparaison, j'ai répété le même ensemble de requêtes de test en utilisant entre/3, détroit après.

?- countAtoB(1,4,I). 
I = 1 ; 
I = 2 ; 
I = 3 ; 
I = 4. 

?- countAtoB(4,4,I). 
I = 4. 

?- countAtoB(4,1,I). 
false. 

?- countAtoB(4,1,1000). 
false. 

?- between(1,4,I). 
I = 1 ; 
I = 2 ; 
I = 3 ; 
I = 4. 

?- between(4,4,I). 
I = 4. 

?- between(4,1,I). 
false. 

?- between(4,1,1000). 
false. 

?- 
+0

'countAtoB (9,1, I) .' réussit. Cela n'a pas beaucoup de sens. – false

+0

'countAtoB (9,1,1000) .' réussit également. – false

+0

Merci de l'avoir signalé. Il ne m'est jamais venu à l'esprit de vérifier les arguments invalides. J'ai examiné mon message et apporté les corrections appropriées. –