2013-10-26 103 views
1

到目前爲止,我的程序可以將兩個數字加起來。執行謂詞減法

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 ..我錯了,但是。有人知道該怎麼辦?

回答

2

的每個數字只能在這3種方法之一來表示:

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