所以我有这个谓词三角形(N),其中N是一个数字,如果一个数字是一个三角形数字,这个谓词返回true。
我的问题是,由于某种原因,我的谓词执行了一个无限循环,而不是只对数字求和,直到N。
示例:
-三角形(3)。3真
而且它不会结束。
所以基本上这是打印数字的和直到3,但它做了一些我不理解的事情。
程序:
triangular(N) :- triangular(N,0).
triangular(N,AC) :- triangular(N,AC,N).
triangular(N,AC,0) :- write(AC).
triangular(N,AC,CONT) :- NCONT is CONT - 1,
NAC is AC + NCONT,
triangular(N,NAC,NCONT).发布于 2020-04-18 12:17:33
背景信息
Prolog可以为您的查询搜索多个解决方案。
考虑这个程序:
human(alice).
human(bob).当您查询?- human(X).时,Prolog将搜索与您的程序匹配的X工作分配。它将向您显示解决方案X = alice。之后,您可以通过按.停止搜索,也可以通过按;继续搜索。如果继续,Prolog将找到X = bob。之后,它将停止,因为它已经用尽了所有可能的解决方案:
?- human(X).
X = alice .
?- human(X).
X = alice ;
X = bob.您可以使用cut谓词!控制搜索过程。cut谓词切断当前层中的替代路径。因此,如果您使用以下规则扩展上述程序:
find_first_human(X) :- human(X), !.运行查询?- find_first_human(X).只会输出X = alice.,而不会搜索更多的答案。Prolog知道human(X)可以通过多种方式解决,但是!告诉Prolog忽略这些替代方案。
将这一点应用于您的程序
主要问题是您的最后一个triangle谓词不需要CONT > 0。因此,当您查询?- triangle(3).时,Prolog最终会到达与您的write规则相匹配的triangular(3,3,0).。如您所见,您的程序按预期输出3。然而,Prolog随后看到了triangular(3,3,0)的替代解决方案,因此它允许您继续搜索。可以通过按.键停止,也可以通过按;键继续。如果继续,Prolog将尝试triangular的最后一个规则,并将CONT解析为0。这样,NCONT就变成了-1。然后,这将进入无限循环,重复应用最后一个triangular规则,递减CONT而不会结束。
您可以使用trace.验证这一点(可以使用notrace.再次禁用):
?- trace.
?- triangular(3).
Call: (8) triangular(3) ? creep
Call: (9) triangular(3, 0) ? creep
Call: (10) triangular(3, 0, 3) ? creep
...
Call: (13) triangular(3, 3, 0) ? creep
Call: (14) write(3) ? creep
3
Exit: (14) write(3) ? creep
Exit: (13) triangular(3, 3, 0) ? creep
...
true ;
Redo: (13) triangular(3, 3, 0) ? creep
Call: (14) _2076 is 0+ -1 ? creep
Exit: (14) -1 is 0+ -1 ? creep
...您可以通过将最后一个规则更改为:
triangular(N,AC,CONT) :- CONT > 0,
NCONT is CONT - 1,
NAC is AC + NCONT,
triangular(N,NAC,NCONT).这将禁止Prolog将规则应用于triangular(3,3,0)。当您使用修改后的程序运行查询?- triangular(3).时,Prolog在到达triangular(3,3,0)时应该像以前一样写出3。之后,它会检测到可能存在其他解决方案。如果按;,则会检测到由于CONT > 0约束不成立而无法应用最后一个规则。然后它停止搜索:
?- triangular(3).
3
true ;
false.我们可以使用上一节中显示的cut谓词!进一步简化这一过程,方法是将write规则修改为:
triangular(N,AC,0) :- write(AC), !.这告诉Prolog不要搜索triangular(3,3,0)的替代解决方案。当您运行查询?- triangular(3).时,Prolog应该像以前一样写出3,然后退出而不进行进一步的搜索:
?- triangular(3).
3
true.https://stackoverflow.com/questions/61281322
复制相似问题