首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查数字是否为三角形

检查数字是否为三角形
EN

Stack Overflow用户
提问于 2020-04-18 05:52:02
回答 1查看 115关注 0票数 1

所以我有这个谓词三角形(N),其中N是一个数字,如果一个数字是一个三角形数字,这个谓词返回true。

我的问题是,由于某种原因,我的谓词执行了一个无限循环,而不是只对数字求和,直到N。

示例:

-三角形(3)。3真

而且它不会结束。

所以基本上这是打印数字的和直到3,但它做了一些我不理解的事情。

程序:

代码语言:javascript
复制
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).
EN

回答 1

Stack Overflow用户

发布于 2020-04-18 12:17:33

背景信息

Prolog可以为您的查询搜索多个解决方案。

考虑这个程序:

代码语言:javascript
复制
human(alice).
human(bob).

当您查询?- human(X).时,Prolog将搜索与您的程序匹配的X工作分配。它将向您显示解决方案X = alice。之后,您可以通过按.停止搜索,也可以通过按;继续搜索。如果继续,Prolog将找到X = bob。之后,它将停止,因为它已经用尽了所有可能的解决方案:

代码语言:javascript
复制
?- human(X).
X = alice .

?- human(X).
X = alice ;
X = bob.

您可以使用cut谓词!控制搜索过程。cut谓词切断当前层中的替代路径。因此,如果您使用以下规则扩展上述程序:

代码语言:javascript
复制
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.再次禁用):

代码语言:javascript
复制
?- 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
...

您可以通过将最后一个规则更改为:

代码语言:javascript
复制
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约束不成立而无法应用最后一个规则。然后它停止搜索:

代码语言:javascript
复制
?- triangular(3).
3
true ;
false.

我们可以使用上一节中显示的cut谓词!进一步简化这一过程,方法是将write规则修改为:

代码语言:javascript
复制
triangular(N,AC,0) :-  write(AC), !.

这告诉Prolog不要搜索triangular(3,3,0)的替代解决方案。当您运行查询?- triangular(3).时,Prolog应该像以前一样写出3,然后退出而不进行进一步的搜索:

代码语言:javascript
复制
?- triangular(3).
3
true.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61281322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档