1

私は3つの水差しの水問題を解決する必要がありますが、少しトリックがあります。アルゴリズムを使用する必要はありませんが、ユーザーが水差しから別の水差しにリットルを移動できるようにする「関数」があります。彼によっても。

たとえば、彼はinitial(10,0,0,0、r)を書き込み、最初の状態は最初の10リットルで、他の2つはゼロです。また、final(0,3,3,3、l)とfinalを書き込みます。状態は、2つの小さい水差しに3リットル、最初の水差しにゼロがあります。

水差しの間の「移動」は、彼がgo(7,3、r)と書いたときに発生します。ここで、彼は3リットルを右に移動します(右から左に、水差しは大きくなり、小さくなります)。は残りのリットル、3は移動するリットル、rは方向です-。

そして、私はこのプロローグコードを書きましたが、すべてのgo-stateはfalseです。

:- dynamic go/3.
:- dynamic cur_state/1,init/5.
:- dynamic end_state/1, final/5.

cur_state(State):-State = state(10,0,0,7,l).
end_state(State):-State = state(0,3,3,0,r).

pour(state(D1,D2,D3,N,l),move(D,C,r),state(D,C,D3,N,r)) :-
        D is D1-N,
        C is D2+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D,C,D3,N,l)) :-
        D is D1-N,
        C is D2.
pour(state(D1,D2,D3,N,l),move(D,C,r),state(D,D2,C,N,r)) :-
        D is D1-N,
        C is D3+N.
pour(state(D1,D2,D3,N,l),move(D,C,r),state(D1,D,C,N,r)) :-
        D is D2-N,
        C is D3+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D1,D,C,N,l)) :-
        D is D2-N,
        C is D1+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D1,D,c,N,l)) :-
        D is D2-N,
        C is D3.
pour(state(D1,D2,D3,N,l),move(D,C,r),state(C,D2,D,N,r)) :-
        D is D3-N,
        C is D1.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D1,C,D,N,l)) :-
        D is D3-N,
        C is D2+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(C,D2,D,N,l)) :-
        D is D3-N,
        C is D1+N.

carry(7,0).
carry(3,0).
carry(10,0).
carry(4,0).
carry(7,3).

legal(10,X,Y):-X+Y=<10.
legal(X,Y,Z):-X+Y+Z=<10.
legal(X,7,Y):-X+Y=<3.
legal(X,Y,3):-X+Y=<7.

newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
        carry(M,C),
        M=<7,C=<3,
        D22 is D2+N,
        D11 is D1-N,
    D3 is D33,
    N1 is N,
        D2=<7,D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
        carry(M,C),
        M=<10,C=<100,
        D11 is D1-N,
    D22 is D2,
    D33 is D3,
        D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
        carry(M,C),
        M=<10,C<3,
        D11 is D1-N,
        D33 is D3+N,
    D22 is D2,
        D1=<10,D3=<3,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
        carry(M,C),
        M=<7,C=<3,
        D22 is D2-N,
        D33 is D1+N,
        D11 is D1,
        D2=<7,D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
        carry(M,C),
        M=<7,C=0,
        D22 is D2-N,
        D33 is D3+N,
        D11 is D1,
    D2=<7,D3=<3,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
        carry(M,C),
        M=<7,C=<100,
        D22 is D2-N,
    D33 is D3,
    D11 is D1,    
    D2=<7,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
        carry(M,C),
        M=<3,C=<7,
        D22 is D2+N,
        D33 is D3-N,
        D11 is D1,
    D3=<3,D2=<7,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
        carry(M,C),
        M=<3,C=<100,
        D11 is D1+N,
        D33 is D3-N,
        D22 is D2,
    D3=<3,D1=<10,
    legal(D1,D2,D3).

newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
        carry(M,C),
        M=<3,C=<100,
        D33 is D3-N,
        D22 is D2,
    D11 is D1,  
    D3=<3,
    legal(D1,D2,D3).


eisodos(_):- cur_state(State),write(State),nl.

init(S1,S2,S3,S4,S5):-assert(cur_state(State):-State =                 state(S1,S2,S3,S4,S5)),write('Arxikh:'),
write(state(S1,S2,S3,S4,S5)),retractall(init(S1,S2,S3,S4,S5)),nl.

final(S1,S2,S3,S4,S5):-assert(end_state(State):-State =  state(S1,S2,S3,S4,S5)),write('Telikh:'),
write(state(S1,S2,S3,S4,S5)),retractall(final(S1,S2,S3,S4,S5)),nl.

go(Move1,Move2,Move3):-cur_state(State),newstate(State,NextState),
    pour(State,move(Move1,Move2,Move3), NextState),
    retractall(cur_state(State):-State = state(_,_,_,_,_)),asserta(cur_state(NextState)),
    ((end_state(NextState),write('Bravo!!!!')) ;(write(' ---*Eiste sthn katastash --- :'),write(NextState))),nl.
4

2 に答える 2

1

あなたが書いたものを理解するのは難しいです。初期状態がini(10,0,0,0,r)、の場合、最後の2つの引数は何ですか?水差しは3つしかないんですよね?なぜ最終状態なのfin(0,3,3,3,r)か?最後3rはどういう意味ですか?

あなたは3つの水差しを持っているので、あなたの州には3つの値があります:s(A,B,C)。外出先で動的に再定義したいようです。罰金。述語go(...)が呼び出さretract/assertれ、ロジックを処理する必要があります。ユーザーが「右に注ぐ」と言うことができるようにしたい場合、なぜあなたは彼に水差しにどれだけの水が残っているかを書くように主張するのですか?それは間違っているようです。システムはその値を計算し、それを使用して現在の動的データベースを更新する必要があります。さらに、どこから「右に注ぐ」?? 私にgo(7,3,r)は、「「7」から注ぐ-3リットルの水をその右側の水差しに注ぐ」と言われているようですが、もしそうなら、なぜ量を指定する必要があるのですか?それはあなたがしない水差し問題の通常の仕様に反していませんか?測定する能力があり、代わりに水差しの能力が与えられていますか?代わりに、「「7」の水差しから「3」の水差しにできるすべての水を注ぐ」という意味ですか?もしそうなら、r機能はありません。

だからあなたの問題を明確にしてください。そして最後に、あなたの水差しの能力は何ですか?

編集:まあ、ルールについての以下のコメントで明確にした後、私はこれを次のようにコーディングします:

%% to be called: initial(10-10,7-0,3-0).
%% to be called: final(10-0,7-3,3-3).

initial(C1-W1,C2-W2,C3-W3):- % capacity-water_content
  retractall( jug(_,_) ), 
  asserta( jug(C1,W1) ),
  asserta( jug(C2,W2) ),
  asserta( jug(C3,W3) ).

final(C1-W1,C2-W2,C3-W3):- 
  retractall( end_jug(_,_) ), 
  asserta( end_jug(C1,W1) ),
  asserta( end_jug(C2,W2) ),
  asserta( end_jug(C3,W3) ).

jugsState(L) :- findall(X-W, jug(X,W), L). % see the state

go(Cfrom,0):-  !, % pour out the water
  retract( jug(Cfrom,_) ), 
  asserta( jug(Cfrom,0) ),
  is_final_state.

go(Cfrom,Cto):-
  retract( jug(Cfrom,Wfrom) ),
  retract( jug(Cto,Wto) ),
  Space is Cto-Wto,
  (  Wfrom >= Space
  -> Wleft is Wfrom - Space,
     asserta( jug(Cfrom,Wleft) ),
     asserta( jug(Cto,Cto) )
  ;  Wnew is Wto+Wfrom,
     asserta( jug(Cfrom,0) ),
     asserta( jug(Cto,Wnew) ) ),
  is_final_state.

is_final_state :- true.

残っているのはis_final_state、ファクトをチェックしjug、終了状態に到達したかどうかを確認し、到達した場合はお祝いメッセージを出力して、true常に戻るものを定義することです。またはそのようなもの。サンプルの実行は、例えば

?- initial(10-10,7-0,3-0).
?- final(10-0,7-3,3-3).
?- go(10,7).
?- go(7,3).
?- go(7,0).
?- jugsState(X).
X = [7-0, 3-3, 10-3]
?- ....
于 2012-01-30T19:24:15.430 に答える
1

私はあなたのコードをコピーしてSWI-Prologでコンパイルしました、そして私はこれらのメッセージを受け取りました:

?- Warning: /home/carlo/prolog/jug1.pl:20:
    Singleton variables: [D3]
Warning: /home/carlo/prolog/jug1.pl:57:
    Singleton variables: [N1]
Warning: /home/carlo/prolog/jug1.pl:66:
    Singleton variables: [N1]
Warning: /home/carlo/prolog/jug1.pl:75:
    Singleton variables: [N1]
Warning: /home/carlo/prolog/jug1.pl:84:
    Singleton variables: [N1]
Warning: /home/carlo/prolog/jug1.pl:93:
    Singleton variables: [N1]
ERROR: /home/carlo/prolog/jug1.pl:102:
    evaluable `n' does not exist
ERROR: /home/carlo/prolog/jug1.pl:111:
    evaluable `n' does not exist
ERROR: /home/carlo/prolog/jug1.pl:120:
    evaluable `n' does not exist
% /home/carlo/prolog/jug1.pl compiled 0,01 sec, 32 clauses

表面的なコード検査により、23行目の小文字の「c」などの他の欠陥が明らかになります。前の質問で得たすべてのヒントを適用する必要があります。

コードを因数分解すると、何が起こっているのかを理解するのに役立ちます。newstate/ 2には9つのルールがあり、ほぼ同じです。唯一の変更点は、エラーは別として(ここでも、スペルが間違っている変数である小文字の識別子)、定数が異なります。state/5は実際には「moves」に関連する値を保持しているようです。これら(つまり、最後の2つの引数)を分離して、newstate(newstate(OldState、NumLitres、Direction、NewState)のようになる必要があります)に渡す必要があります。

于 2012-01-27T08:44:16.633 に答える