介于 0 和数字序言之间的变量的多个值
Multiple values of a variable inbetween 0 and a number prolog
所以我一直在努力自学 prolog,我认为我进展顺利。但是,我有点卡在我正在尝试制作的这种方法上。
toN(N,A) A等于0到N-1之间的整数值,按升序生成
所以
toN(5,A) 将是
A = 0;
A = 1;
A = 2;
A = 3;
A = 4.
我还是 prolog 的新手,所以我不太确定如何使用多个值来执行此操作。我有这样的事情:
toN(N,A) :- 0 < N, Nx is N-1, toN(Nx,A).
toN(N,A) :- 0 =< N, Nx is N-1, A = Nx.
然而这只是 returns 错误。没有其他的。在我看来完全没问题
这样的事情应该在任意两个任意端点之间生成整数序列:
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
. %
有了这个通用工具,您可以简单地说:
to_n(N,A) :- sequence(0,N,A).
您的实施没有失败:通过回溯它产生从 -1
到 N-1
的数字
?- toN(5,A).
A = -1 ? ;
A = 0 ? ;
A = 1 ? ;
A = 2 ? ;
A = 3 ? ;
A = 4 ? ;
no
要消除 -1
,您只需将第二个子句中的 =<
替换为 <
,正如上面 @false 评论的那样。
另一种可能更具可读性的实现是
编辑: 插入条件 N>=0
以回答下面的@false 评论。
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).
检查您使用的 Prolog 实现是否支持 clpfd!
:- use_module(library(clpfd)).
toN/2
的实现变得声明式且超级简洁:
toN(N,A) :-
A #>= 0,
A #< N,
labeling([up],[A]).
您将在 clpfd 手册中找到更多标签选项:SWI-Prolog clpfd, SICStus Prolog clpfd。
所以我一直在努力自学 prolog,我认为我进展顺利。但是,我有点卡在我正在尝试制作的这种方法上。
toN(N,A) A等于0到N-1之间的整数值,按升序生成
所以 toN(5,A) 将是
A = 0;
A = 1;
A = 2;
A = 3;
A = 4.
我还是 prolog 的新手,所以我不太确定如何使用多个值来执行此操作。我有这样的事情:
toN(N,A) :- 0 < N, Nx is N-1, toN(Nx,A).
toN(N,A) :- 0 =< N, Nx is N-1, A = Nx.
然而这只是 returns 错误。没有其他的。在我看来完全没问题
这样的事情应该在任意两个任意端点之间生成整数序列:
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
. %
有了这个通用工具,您可以简单地说:
to_n(N,A) :- sequence(0,N,A).
您的实施没有失败:通过回溯它产生从 -1
到 N-1
?- toN(5,A).
A = -1 ? ;
A = 0 ? ;
A = 1 ? ;
A = 2 ? ;
A = 3 ? ;
A = 4 ? ;
no
要消除 -1
,您只需将第二个子句中的 =<
替换为 <
,正如上面 @false 评论的那样。
另一种可能更具可读性的实现是
编辑: 插入条件 N>=0
以回答下面的@false 评论。
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).
检查您使用的 Prolog 实现是否支持 clpfd!
:- use_module(library(clpfd)).
toN/2
的实现变得声明式且超级简洁:
toN(N,A) :-
A #>= 0,
A #< N,
labeling([up],[A]).
您将在 clpfd 手册中找到更多标签选项:SWI-Prolog clpfd, SICStus Prolog clpfd。