Prolog - 一些基本的算术运算实现

时间:2016-03-19 13:45:36

标签: prolog successor-arithmetics non-termination

我是Prolog的新手,需要对自然数进行一些基本的算术运算,而不使用内置的谓词。

我在一元通知中表示自然数字Term,意味着我有常数0,递归后继函子 s [即4 = s(s(s(s(s))))]。关于上面的表示法,我实现了算术运算。

一套规则是:

% nat(N)/1 ---> N is a natural number
nat(0).
nat(s(X)) :-
    nat(X).

% add(X,Y,Z)/3 ---> Z = X + Y
add(X,0,X) :-
    nat(X).
add(X,s(Y),s(Z)) :-
    add(X,Y,Z).

% mult(X,Y,Z)/3 ---> Z = X * Y
mult(0,X,0) :-
    nat(X).
mult(s(X),Y,Z) :-
    mult(X,Y,XY),
    add(XY,Y,Z).

现在,当我查询:

?- mult(s(s(0)), s(s(s(0))), RES).

我把一切都搞定了:

RES = s(s(s(s(s(s(0))))))。

当我查询:(想问6/3 =?)

?- mult(X, s(s(s(0))), s(s(s(s(s(s(0))))))).

我陷入无限循环并获得S.O。

即使我在mult谓词中更改递归调用的顺序也没有帮助:

mult(s(X),Y,Z) :-
    add(XY,Y,Z),
    mult(X,Y,XY).

我在linux机器上运行swi-prolog。

非常感谢您的建议!

1 个答案:

答案 0 :(得分:0)

好的,有一个快速修复(错误的递归):

% add(X,Y,Z)/3 ---> Z = X + Y
add(0,X,X) :-
    nat(X).
add(s(X),Y,s(Z)) :-
    add(X,Y,Z).

然后是mult:

mult(s(X),Y,Z) :-
   add(XY,Y,Z),
   mult(X,Y,XY).

将给出期望的结果。

但是,对于查询:

?- mult(X,Y,s(s(s(s(s(s(0))))))).

它将输出所有对应的X,Y对应:X * Y = s(s(s(s(s(s(0)))))),在最后一对之后,将进入无限循环,原因不明。