微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Prolog中的一阶谓词逻辑:使用签名和算术术语

如何解决Prolog中的一阶谓词逻辑:使用签名和算术术语

我正在使用Prolog中的术语和签名(一阶谓词逻辑)。

我已获得签名(∅,Z,{add(2),sub(2),mult(2)})。因此没有变量,常量是整数,并且功能是“加”,“子”和“多”。

目标是写谓词“ calc / 2”,该谓词采用一个术语(基于上面的签名)并根据整数的加法,减法和乘法的通常定义进行计算。示例:

?- calc( add(sub(8,2),mult(4,-3)),N).
N = -6

((((8-2)+(4 ∗ -3))= -6)

问题与 this question 类似,但有一个很大的不同,就是我需要避免使用= ..运算符来查找函数名称。相反,我想利用Prolog在规则参数上使用模式匹配的事实,这是我完全坚持的。要注意的另一件事是,“ add”,“ sub”和“ mult”不应被视为谓词。

我使用= ..运算符的第一个解决方案是(借助上面链接的线程的答案):

op(+,add).
op(-,sub).
op(*,mult).

calc(Term,N) :-
    calc2(Term,Expr),N is Expr.

calc2(N,N) :- integer(N).
calc2(Term,Expr) :-
    Term =.. [Op_str,Comp1,Comp2],op(Op,Op_str),calc2(Comp1,Expr1),calc2(Comp2,Expr2),Expr =.. [Op,Expr1,Expr2].

但是由于这不是我正在寻找的解决方案类型,因此对我的问题没有太大帮助。

我可以很容易地执行单个计算(例如calc(add(1,N)),但是我要处理比这更复杂的事情。

解决方法

要使用模式匹配并避免使用univ运算符= ..,可以像这样重写calc2 / 2:

calc2(add(Op1,Op2),Expr1 + Expr2) :- 
    calc2(Op1,Expr1),calc2(Op2,Expr2).
calc2(sub(Op1,Expr1 - Expr2) :-
    calc2(Op1,Expr2).
calc2(mult(Op1,Expr1 * Expr2) :-
    calc2(Op1,Expr2).

这使代码更直观,其中可以通过单独的子句处理其他情况(例如,幂)。另外,现代的编译器可以优化生成的代码。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。