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