在Prolog中停止递归?

在Prolog中停止递归?,prolog,Prolog,那么现在在质疑的时候, connect(raj,isa,indian). connect(indian,isa,man). attribute(raj,marks,100). attribute(indian,marks,200). p(Node,marks,Number) :- attribute(Node,marks,Number). p(Node,marks,Number) :- connect(Node,isa,X), p(X,marks,Number). 在这

那么现在在质疑的时候,

connect(raj,isa,indian).
connect(indian,isa,man).

attribute(raj,marks,100).
attribute(indian,marks,200).

p(Node,marks,Number) :- 
   attribute(Node,marks,Number).
p(Node,marks,Number) :-
   connect(Node,isa,X),
   p(X,marks,Number).
在这种情况下,我希望
p(raj,marks,200)
失败


如何在得到第一个答案时停止递归?

我想您希望Prolog在确认这些示例为
真后不要提示更多解决方案?您可以通过切割来实现这一点,因为切割会在某一点修剪回溯:

171 ?- p(raj,marks,100).
true .

172 ?- p(raj,marks,200).
true .
现在,在确认解决方案后,您所述的问题不会像我认为您所问的那样出现倒退:

p(Node, marks, Number) :- 
   attribute(Node, marks, Number),
   !.                       % Don't backtrack after confirming the attribute
p(Node, marks, Number) :-
   connect(Node, isa, X),
   p(X, marks, Number).
但这带来了一个问题。谓词将不再找到查询的所有有效解决方案,
p(raj,marks,X)
它将在只找到一个后停止,即使还有更多

| ?- p(raj, marks, 100).

yes
| ?- p(raj, marks, 200).

(1 ms) yes
| ?-
如果我们从代码中删减(回到您的原始代码),它将给出正确的响应,并提供
X
的所有有效解决方案:

| ?- p(raj, marks, X).

X = 100

yes
| ?-
另一个获取所需结果的选项是使用
once/1
谓词,该谓词将只查找第一个解决方案,然后停止回溯:

| ?- p(raj, marks, X).

X = 100 ? ;

X = 200 ? ;

no
| ?-
现在,我们还没有打破
p/3
查询,并且有一种方法可以在没有回溯的情况下获得第一个解决方案。如果愿意,您可以围绕此构建单独的谓词:

| ?- once(p(raj,marks,100)).

(1 ms) yes
| ?-
然后,当然:

p_once(Node, Marks, Number) :- once(p(Node, Marks, Number)).

但在我看来,显式使用
一次/1
是首选,因为它简洁明了,目的明确,同时保留了原始谓词的完整性。

这两个查询都运行得很好。你发布了错误的查询吗?Raj的分数应该是100分,应该是200分。当我得到100时,如何停止递归?但是prolog不会“抛出false”。当它得到第一个答案时就停止了。您的程序对
p(raj,marks,200)有效。
-事实
connect(raj,isa,indian)和
属性(indian,marks,200)`使规则生效。IMO@Enigmativity是正确的。怎么了?!看,我已经编辑了这个问题。为什么不走正道呢?问题是IMHO在不同的层面(建模、表示)
(!)/0
有它的用途,但鼓励初学者从一开始就采用“糟糕的编码+快速修复”的风格,你不同意吗?重复一遍,相反,我不鼓励使用cut。我在解释为什么这不是个好主意。我相信我的回答正是你的评论所表达的观点(见开头,但这会带来一个问题)!为什么投反对票?好吧,说得好。我只是检查了我的投票记录和我的声誉信息;根据这两份报告,我今天没有投任何反对票。@重复一遍,好的,谢谢。这只是一个同时发生的事件。很抱歉不知道是谁或者为什么我从那时起就被否决了。我不太在乎。我可能会删除答案。不要删除,乘法!让每一个都有自己的优点和缺点,有一个清晰、简单的信息。
| ?- p_once(raj,marks,100).

(1 ms) yes
| ?-