我正在使用SWI Prolog,我的作业中使用了以下代码(代码不是作业,但需要编写课程所需的方法):
nat(0).
nat(s(X)) :-
nat(X).
plus(0,N,N) :-
nat(N).
plus(s(M),N,s(Z)) :-
plus(M,N,Z).
times(0,N,0) :-
nat(N).
times(s(M),N,Z) :-
times(M,N,W),
plus(W,N,Z).
exp(s(M),0,0) :-
nat(M).
exp(0,s(M),s(0)) :-
nat(M).
exp(s(N),X,Z) :-
exp(N,X,Y),
times(X,Y,Z).
exp(a,b,c)
表示c=b^a
。
直接从书中复制:“Prolog的艺术:高级编程技巧”。
当我运行以下查询时:
exp(s(s(0)),L,s(s(s(s(0))))).
我得到了答案:
L = s(s(0))
但是当我通过进入而要求另一个答案时;
L = s(s(0)) ;
我得到一个无限循环(以堆栈错误结束),我期待得到错误。
代码中有什么问题?是否存在相同的代码(具有相同的自然数字表示)但行为与我描述的方式相同?如果是这样,一些指示或建议会有很大的帮助。
提前致谢。
答案 0 :(得分:0)
它运行到给定程序的无限循环是正常的:如果你调用exp/3
,在第二个元素未被实例化的情况下,它会开始分支L
的所有可能值。换句话说,如果您查询:
exp(s(s(0)),L,s(s(s(s(0))))).
它充当:
我将
L
实例化为s(0)
,s(0)
(因此1)是否正确?
没有!我将L
实例化为s(s(0))
2是否正确? 是,返回2
。等等,用户要求更多答案....3
是否正确?没有
4
是否正确?没有
是正确的? (你明白了)
每次尝试时,堆栈都会更深一层(因为它需要一个级别来构建s(X)
而不是X
...
您可以尝试使用另一种方式:存在逻辑上限:结果(第三个参数),因此您可以首先将第二个参数实例化为第三个参数并测试然后递减第二个参数,直到找到正确的结果。