I have a small question. I need to make a predicate that counts from a natural number to some other natural number. I have to implement a check too, that the second interval is bigger than the first one. However I got stuck during my way.
Here is my code (SWI-PROLOG)
count(O, _开发者_如何学JAVA, O).
count(A, B, C) :- count(A, B, D), C is D+1, C =< B.
It works kind of well as, I can get the results C=1, C=2, C=3, C=4
if I type in count(1, 4, C).
However I get stuck at the end, it will result in an error with stack overflow.
The question is how do I make it to stop? I have tried almost everything. =(
Thanks for your response!
SWI-Prolog has a builtin for that...
?- 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.
?-
As Paulo Moura pointed out, re-ordering will solve part of the problem. Getting it to terminate gracefully, may be achieved by adding an additional clause to handle the recursive terminating condition.
Try this.
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).
Queries would then look like this. For the sake of comparison, I have repeated the same set of test queries using between/3, strait after.
?- 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.
?-
This
count(A, B, C) :- count(A, B, D), ...
causes an infinite recursion.
Just reorder the predicate, like this:
count(A, B, A) :- A =< B.
count(A, B, C) :- A < B, A2 is A+1, count(A2, B, C).
精彩评论