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).
Run Code Online (Sandbox Code Playgroud)
所以现在,在查询时,
171 ?- p(raj,marks,100).
true .
172 ?- p(raj,marks,200).
true .
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想p(raj,marks,200)失败.
在获得第一个答案时如何停止递归?
我想你在确认这些例子之后,是不是希望Prolog不要提示更多解决方案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).
Run Code Online (Sandbox Code Playgroud)
现在,在确认解决方案之后,正如我认为您要求的那样,您所提出的查询不会回溯:
| ?- p(raj, marks, 100).
yes
| ?- p(raj, marks, 200).
(1 ms) yes
| ?-
Run Code Online (Sandbox Code Playgroud)
但这提出了一个问题.您的谓词将不再找到查询的所有有效解决方案p(raj, marks, X).它只会在找到一个之后停止,即使还有更多.
| ?- p(raj, marks, X).
X = 100
yes
| ?-
Run Code Online (Sandbox Code Playgroud)
如果我们从代码中删除(返回原始代码),它会为所有有效的解决方案提供正确的响应X:
| ?- p(raj, marks, X).
X = 100 ? ;
X = 200 ? ;
no
| ?-
Run Code Online (Sandbox Code Playgroud)
获得结果的另一个选择是使用once/1谓词,它只会寻找第一个解决方案,然后停止回溯:
| ?- once(p(raj,marks,100)).
(1 ms) yes
| ?-
Run Code Online (Sandbox Code Playgroud)
现在,我们还没有打破p/3查询,并且有办法在没有回溯的情况下获得第一个解决方案.如果您愿意,可以围绕此构建一个单独的谓词:
p_once(Node, Marks, Number) :- once(p(Node, Marks, Number)).
Run Code Online (Sandbox Code Playgroud)
然后,当然:
| ?- p_once(raj,marks,100).
(1 ms) yes
| ?-
Run Code Online (Sandbox Code Playgroud)
但once/1在我看来,明确使用是首选,因为它简洁明了,并且保留了原始谓词的完整性.
| 归档时间: |
|
| 查看次数: |
1135 次 |
| 最近记录: |