实现谓词减法

时间:2013-10-26 16:25:34

标签: prolog

到目前为止,我的程序可以将两个数字加在一起。

s(0)代表1s(s(0))代表2,依此类推

p(0)代表-1p(p(0))代表-2等。

我希望能够调用一个程序

add2(s(s(0)), p(0), Z).

返回

Z = s(0).

我的代码如下:

numeral(0).
numeral(s(X)) :- numeral(X).

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

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

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

numeral(p(X)) :- numeral(X).

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

我的逻辑是,如果列表中有p(s(0)),它只会将其等同于0。但是我错了。有人知道该去哪儿吗?

1 个答案:

答案 0 :(得分:2)

每个数字只能用以下三种方式之一表示:

  • 0 - null;
  • s(X) - 接下来,其中X是数字;
  • p(X) - 之前,其中X是数字;

add2/3应该取2个数字并返回它们的总和。可以为每个可能的参数手动定义:

add2(0, 0, 0).
add2(0, s(X), Y) :- Y = s(X).
add2(0, p(X), Y) :- Y = p(X).

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

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

效果很好:

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

值得注意的是,add2/3规则的许多案例实际上是重叠的,可以消除:

add2(0, X, X).
add2(X, 0, X).

add2(s(X), s(Y), Z) :- add2(X, Y, s(s(Z))).
add2(s(X), p(Y), Z) :- add2(X, Y, Z).

add2(p(X), s(Y), Z) :- add2(X, Y, Z).
add2(p(X), p(Y), Z) :- add2(X, Y, p(p(Z))).