2

我是 Prolog 的新手,需要在不使用内置谓词的情况下对自然数实现一些基本的算术运算。

我用一元表示法表示自然数 Term,这意味着我有常数 0 和递归后继仿函数s [即 4 = s(s(s(s(0))))]。关于上述符号,我实现了算术运算。

规则集是:

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

我陷入了无限循环并得到了如此

即使我更改了 mult 谓词中递归调用的顺序,它也无济于事:

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

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

将感谢您的建议!

4

1 回答 1

1

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

% 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 = s(s(s(s(s(s(0)))))) 的所有 X,Y 对,并且在最后一对之后,将进入无限循环,对于对我来说未知的原因。

于 2016-03-19T14:22:53.190 回答