3

Prolog を使用して Ship Puzzle の問題を解決する必要があります。ここに事実があります。

船は5隻。

  1. ギリシャの船は 6 時に出発し、コーヒーを運びます。
  2. 真ん中の船には黒い煙突があります。
  3. イギリスの船は9時に出発します。
  4. 青い煙突のフランス船は、コーヒーを運ぶ船の左側にあります。
  5. ココアを運ぶ船の右側にはマルセイユ行きの船があります。
  6. ブラジル船はマニラに向かっています。
  7. お米を運ぶ船の隣には、緑の煙突の船が。
  8. ジェノバ行きの船は5時に出発します。
  9. スペイン船は 7 時に出発し、マルセイユ行きの船の右側にあります。
  10. 赤い煙突のある船はハンブルグに行きます。
  11. 7時に出発する船の隣には、白い煙突のある船があります。
  12. 国境の船はとうもろこしを運んでいます。
  13. 黒い煙突のある船は8時に出発します。
  14. とうもろこしを運ぶ船は、米を運ぶ船の隣に停泊しています。
  15. ハンブルグ行きの船は 6 時に出発します。

ポートサイドに行く船は?お茶を運ぶ船は?

答えをインターネットで検索しましたが、何も見つかりませんでした。そこで、「The Zebra Puzzle」を参考にして、この問題のコードを整理しました。これが私のPrologコードの問題です。

exists(A,(A,_,_,_,_)).
exists(A,(_,A,_,_,_)).
exists(A,(_,_,A,_,_)).
exists(A,(_,_,_,A,_)).
exists(A,(_,_,_,_,A)).

rightOf(A,B,(B,A,_,_,_)).
rightOf(A,B,(_,B,A,_,_)).
rightOf(A,B,(_,_,B,A,_)).
rightOf(A,B,(_,_,_,B,A)).

middleShip(A,(_,_,A,_,_)).

lastShip(A,(_,_,_,_,A)).

nextTo(A,B,(B,A,_,_,_)).
nextTo(A,B,(_,B,A,_,_)).
nextTo(A,B,(_,_,B,A,_)).
nextTo(A,B,(_,_,_,B,A)).
nextTo(A,B,(A,B,_,_,_)).
nextTo(A,B,(_,A,B,_,_)).
nextTo(A,B,(_,_,A,B,_)).
nextTo(A,B,(_,_,_,A,B)).

solution(PortSaidShip, TeaCarrier) :-
   Shipes = (ship(_,_,_,_,_),ship(_,_,_,_,_),ship(_,_,_,_,_),ship(_,_,_,_,_),ship(_,_,_,_,_)),
   exists(ship('Greek',6,'Coffee',_,_),Shipes),
   middleShip(ship(_,_,_,_,'Black',_),Shipes),
   exists(ship('English',9,_,_,_),Shipes),
   rightOf(ship(_,_,'Coffee',_,_),ship('French',_,_,'Blue',_),Shipes),
   rightOf(ship(_,_,_,_,'Marseille'),ship(_,_,'Cocoa',_,_),Shipes),
   exists(ship('Brazilian',_,_,_,'Manila'),Shipes),
   nextTo(ship(_,_,_,'Green',_),ship(_,_,'Rice',_,_),Shipes),
   exists(ship(_,5,_,_,'Genoa'),Shipes),
   rightOf(ship('Spanish',7,_,_,_),ship(_,_,_,_,'Marseille'),Shipes),
   exists(ship(_,_,_,'Red','Hamburg'),Shipes),
   nextTo(ship(_,_,_,'White',_),ship(_,7,_,_,_),Shipes),
   lastShip(ship(_,_,'Corn',_,_),Shipes),
   exists(ship(_,8,_,'Black',_),Shipes),
   nextTo(ship(_,_,'Corn',_,_),ship(_,_,'Rice',_,_),Shipes),
   exists(ship(_,6,_,_,'Hamburg'),Shipes),
   exists(ship(PortSaidShip,_,_,_,'Port Said'),Shipes),
   exists(ship(TeaCarrier,_,'Tea',_,_),Shipes).

しかし、プログラムを実行すると、「false」と表示されます。
では、どうすればこれを解決できますか?
ありがとうございました

4

2 に答える 2

6

あなたは尋ねました:

では、どうすればこれを解決できますか?

以下は、あなたのような純粋で単調な Prolog プログラムで常に機能する一般的な方法論です。あなたの実際の問題は、特定の目標が成功するはずなのに失敗することです。予期しない失敗が発生しました。プログラムの責任部分をローカライズするために、プログラムを体系的に一般化します。一歩一歩。小さな小さなプログラムの断片ができるまで。この手法は、プログラムのスライシングプログラムの修正と呼ばれることもあります。

まず、コードに次を追加します。

:- op(950, fy, *).
*_.

:- initialization(solution(_Port, _Carrier)).

次に、ゴールの前にa を追加してゴールを次々と削除し*、プログラムを再実行します。そのため、プログラムを数回再実行する準備をしてください。プログラムをロードするには、トップレベルで次のように入力します。

?- [shipes].

これは、SICStus、GNU、SWI、YAP など、事実上どこでも機能します。「失敗したディレクティブ」などに関する警告が表示されるようになりました。だから - 幸せに - 問題を簡単に再現できるようになりました!

*最後のゴールでa を追加し始めます。一度にいくつか試すこともできます。変更後にリロードするには、その目標を再入力するか、

  • SICStus では、より良い状態ensure_loaded(shipes).これにより、ファイルが変更されているかどうかがチェックされ、再ロードされた場合にのみ再実行されます

  • SWI で、次のように入力します。make.

最後に、次のプログラムフラグメントを取得しました。

middleShip(A,(_,_,A,_,_))。

ソリューション(PortSaidShip、TeaCarrier): -
   Shipes = (船(_,_,_,_,_),船(_,_,_,_,_),船(_,_,_,_,_),船(_,_,_, _、_)、輸送する(_、_、_、_、_))、
   *  exists(ship('Greek',6,'Coffee',_,_),Shipes) ,
   middleShip(ship(_,_,_,_,'ブラック',_),Shipes),
   *  exists(ship('English',9,_,_,_),Shipes) ,
    *  rightOf(ship(_,_,'Coffee',_,_),ship('French',_,_,' Blue',_),Shipes) ,
    *  rightOf(ship(_,_,_,_,'マルセイユ'),ship(_,_,'ココア',_,_),Shipes) ,
    *  exists(ship( 'ブラジル',_,_,_,'マニラ'),船) ,
    *  nextTo(船(_,_,_,'緑',_),船(_,_,'米',_,_) ,Shipes) ,
    *  exists(ship(_,5,_,_,'ジェノバ'),Shipes) ,
    *  rightOf(ship('Spanish',7,_,_,_),ship(_,_,_ ,_,'マルセイユ'),Shipes) ,
    *  exists(ship(_,_,_,'Red','Hamburg'),Shipes) ,
   *  nextTo(ship(_,_,_,'ホワイト',_),ship(_,7,_,_,_),Shipes),
    *  lastShip(ship(_,_,'Corn',_,_),Shipes) ,
    *  exists(ship(_,8,_,'Black',_),Shipes) ,
    *  nextTo(ship(_, _,'とうもろこし',_,_),ship(_,_,'米',_,_),Shipes) ,
    *  exists(ship(_,6,_,_,'ハンブルグ'),Shipes) ,
    *  exists(ship(PortSaidShip,_,_,_,'Port Said'),Shipes) ,
    *  exists(ship(TeaCarrier,_,'Tea',_,_),Shipes) .

したがって、問題を理解するには 4 行のコードを理解する必要があります。

他の人がすでに示しているように、問題は、一度使用するship/6と、他の状況でship/5.

別の注意:(_,_,_,A,B)より良い書き込みの代わりに[_,_,_,A,B]、一般的なリスト表記法です。

于 2015-06-10T11:19:56.540 に答える