使用Peano数字在Prolog中递归添加并不起作用

时间:2017-11-21 19:14:25

标签: prolog successor-arithmetics

我目前正在尝试练习一些Prolog。我刚刚开始,我遇到了一个我不太了解的问题。我想以递归方式确定一个Peano数是另一个的两倍。我试着像这样解决它:

isDouble(0, X,X).
isDouble(s(Peano1), Peano1, Peano2) :-
    isDouble(Peano1, s(Peano1), Peano2).

由于某种原因,它不起作用。有谁知道为什么?

1 个答案:

答案 0 :(得分:5)

您不需要三个参数来定义这样的谓词。只要考虑它应该描述的关系:数字与其双重之间的关系。因此,您只需要两个参数和两个描述两种可能性的规则。数字为零,则其double也为零。否则,在每次递归中,对于double,只有两个s / 2,但只有一个用于数字:

nat_double(0,0).
nat_double(s(X),s(s(Y))) :-
   nat_double(X,Y).

这产生了预期的结果:

?- nat_double(X,Y).
X = Y, Y = 0 ;                     % X=0, Y=0
X = s(0),                          % X=1
Y = s(s(0)) ;                      % Y=2
X = s(s(0)),                       % X=2
Y = s(s(s(s(0)))) ;                % Y=4
X = s(s(s(0))),                    % X=3
Y = s(s(s(s(s(s(0)))))) ;          % Y=6
X = s(s(s(s(0)))),                 % X=4
Y = s(s(s(s(s(s(s(s(0)))))))) ;    % Y=8
.
.
.

或者,如果您想按照评论中的建议测试一对:

?- nat_double(s(s(0)),s(s(s(s(0))))).
true.

编辑:

如果您坚持使用界面isDouble / 3,正如您的评论所示,那么您可以将其定义为nat_double / 2的调用谓词,如下所示:

isDouble(X,X,Y) :-
   nat_double(X,Y).

这会为您的示例产生所需的结果:

?- isDouble(s(s(0)),s(s(0)),s(s(s(s(0))))).
true.