したがって、プロローグを使用した深さ優先検索アプローチを使用して、次の問題を解決しようとしています
次の問題を考えてみましょう: 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]
あり、目標状態であるかを実行しようとすると、「いいえ」という答えが返されます!! すべての状態を出力する深さ優先検索ソリューションの代わりに..など.
私はそれを追跡しようとしましたが、すぐに例外があると言われました。これを修正する方法はありますか?