介于 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).

您的实施没有失败:通过回溯它产生从 -1N-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 实现是否支持 !

:- use_module(library(clpfd)).

toN/2 的实现变得声明式且超级简洁:

toN(N,A) :- 
   A #>= 0, 
   A #<  N, 
   labeling([up],[A]).

您将在 clpfd 手册中找到更多标签选项:SWI-Prolog clpfd, SICStus Prolog clpfd