是否有一种简单的方法可以在prolog中进行查询,只返回一次结果?
例如我正在尝试这样的事情:
deadly(Xn) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xn)), safe(Xp).
deadly(Xp) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xp)), safe(Xn).
deadly(X).
并获得
X = 5
X = 5
X = 5
X = 5
....
对我没用。
答案 0 :(得分:4)
您可以做的一件事是将setof/3
应用于生成解决方案的谓词。但请注意,setof/3
是通过将sort/2
应用于bagof/3
提供的结果来实现的(至少在SWI-Prolog中就是这种情况)。因此,如果您的解决方案生成器永远存在,则永远不会应用setof/3
...
所以我会说尝试编程,以便不生成重复项,即使用切割(!),这是有道理的。
答案 1 :(得分:3)
如果我没记错的话,有一个谓词解决方案(或类似的,自我编写Prolog以来已经有一段时间了),它会在列表中收集唯一的解决方案。
编辑: setof/3
是我想到的那个。谢谢,卡雷尔。
答案 2 :(得分:3)
另一种方法是记住解决方案。
:- dynamic seen/1.
% Call this always before calling deadly_wrapper/1
clear_seen :-
retractall(seen(_)).
% This wrapper calls deadly/1 but remembers
% the solution using assert/1, and fails
% if the solution has been "seen" before.
deadly_wrapper(X) :-
deadly(X),
(
seen(X)
->
fail
;
assert(seen(X))
).
% This is for testing.
deadly(1).
deadly(1).
deadly(1).
deadly(5).
deadly(1).
deadly(1).
如果您的Prolog支持制表,那么它会变得更简单。 示例文件:
:- table deadly/1.
deadly(1).
deadly(1).
deadly(5).
deadly(1).
deadly(5).
使用XSB执行示例:
$ xsb
[xsb_configuration loaded]
[sysinitrc loaded]
XSB Version 3.2 (Kopi Lewak) of March 15, 2009
[x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam;
scheduling: local; word size: 64]
| ?- [deadly_tab].
[Compiling ./deadly_tab]
[deadly_tab compiled, cpu time used: 0.0100 seconds]
[deadly_tab loaded]
yes
| ?- deadly(X).
X = 5;
X = 1;
no
| ?-
答案 3 :(得分:1)
如果没有更多代码,很难说,但您可能正在寻找切割运算符(!
)。如果您要发布foo
的定义,我(或其他关注者)可能会提供详细/具体的答案。