2

我已经看到了Prolog Prologue的定义between/3

between(Lower, Upper, Lower) :-
   Lower =< Upper.
between(Lower1, Upper, X) :-
   Lower1 < Upper,
   Lower2 is Lower1 + 1,
   between(Lower2, Upper, X).

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

between(Lower, Upper, Something):-
   Lower =< Upper,
   Lower =< Something,
   Something =< Upper.

我试过了gprolog,它可以工作,但只适用于简单的查询:

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

yes

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

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

我真的不明白为什么。

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

4

1 回答 1

5

一旦你知道Prolog 中的通用算法是做什么的,这个错误就不那么神秘了。简而言之,它只是做不合逻辑的“计算这个并给我答案”的算术。比较(所以所有的</2, =</2,=:=/2等)都要求两边都有算术表达式;is/2假设它在左边有一个算术表达式,在右边有一个自由变量。因此,您可以执行以下操作:

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

?- 1 =:= sin(pi/2).
true.

如果您真的足够仔细地阅读 GNU-Prolog 手册,您应该会在相关部分的开头找到以下两句话:

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

(强调我的)

between/3像, plus/3, or这样的谓词是特殊用途整数算术succ/2的例子。它们有它们的用途。但是,大多数用于实际整数数学的用途已被 CLPFD 取代。对于 GNU-Prolog,您应该查阅文档,但是对于一个简短的示例,要 emulate ,您可以说:between/3

?- fd_domain(X, 0, 2), fd_labeling(X).
X = 0 ? ;
X = 1 ? ;
X = 2
yes

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

于 2016-03-05T21:04:14.440 回答