between/3可以不递归吗?
Can between/3 not be recursive?
我看过 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
上的神秘错误?
一旦您知道 Prolog 中的通用算术 是做什么的,错误就不是那么神秘了。简而言之,它只是用来做 non-logical、"calculate this and give me the answer" 之类的算术运算。比较(所以所有 </2
、=</2
、=:=/2
等)要求你在两边都有 算术表达式; is/2
假设它左边是一个算术表达式,右边是一个自由变量。因此,您可以执行以下操作:
?- X is 3^1.3.
X = 4.171167510947728.
?- 1 =:= sin(pi/2).
true.
如果你真的仔细阅读了GNU-Prolog手册,你应该会发现,在relevant section的开头,有下面两句话:
An arithmetic expression is a Prolog term built from numbers, variables, and functors (or operators) that represent arithmetic functions. When an expression is evaluated each variable must be bound to a non-variable expression.
(强调我的)
between/3
、plus/3
或 succ/2
等谓词是 特殊用途整数算法 的示例。他们有他们的用途。然而,大多数用于进行实际整数数学运算的用途已被 CLPFD 取代。对于 GNU-Prolog,你应该 consult the documentation,但举个简短的例子,要模拟 between/3
,你可以说:
?- fd_domain(X, 0, 2), fd_labeling(X).
X = 0 ? ;
X = 1 ? ;
X = 2
yes
你应该注意到这绝对是不是递归的(回答标题中的问题)。当然,我们都知道在某种程度上,为了得到这些答案,涉及到递归或迭代。
我看过 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
上的神秘错误?
一旦您知道 Prolog 中的通用算术 是做什么的,错误就不是那么神秘了。简而言之,它只是用来做 non-logical、"calculate this and give me the answer" 之类的算术运算。比较(所以所有 </2
、=</2
、=:=/2
等)要求你在两边都有 算术表达式; is/2
假设它左边是一个算术表达式,右边是一个自由变量。因此,您可以执行以下操作:
?- X is 3^1.3.
X = 4.171167510947728.
?- 1 =:= sin(pi/2).
true.
如果你真的仔细阅读了GNU-Prolog手册,你应该会发现,在relevant section的开头,有下面两句话:
An arithmetic expression is a Prolog term built from numbers, variables, and functors (or operators) that represent arithmetic functions. When an expression is evaluated each variable must be bound to a non-variable expression.
(强调我的)
between/3
、plus/3
或 succ/2
等谓词是 特殊用途整数算法 的示例。他们有他们的用途。然而,大多数用于进行实际整数数学运算的用途已被 CLPFD 取代。对于 GNU-Prolog,你应该 consult the documentation,但举个简短的例子,要模拟 between/3
,你可以说:
?- fd_domain(X, 0, 2), fd_labeling(X).
X = 0 ? ;
X = 1 ? ;
X = 2
yes
你应该注意到这绝对是不是递归的(回答标题中的问题)。当然,我们都知道在某种程度上,为了得到这些答案,涉及到递归或迭代。