0

私は swi-prolog で 2 水差しの問題を解決しようとしています: 容量がそれぞれ 4 ガロンと 3 ガロンの 2 つの水差しがある場合、容量 4 と 0 の水差しで 2 ガロンを取得する手順を見つけたいと思います。

bfs と dfs の両方を使用して C++ でこの問題のプログラムを作成しました: http://kartikkukreja.wordpress.com/2013/10/11/water-jug-problem/。今、私はプロローグで問題を解決しようとしています。私は言語にまったく慣れていないので、コードが終了しません。

これまでのコードは次のとおりです。

% state(0, 0) is the initial state
% state(2, 0) is the goal state
% Jugs 1 and 2 have capacities 4 and 3 respectively
% P is a path to the goal state
% C is the list of visited states

solution(P) :-
    path(0, 0, [state(0, 0)], P).

path(2, 0, [state(2, 0)|_], _).

path(0, 2, C, P) :-
not(member(state(2, 0), C)),
path(2, 0, [state(2, 0)|C], R),
P = ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R].

path(X, Y, C, P) :-
X < 4,
not(member(state(4, Y), C)),
path(4, Y, [state(4, Y)|C], R),
P = ['Fill the 4-Gallon Jug.'|R].

path(X, Y, C, P) :-
Y < 3,
not(member(state(X, 3), C)),
path(X, 3, [state(X, 3)|C], R),
P = ['Fill the 3-Gallon Jug.'|R].

path(X, Y, C, P) :-
X > 0,
not(member(state(0, Y), C)),
path(0, Y, [state(0, Y)|C], R),
P = ['Empty the 4-Gallon jug on ground.'|R].

path(X, Y, C, P) :-
Y > 0,
not(member(state(X, 0), C)),
path(X, 0, [state(X, 0)|C], R),
P = ['Empty the 3-Gallon jug on ground.'|R].

path(X, Y, C, P) :-
X + Y >= 4,
X < 4,
Y > 0,
NEW_Y = Y - (4 - X),
not(member(state(4, NEW_Y), C)),
path(4, NEW_Y, [state(4, NEW_Y)|C], R),
P = ['Pour water from 3-Gallon jug to 4-gallon until it is full.'|R].

path(X, Y, C, P) :-
X + Y >=3,
X > 0,
Y < 3,
NEW_X = X - (3 - Y),
not(member(state(NEW_X, 3), C)),
path(NEW_X, 3, [state(NEW_X, 3)|C], R),
P = ['Pour water from 4-Gallon jug to 3-gallon until it is full.'|R].

path(X, Y, C, P) :-
X + Y =< 4,
Y > 0,
NEW_X = X + Y,
not(member(state(NEW_X, 0), C)),
path(NEW_X, 0, [state(NEW_X, 0)|C], R),
P = ['Pour all the water from 3-Gallon jug to 4-gallon.'|R].

path(X, Y, C, P) :-
X + Y =< 3,
X > 0,
NEW_Y = X + Y,
not(member(state(0, NEW_Y), C)),
path(0, NEW_Y, [state(0, NEW_Y)|C], R),
P = ['Pour all the water from 4-Gallon jug to 3-gallon.'|R].

どんな助けでも大歓迎です。

4

1 に答える 1

0

Prolog の 'equal' 演算子は算術演算を実行しませんが、2 つの引数を統合します。(たとえば)これを置き換えてみてください

NEW_Y = Y - (4 - X)

NEW_Y is Y - (4 - X)

OT: また、Prolog は、他の言語と同様に、コード ファクタリングの恩恵を受けます:ほとんどのパス/4 ルールは同じパターンを公開するため、コードはヘルパー述語でよりクリーンになる可能性があります: 繰り返しますが、たとえば

path(0, 2, C, P) :-
  not(member(state(2, 0), C)),
  path(2, 0, [state(2, 0)|C], R),
  P = ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R].

になり得る

path(0, 2, C, ['Pour 2 gallons from 3-Gallon jug to 4-gallon.'|R]) :-
  upd_path(2, 0, C, R).

与えられた

upd_path(X, Y, C, R).
      not(member(state(X, Y), C)),
      path(X, Y, [state(X, Y)|C], R).

edit : 別の OT ヒント: member/2 の代わりに memberchk/2 を使用してください。より効率的であり、決定論的であるため、実行の追跡が容易になります。

editまた、再帰の基本ケースは説明のリストを閉じません:

path(2, 0, [state(2, 0)|_], []).
于 2013-11-01T14:29:04.623 に答える