2

したがって、プロローグを使用した深さ優先検索アプローチを使用して、次の問題を解決しようとしています

次の問題を考えてみましょう: Rowena は、3 オンス、5 オンス、および 8 オンスの異なるサイズの 3 つのマークのないグラスを持っています。一番大きなグラスがいっぱいです。大きい 2 つのグラスのそれぞれに 4 オンスの液体を入れるには、ロウェナはどうすればよいでしょうか?

私は移動状態とすべてを行い、オンラインで見つかった深さ優先検索のバージョンを使用しました。これまでのところコードは次のとおりです

%stack 
empty_stack([]).
member_stack(E, S) :- member(E, S).
stack(E, S, [E|S]).



go(Start, Goal) :-
    empty_stack(Empty_been_list),
    stack(Start, Empty_been_list, Been_list),
    path(Start, Goal, Been_list).

    % path implements a depth first search in PROLOG

    % Current state = goal, print out been list
path(Goal, Goal, Been_list) :-
    reverse_print_stack(Been_list).

path(State, Goal, Been_list) :-
    move(State, Next), 
    \+ (member_stack(Next, Been_list)),
    stack(Next, Been_list, New_been_list),
    path(Next, Goal, New_been_list), !.

reverse_print_stack(S) :-
    empty_stack(S).
reverse_print_stack(S) :-
    stack(E, Rest, S),
    reverse_print_stack(Rest),
    write(E), nl.

%move rule #1: Pour Large into Medium (L--> M) 
%move(oldstate,newstate)

move([L, M, S], [NewLarge,NewMedium,S]) :-
L > 0, %We can't pour from large if Large is empty
M < 5, %We can't pour into the medium if medium is full
Diff is min(5 - M, L),
  Diff > 0,
  NewLarge is L - Diff, %calculate the new Large
  NewMedium is M + Diff. %calculate the new Medium 

% move rule #2: Pour Large into Small (L--> S)

move([L, M, S], [NewLarge,M,NewSmall]) :-
L > 0, %We can't pour from large if Large is empty
S < 3, %We can't pour into the small if small is full
Diff is min(5 - S, L),
  Diff > 0,
  NewLarge is L - Diff, %calculate the new Large
  NewSmall is S + Diff. %calculate the new Small

% move rule #3: Pour Medium into Large (M--> L)

move([L, M, S], [NewLarge,NewMedium,S]) :-
L < 8, %We can't pour into the large if the large is full
M > 0, %We can't pour from Medium if medium is empty
Diff is min(8 - L, M),
  Diff > 0,
  NewMedium is M - Diff, %calculate the new Medium
  NewLarge is L + Diff. %calculate the new Large 


% move rule #4: Pour Medium into small (M--> S)
move([L, M, S], [L, NewMedium,NewSmall]) :-
M > 0, %We can't pour from Medium if Medium is empty
S < 3, %We can't pour into the small if small is full
Diff is min(5 - S, M),
  Diff > 0,
  NewMedium is M - Diff, %calculate the new Medium
  NewSmall is S + Diff. %calculate the new Small


% move rule #5: Pour small into large (S--> L)

move([L, M, S], [NewLarge,M,NewSmall]) :-
L < 8, %We can't pour into the large if the large is full
S > 0, %We can't pour from Small if Small is empty
Diff is min(8 - L, S),
  Diff > 0,
  NewSmall is S - Diff, %calculate the new Small
  NewLarge is L + Diff. %calculate the new Large 


% move rule #6: Pour small into medium (S --> M)

move([L, M, S], [L,NewMedium,NewSmall]) :-
M < 5, %We can't pour into the large if the large is full
S > 0, %We can't pour from Medium if medium is empty
Diff is min(8 - M, S),
  Diff > 0,
  NewSmall is S - Diff, %calculate the new Small
  NewMedium is M + Diff. %calculate the new Medium 

これでコンパイルが完了しましたが、go([8,0,0],[4,4,0])どこ[8,0,0]が初期状態で[4,4,0]あり、目標状態であるかを実行しようとすると、「いいえ」という答えが返されます!! すべての状態を出力する深さ優先検索ソリューションの代わりに..など.

私はそれを追跡しようとしましたが、すぐに例外があると言われました。これを修正する方法はありますか?

4

0 に答える 0