【问题标题】:Prolog Successor ArithmeticProlog 后继算法
【发布时间】:2017-11-06 17:02:38
【问题描述】:

我有以下知识库:

numeral(0).
numeral(s(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).

add(0,X,X).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

add2(W+X,Y+Z,R) :- add(W,X,A),add(Y,Z,T),add2(A,T,R).
add2(X+Y,Z,R) :- add(X,Y,A),add2(A,Z,R).
add2(X,Y+Z,R) :- add(Y,Z,A),add2(X,A,R).
add2(X,Y,R) :-  add(X,Y,R).

正确评估查询,例如:

?- add2(s(0)+s(s(0)), s(s(0)), Z).
Z = s(s(s(s(s(0)))))

?- add2(0, s(0)+s(s(0)), Z).
Z = s(s(s(0)))

?- add2(s(s(0)), s(0)+s(s(0)), Z).
Z = s(s(s(s(s(0)))))

但是,以下查询被评估为:

?- add2(s(0)+s(0), s(0+s(s(0))), Z).
Z = s(s(s(0+s(s(0))))) .

但是需要的输出是:

?- add2(s(0)+s(0), s(0+s(s(0))), Z).
Z = s(s(s(s(s(0)))))

我知道问题出在以下行:

add2(W+X,Y+Z,R) :- add(W,X,A),add(Y,Z,T),add2(A,T,R).

但我就是想不通。任何帮助将不胜感激!

【问题讨论】:

  • 您还需要在前两个调用中递归调用add2/3。所以使用add2(W+X,Y+Z,R) :- add2(W,X,A),add2(Y,Z,T),add2(A,T,R).。但是如果你想要一个纯粹的 Prolog 实现,你需要更彻底地改变代码。
  • 该实现的输出没有任何变化。
  • 形式有点奇特。为什么在两个不同的参数中进行内联加法,然后将它们加在一起会带来额外的复杂性?

标签: prolog successor-arithmetics


【解决方案1】:

我认为您通过使用add2/3 谓词处理案例会使问题更加复杂。您首先需要将前两个参数的结构解析为 s(s(...s(0)...)) 形状的东西。

为了做到这一点,我们可以创建一个 resolve/2 函数来查找 (+)/2 术语并递归地使用 add/3

resolve(0,0).
resolve(s(X),s(Y)) :-
    resolve(X,Y).
resolve(X+Y,Z) :-
    resolve(X,RX),
    resolve(Y,RY),
    add(RX,RY,Z).

现在是语法:

E -> 0
E -> s(E)
E -> E + E

resolve/2 会将其转换为语法:

E -> 0
E -> s(E)

例如:

?- resolve(s(0)+s(0),X).
X = s(s(0)).

?- resolve(s(0+s(s(0))),X).
X = s(s(s(0))).

现在我们的add2/3 谓词将首先resolve/2 操作数,然后将它们加在一起:

add2(A,B,C) :-
    resolve(A,RA),
    resolve(B,RB),
    add(RA,RB,C).

然后您编写的示例查询解析为:

?- add2(s(0)+s(s(0)), s(s(0)), Z).
Z = s(s(s(s(s(0))))).

?- add2(0, s(0)+s(s(0)), Z).
Z = s(s(s(0))).

?- add2(s(s(0)), s(0)+s(s(0)), Z).
Z = s(s(s(s(s(0))))).

?- add2(s(0)+s(0), s(0+s(s(0))), Z).
Z = s(s(s(s(s(0))))).

【讨论】:

  • 非常感谢您简化了方法。我知道我的方法是不必要的复杂。欣赏解释!
  • 假设 i 将符号 p 作为负数引入,这样查询的计算结果就像 ?- add2(p(0)+s(s(0)),s(s(0)) ,Z)。 Z = s(s(s(0))) 是否可以扩展您以前的解决方案,还是需要对代码进行重大更改?
  • 我想通了。谢谢@Willem
  • @oreillsf:抱歉,没在线:s.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
相关资源
最近更新 更多