'is/2' Prolog 谓词是如何实现的?我知道
X is 3*4
相当于
is(X, 3*4)
但是谓词是使用命令式编程实现的吗?换句话说,实现是否等同于以下 C 代码?
if(uninstantiated(x))
{
X = 3*4;
}
else
{
//signal an error
}
还是使用声明式编程和其他谓词来实现?
'is/2' Prolog 谓词是如何实现的?我知道
X is 3*4
相当于
is(X, 3*4)
但是谓词是使用命令式编程实现的吗?换句话说,实现是否等同于以下 C 代码?
if(uninstantiated(x))
{
X = 3*4;
}
else
{
//signal an error
}
还是使用声明式编程和其他谓词来实现?
显然,取决于您的 Prolog,但任何实际的实现都将在 C 或其他命令式语言中完成其肮脏的工作。部分is/2
可以在纯Prolog中模拟:
is(X, Expr) :-
evaluate(Expr, Value),
(var(X) ->
X = Value
;
X =:= Value
).
evaluate
知道算术表达式的巨大谓词在哪里。也有一些方法可以在纯 Prolog 中实现大部分内容,但这既缓慢又痛苦。例如,如果您有一个添加整数的谓词,那么您也可以使用以下(愚蠢的)算法将它们相乘:
evaluate(X + Y, Value) :-
% even this can be done in Prolog using an increment predicate,
% but it would take O(n) time to do n/2 + n/2.
add(X, Y, Value).
evaluate(X * Y, Value) :-
(X == 0 ->
Value = 0
;
evaluate(X + -1, X1),
evaluate(X1, Y, Value1),
evaluate(Y + Value1, Value)
).
这些都不能保证是实际的或正确的;我只是在展示如何在 Prolog中实现算术。
取决于 Prolog 的版本;例如,CProlog(不出所料)是用 C 编写的,因此所有内置谓词都是用命令式语言实现的。
Prolog 是为语言解析而开发的。所以,像这样的算术表达式
3 + - ( 4 * 12 ) / 2 + 7
after parsing 只是一个序言词(代表解析树),operator/3
提供语义来指导解析器的操作。对于基本的算术表达式,术语是
'-'/2
. 否定'*'/2
, '/'/2
. 乘法、除法'+'/2
, '-'/2
. 加法、减法上面的示例表达式被解析为
'+'( '+'( 3 , '/'( '-'( '*'(4,12) ) , 2 ) ) , 7 )
'is'/2
只需对表示右侧的解析树进行递归遍历,以几乎与 RPN(反向波兰表示法)计算器相同的方式评估每个术语。一旦对该表达式求值,结果将与左侧统一。
每个基本操作(加、减、乘、除等)都必须在机器代码中完成,因此在一天结束时,将调用一些机器代码例程来计算每个基本操作的结果。
无论is/2
是完全用本机代码编写还是主要用 prolog 编写,只用本机代码编写叶操作,这几乎都是一种实现选择。