6

私は「オオカミ ヤギ キャベツ」という名前のパズル ゲームに取り組んでいます。プログラミング言語は Prolog です。

change(e,w).
change(w,e).
move([X,X,Goat,Cabbage],wolf,[Y,Y,Goat,Cabbage]) :- change(X,Y).
move([X,Wolf,X,Cabbage],goat,[Y,Wolf,Y,Cabbage]) :- change(X,Y).
move([X,Wolf,Goat,X],cabbage,[Y,Wolf,Goat,Y]) :- change(X,Y).
move([X,Wolf,Goat,Cabbage],nothing,[Y,Wolf,Goat,Cabbage]) :- change(X,Y).

oneeq(X,X,WW).
oneeq(X,WWW,X).

safe([Man,Wolf,Goat,Cabbage]) :-
        oneeq(Man,Goat,Wolf),
        oneeq(Man,Goat,Cabbage).

wgc([e,e,e,e],[]).

wgc(Config,[FirstMove|OtherMoves]) :-
        move(Config,FirstMove,NextConfig),
        safe(NextConfig),
        wgc(NextConfig,OtherMoves).

それを機能させるために、呼び出す length(X,7),wgc([w,w,w,w],X).と結果が表示されます。問題は、最初の結果と 2 番目の結果が何度も表示されることです。

X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, wolf, goat, cabbage, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
X = [goat, nothing, cabbage, goat, wolf, nothing, goat] ;
false.

両方の結果を一度だけ表示する方法は? 追加してみた!wgc への記号:

wgc(Config,[FirstMove|OtherMoves]) :-
        move(Config,FirstMove,NextConfig),
        safe(NextConfig),
        wgc(NextConfig,OtherMoves), !.

...しかし、最初の結果は 1 回しか表示されません。それを修正する方法はありますか?

4

2 に答える 2

7

ここで冗長な回答/解決策が得られます。a (終了) の冗長な回答を排除するには、Goal単にそのゴールを でラップします。setof(t, Goal, _). 最後の引数は just_であることに注意してください[t]

?- length(X,7), setof(t, wgc([w,w,w,w],X), _) .
X = [ヤギ、何もない、キャベツ、ヤギ、オオカミ、何もない、ヤギ] ;
X = [ヤギ、何もない、オオカミ、ヤギ、キャベツ、何もない、ヤギ].

これは、答えがグラウンドアンサーである限り機能します。

@SergeyDymchenko が提案するように明示的にリスト内のソリューションを収集するには、そのリストに新しい変数名を付け、すべてのソリューションを単一のリストで表す必要があります。これは、これを実装に任せるよりもコストがかかる可能性があります。ただし、この具体的なケースでは、固有の違いはありません。

于 2013-01-28T07:55:40.480 に答える
4

述語を使用setofして、一意のソリューションのリストを取得できます。

setof(X, (length(X,7),wgc([w,w,w,w],X)), Sols).

X = X
Sols = [[goat, nothing, cabbage, goat, wolf, nothing, goat], [goat, nothing, wolf, goat, cabbage, nothing, goat]]
Yes (0.00s cpu)
于 2013-01-27T21:08:02.317 に答える