首页 > 解决方案 > Prolog 前身数学

问题描述

我有一个add2谓词,它像这样解析ies(0)的继承者在哪里01

?- 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)))))

ETC..

我正在尝试添加一个前任谓词,它将像这样工作

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

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

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

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

我似乎找不到办法做到这一点。我的代码如下。

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


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


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

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

标签: prologsuccessor-arithmetics

解决方案


通常,使用后继算术相加意味着处理后继项,这些后继项具有形状0s(X)whereX也是后继项。这部分代码完全解决了这个问题:

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

现在你必须做出决定;您可以在此处处理前辈和附加术语add/3,或者您可以将此谓词包装在另一个将处理它们的谓词中。您似乎已选择add/3使用add2/3. 在这种情况下,您肯定需要创建一个缩减项,例如您在此处使用 构建的resolve/2,并且我同意您对其中一部分的实现:

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).

这一切都很好。您现在缺少的是一种处理p(X)条款的方法。正确的做法是注意你已经有一种减一的方法,通过使用add/3with s(0)

resolve(p(X), R) :-
    resolve(X, X1),
    add(s(0), R, X1).

换句话说,我们不是使用 X = Y - 1 来计算 X,而是使用 X + 1 = Y 来计算 X。

如果您的输入永远不会是负数,那么您的add2/3谓词现在就可以工作了。


推荐阅读