在prolog中定义中缀二进制运算符时遇到问题

在prolog中定义中缀二进制运算符时遇到问题,prolog,operators,swi-prolog,Prolog,Operators,Swi Prolog,我刚刚接触序言。我想定义一个中缀二进制运算符“rA”,当我给出矩形的宽度和宽度时,它会给出矩形的面积。这是我的代码: :-op(300, xfy, rA). rA(X,Y,R) :- R is X*Y. 当我这样做时,代码运行良好: 1 ?- rA(3,4,A). A = 12. 我搞不懂的是将其定义为中缀二进制运算符。我得到这个错误: 2 ?- A is 3 rA 4. ERROR: evaluable `3 rA 4' does not exist 谢谢在标准Prolog中无法执

我刚刚接触序言。我想定义一个中缀二进制运算符“rA”,当我给出矩形的宽度和宽度时,它会给出矩形的面积。这是我的代码:

:-op(300, xfy, rA).

rA(X,Y,R) :- R is X*Y.
当我这样做时,代码运行良好:

1 ?- rA(3,4,A).
A = 12. 
我搞不懂的是将其定义为中缀二进制运算符。我得到这个错误:

2 ?- A is 3 rA 4.
ERROR: evaluable `3 rA 4' does not exist 

谢谢

在标准Prolog中无法执行此操作。然而,SWI Prolog过去支持算术函数的用户定义,但我认为,在最近的版本中,该功能已被弃用。检查文档。一种可能的替代方法是利用几个Prolog系统(包括SWI Prolog)定义的术语扩展机制和目标扩展
is/2
goals来处理使用用户定义的算术函数的调用。比如:

goal_expansion(X is Expression, X is ExpandedExpression) :-
    % traverse and transform Expression
但是请记住,
goal_expansion/2
会被反复调用,直到达到一个固定点。因此,请注意,尝试扩展已扩展的算术表达式时会产生无休止的循环。解决此问题的一种方法是使用动态谓词缓存扩展的结果,该谓词在调用
goal\u expansion/2
时被选中。缓存动态谓词可以取消,例如,当您正在处理的文件结束时:

term_expansion(end_of_file, _) :-
    abolish(...), % the argument will be the predicate indicator of the caching predicate
    fail.

当扩展
end\u of_文件时,建议在执行任何必要的操作后失败,因为可能还有其他(正交)扩展也依赖于
end\u of_文件的扩展,无论如何,以下是一个详细信息示例,用于向SWI Prolog说明您的函数:

22 ?- [user].
|: :- arithmetic_function(rA/2).
|: rA(X,Y,Z) :- Z is X*Y.
% user://1 compiled 0.07 sec, 3 clauses
true.

23 ?- F is rA(3,6).
F = 18.

24 ?- [user].
|: :-op(300,xfx,rA).
% user://2 compiled 0.02 sec, 1 clauses
true.

25 ?- F is 3 rA 6.
F = 18.

不是到处都能用的。例如,gprolog 1.4.4似乎没有目标扩展/2和扩展目标/2。术语扩展机制既不是通用的,也不是标准的(这就是为什么我写了“几个”(Prolog系统),而不是“全部”或“大多数”。如果您正在寻找一个可移植的术语扩展解决方案,Logtalk提供了一个在最现代和最受积极支持的Prolog系统上运行的解决方案。是的,当然。如果您定义的表达式需要谓词调用,
X is E
将转换为
G,X is E'
。今天刚刚跳过了一个旧示例,其中SWI Prolog允许定义关于可评估函数的定义,请参见此处:。例如,box mueller需要一个目标。