搜索时,Prolog 会给出正确答案,但在搜索另一个之前会重复 N 次

When searching, Prolog gives correct answers but repeats them N times before searching another

好的,所以我有这个 Prolog 代码,它代表了一个不断发展的方块世界,并且有一个机械臂可以同时移动 1 个方块,还有 2 个小机器人 "rob and bor" 可以绘制方块当方块位于塔顶或塔底时,它们指定的颜色(条件见代码)。函数 clear(X) 当方块 X 在塔顶时为真,当 X 在 table(在塔底)时 ontable(X) 为真。单块塔 return clearontabletrue。 该代码旨在在询问特定状态时逐步给出所有解决方案(就像单个塔上的所有 4 个块并涂成红色)。 为此,定义了一组动作和事实,它们的条件作用(当动作 A 在条件 C 下完成时,事实 F 会发生什么)和 possibility/reality 使用函数 poss(returns true if some action is possible to do) and holds(returns true if some fact is true) 适用于每个状态 S。legal 是这些的混合2(如果其中的一切都成立并且是可能的,那么它就是合法的)。

%% Object Declaration (problem-specific)
block(B) :- member(B,[a,b,c,d]).

% colors available for rob and bor
color(rob,B) :- member(B,[blue]).
color(bor,B) :- member(B,[red]).

%% Initial Situation (problem-specific)
holds(F,s0) :- member(F,[on(a,b),on(b,c),ontable(c), ontable(d), clear(a), clear(d)]).
holds(color(B,white),s0) :- block(B).

%% Blocks World Preconditions (domain-specific)
%% action move_to_block(X,Z) moves block X on top of block Z
% poss is true when its possible to do the action.
poss(move_to_block(X,Z),S) :-
    holds(clear(X),S), holds(clear(Z),S), Z\=X, \+ holds(on(X,Z),S).

poss(move_to_table(X),S) :-
    holds(clear(X),S), \+ holds(ontable(X),S).

%% Robot R paints block B of color C

poss(paint(rob,B,C),S) :-
     color(rob,C),holds(clear(B),S), \+ holds(color(B,C),S).



poss(paint(bor,B,C),S) :-
    color(bor,C), holds(ontable(B),S), \+ holds(color(B,C),S).


%% Blocks World Effects (domain-specific)
% is_conditional_negative_effect(Act,Cond,Fact)
% when Act is peformed and Cond holds, Fact becomes false

is_conditional_negative_effect(move_to_block(X,_),on(X,Y),on(X,Y)).
is_conditional_negative_effect(move_to_block(X,_),ontable(X),ontable(X))
is_conditional_negative_effect(move_to_block(X,Z),true,clear(Z)).
is_conditional_negative_effect(move_to_table(X),on(X,_),on(X,_)).
is_conditional_negative_effect(paint(R,B,C),color(B,D),color(B,D)).
% is_conditional_positive_effect(Act,Cond,Fact)
% when Act is peformed and Cond holds, Fact becomes true
is_conditional_positive_effect(move_to_block(X,_),on(X,Y),clear(Y)).
is_conditional_positive_effect(move_to_block(X,Z),true ,on(X,Z)).
is_conditional_positive_effect(move_to_block(X,_),true,clear(X)).
is_conditional_positive_effect(move_to_table(X),true ,ontable(X)).
is_conditional_positive_effect(move_to_table(X),on(X,Y),clear(Y)).
is_conditional_positive_effect(move_to_table(X),true,clear(X)).
is_conditional_positive_effect(paint(R,B,C),color(B,_),color(B,C)).

holds(true,s0). % "true" always holds

holds(F,do(A,S)) :-
         holds(F,S),
         \+ (is_conditional_negative_effect(A,C,F), holds(C,S)).

holds(F,do(A,S)) :-
    is_conditional_positive_effect(A,C,F),holds(C,S).

% S is legal if it is the result of performing executable actions
legal(s0).
legal(do(A,S)) :-
    legal(S),
    poss(A,S).

所以事情是,当像下面这样进行咨询时(time() 只使给定的答案 return 是处理时间,为了优化......这是另一个问题,我会检查后来):

time((legal(S), holds(on(b,d),S), holds(on(c,b),S), holds(on(a,c),S), holds(color(b,blue),S), holds(color(a,red),S))).

到目前为止我得到了正确的答案,但在给出另一个答案之前重复了 10 次(也是正确的),所以如果我想要所有的答案,我必须粉碎 ;像一万次。我已经花了大约 3 个小时来尝试解决这个问题,因为它不允许我检查我是否得到了所有正确的答案或缺少某些东西。你们知道这是怎么回事吗? 试图让一切尽可能清楚,但如果您需要我澄清一些事情,请发表评论!

最后,在朋友的帮助下,我们设法解决了这个问题,问题出在积极的条件效应上,特别是与 clear 相关的那些。这些肯定是显而易见的,因为一个块在被移动之前必须已经 return 符合 clear

is_conditional_positive_effect(move_to_block(X,_),true,clear(X)).
is_conditional_positive_effect(move_to_table(X),true,clear(X)).

我还更改了一些条件,使其更具体,这些极大地提高了搜索性能:

is_conditional_negative_effect(move_to_table(X),on(X,_),on(X,_)).

取代
is_conditional_negative_effect(move_to_table(X),on(X,Y),on(X,Y)).

is_conditional_positive_effect(paint(R,B,C),color(B,_),color(B,C)).

取代
is_conditional_positive_effect(paint(R,B,C),true,color(B,C)).

感谢我的伙伴 Pablo。