0

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

s(0)代表1s(s(0))代表2等等

p(0)代表-1, p(p(0))is-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.. 但是我错了。有人知道该去哪里吗?

4

1 回答 1

1

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

  • 0- 无效的;
  • 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))).
于 2013-10-27T07:54:15.497 回答