0

我正在使用 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)) ;

我得到一个无限循环(以堆栈外错误结束),我希望得到错误。

代码中的问题是什么?是否有相同的代码(具有相同的自然数表示)但行为方式与我描述的方式相同?如果是这样,一些指示或建议会很有帮助。

提前致谢。

4

1 回答 1

0

对于给定程序,它运行到无限循环是正常的:如果您调用exp/3,在第二个元素未实例化的情况下,它开始分支L. 换句话说,如果您查询:

exp(s(s(0)),L,s(s(s(s(0))))).

它充当:

我实例化Ls(0)s(0)(因此 1)是否正确?
不!我实例化为2 正确吗L? 是的回报。等等,用户要求更多的答案.... 是正确的吗?否正确吗 ?不 ……对吗?(你明白了)s(s(0))
2
3
4

每次尝试时,堆栈都会增加一层(因为它需要再一层来s(X)构建X......

您可以尝试使用另一种方式:有一个逻辑上界:结果(第三个参数),因此您可以首先将第二个参数实例化为第三个参数并进行测试,然后减少第二个参数,直到找到正确的结果。

于 2015-03-31T11:07:49.360 回答