/ 3之间可以不递归吗?

Jul*_*ano 2 prolog instantiation-error

我看过Prolog Prologue的定义between/3:

between(Lower, Upper, Lower) :-
   Lower =< Upper.
between(Lower1, Upper, X) :-
   Lower1 < Upper,
   Lower2 is Lower1 + 1,
   between(Lower2, Upper, X).
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它需要递归.逻辑定义between可以是:

between(Lower, Upper, Something):-
   Lower =< Upper,
   Lower =< Something,
   Something =< Upper.
Run Code Online (Sandbox Code Playgroud)

我试过它gprolog并且它可以工作,但仅用于简单的查询:

| ?- between(0,5,1).

yes
Run Code Online (Sandbox Code Playgroud)

对于带变量的查询,我得到:

| ?- between(0,5,X).
uncaught exception: error(instantiation_error, (=<)/2)
Run Code Online (Sandbox Code Playgroud)

我真的不明白为什么.

我有点像Prolog需要某种参考数字来统一变量,但为什么会出现神秘错误(=<)/2?

小智 5

一旦你知道Prolog中的通用算法是什么,那么错误并不是那么神秘.简而言之,它只是做非逻辑的,"计算这个并给我答案"的算术类型.比较(因此所有的</2,=</2,=:=/2等),需要你有算术表达式两侧; is/2假设它在左侧有一个算术表达式,在右边有一个自由变量.所以,你可以这样做:

?- X is 3^1.3.
X = 4.171167510947728.

?- 1 =:= sin(pi/2).
true.
Run Code Online (Sandbox Code Playgroud)

如果你真的仔细阅读了GNU-Prolog手册,你应该在相关章节的开头找到以下两句话:

算术表达式是由表示算术函数的数字,变量和函子(或运算符)构建的Prolog术语.在计算表达式时,每个变量必须绑定到非变量表达式.

(强调我的)

谓词类似于between/3,plus/3或是特殊用途整数运算的succ/2示例.他们有自己的用途.但是,实际整数数学的大多数用法已被CLPFD取代.对于GNU-Prolog,你应该查阅文档,但是为了一个简单的例子,你可以说:between/3

?- fd_domain(X, 0, 2), fd_labeling(X).
X = 0 ? ;
X = 1 ? ;
X = 2
yes
Run Code Online (Sandbox Code Playgroud)

你应该注意到这绝对不是递归的(回答标题中的问题).当然,我们都知道,在某种程度上,涉及递归或迭代,以获得这些答案.