问题
So I've been trying to teach myself prolog and I think I'm coming along nicely. However, I'm sort of stuck at this one method I'm trying to make.
toN(N,A) A is equal to the integer values between 0 and N-1, generated in ascending order.
so toN(5,A) would be
A = 0;
A = 1;
A = 2;
A = 3;
A = 4.
I'm still new to prolog so I'm not exactly sure how to do this with multiple values. I had something like this:
toN(N,A) :- 0 < N, Nx is N-1, toN(Nx,A).
toN(N,A) :- 0 =< N, Nx is N-1, A = Nx.
However this just returns false. Nothing else. It seems perfectly fine to me
回答1:
Check if the Prolog implementation that you are using supports clpfd!
:- use_module(library(clpfd)).
The implementation of toN/2
gets declarative and super-concise:
toN(N,A) :-
A #>= 0,
A #< N,
labeling([up],[A]).
You'll find more labeling options in the clpfd manual: SWI-Prolog clpfd, SICStus Prolog clpfd.
回答2:
Something like this should generate the sequence of integers between any two arbitrary endpoints:
sequence(X,Y,X) :- % to generate the integers between X and Y,
integer(X) , % - the starting point must be bound
integer(Y) , % - the endpoint must be bound
range(X,Y,Z) % - then we just invoke the worker
. %
range(X,X,X) . % hand back the last item in the sequence if X and Y have converged.
range(X,Y,X) :- % otherwise, return an item
X =\= Y . % - if X and Y haven't converged.
range(X,Y,Z) :- % otherwise,
X < Y , % - if X < Y ,
X1 is X+1 , % - increment X
range(X1,Y,Z) % - and recurse down.
. %
range(X,Y,Z) :- % otherwise
X > Y , % - if X > Y
X1 is X-1 , % - decrement X
range(X1,Y,Z) % - and recurse down
. %
With that general-purpose tool, you can simply say:
to_n(N,A) :- sequence(0,N,A).
回答3:
Your implementation does not fail: by backtracking it yields numbers from -1
to N-1
?- toN(5,A).
A = -1 ? ;
A = 0 ? ;
A = 1 ? ;
A = 2 ? ;
A = 3 ? ;
A = 4 ? ;
no
To eliminate the -1
you should just replace =<
by <
in your second clause as @false commented above.
An alternative implementation, maybe more readable, would be
Edit: inserted condition N>=0
in answer to @false comment below.
toN(N,A) :-
N >= 0,
toN(0,N,A).
toN(K,N,K).
toN(K,N,A) :-
K < N-1,
Kn is K+1,
toN(Kn,N,A).
来源:https://stackoverflow.com/questions/30113105/multiple-values-of-a-variable-inbetween-0-and-a-number-prolog