5

有没有一种简单的方法可以在 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

....

对我没用。

4

4 回答 4

4

您可以做的一件事是应用于setof/3生成解决方案的谓词。但请注意,这setof/3是通过应用于sort/2传递的结果来实现的bagof/3(至少在 SWI-Prolog 中是这种情况)。因此,如果您的解决方案生成器永远存在,那么setof/3将永远不会被应用......

所以我会说尝试编程以便不生成重复项,即在有意义的地方使用剪切(!)。

于 2009-04-07T12:43:48.397 回答
3

If I remember correctly there is a predicate solutions (or similar, it's been a while since I programmed Prolog) which collects unique solutions in a list.

Edit: setof/3 is the one I was thinking of. Thanks, Kaarel.

于 2009-04-07T08:34:33.347 回答
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
| ?- 
于 2009-04-07T13:22:34.997 回答
1

没有更多代码很难说,但您可能正在寻找剪切运算符 ( !)。如果您想发布 的定义foo我(或跟随的其他人)也许能够给出详细/具体的答案。

于 2009-04-07T06:39:28.227 回答