我正在尝试编写一个函数 -它按降序decListRange(X,List)
给出范围内的列表。[X-1:1]
例如 -
decListRange(9,List).
会给 -
List = [8,7,6,5,4,3,2,1].
我尝试了以下但它进入无限循环 -
decListRange(1,[]) :- !.
decListRange(X,[H|Rest]) :-
H = X-1, NextX = X - 1 ,decListRange(NextX,Rest).
我正在尝试编写一个函数 -它按降序decListRange(X,List)
给出范围内的列表。[X-1:1]
例如 -
decListRange(9,List).
会给 -
List = [8,7,6,5,4,3,2,1].
我尝试了以下但它进入无限循环 -
decListRange(1,[]) :- !.
decListRange(X,[H|Rest]) :-
H = X-1, NextX = X - 1 ,decListRange(NextX,Rest).
你有两个问题。第一个真正的问题是您需要使用is
而不是=
:
H is X-1
这是触发算术评估所必需的。您的第二个问题不是真正的问题,而是说明了一个更大的误解,那就是H
并且NextX
是等效的。因为 Prolog 只有绑定而不是“可赋值”,所以您永远不需要创建两个具有相同绑定的“变量”。没有保留状态供您以后修改。
清理两个你得到这个:
decListRange(1, []) :- !.
decListRange(X, [H|Rest]) :-
X > 1,
H is X-1,
decListRange(H, Rest).
编辑 2:clpfd 实现
:- use_module(library(clpfd)).
declist(N, L) :- N == 1, !, L = []. % green cut
declist(1, []).
declist(N, [N1|Ns]) :-
N #> 1,
N1 #= N - 1,
declist(N1, Ns).
这个具有@false 在评论中提到的属性:
?- declist(3, L).
L = [2, 1] ;
false.
?- declist(3, [2,1]).
true ;
false.
?- declist(N, [3,2,1]).
N = 4.
?- declist(N, X).
N = 1,
X = [] ;
N = 2,
X = [1] ;
N = 3,
X = [2, 1] ;
N = 4,
X = [3, 2, 1] ;
N = 5,
X = [4, 3, 2, 1] .
编辑=
:关于和之间区别的简短插曲is
。
在过程语言=
中,几乎总是将特定值分配给变量的语法。在 Prolog 中,变量是绑定,一旦建立,就不能通过重新分配不同的值来直接修改它们。相反,它们更像数学和逻辑中的变量,其中变量“代表”有趣的值,但这些值本身基本上是不可变的。在 Prolog 中,=
本质上是要求统一引擎建立绑定。因此,如果您要执行以下操作:
?- name(X, Y) = name(bob, tony).
Prolog 以变量绑定响应:
X = bob,
Y = tony.
一旦存在这些绑定,矛盾的绑定将失败,而肯定的绑定将成功:
?- name(X, Y) = name(bob, tony), X = bob.
X = bob,
Y = tony.
?- name(X, Y) = name(bob, tony), X = william.
false.
统一算法本身对算术一无所知。这具有令人愉快的副作用,您可以使用任何原始表达式。例如:
?- Expr = X + 3, Z + Q = Expr.
Expr = Z+3,
X = Z,
Q = 3.
这可能真的很令人惊讶。你可能会期望 Prolog 足够聪明地保留表达式,因为它注意到 X 是一个变量或其他东西,但这也不是真的:
?- X = 4, Expr = X + 3, Z + Q = Expr.
X = 4,
Expr = 4+3,
Z = 4,
Q = 3.
另一种看待这一点的方式是,Prolog 认为+
只是另一个运算符,所以这样X+3
的事实add(X, 3)
并不一定有任何特殊含义。无论您以哪种方式看待它,is/2
运算符的存在都是为了应用算术推理并产生一个值:
?- X = 4, Expr is X + 3.
X = 4,
Expr = 7.
请注意,Expr 具有计算值,但没有原始结构:
?- X = 4, Expr is X + 3, Z + Q = Expr.
false.
在实践中,如果您需要对算术进行大量推理,您将需要使用类似clpfd
或clpqr
取决于您是否对整数或实数感兴趣的库。该库使您能够更轻松地做更多有趣的事情,例如指定一个方程对某个范围内的值成立并取出这些值。