Why I can't get an answer for the Ship Puzzle with Prolog?

為{幸葍}努か 提交于 2019-12-01 22:19:59

You asked:

So how can I solve this?

The following is a general methodology, that always works for pure, monotonic Prolog programs like yours. Your actual problem is that a specific goal should succeed, but it fails. So you got an unexpected failure. To localize the responsible part of your program, we will now systematically generalize your program. Step by step. Until we have a tiny little program fragment. This technique is called sometimes program slicing and sometimes program modification.

First of all, add the following to your code:

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

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

Now we will remove one goal after the other by adding a * in front of it and then rerun your program. So be prepared that you will rerun your program for a couple of times. To load the program enter at the toplevel:

?- [shipes].

This works virtually everywhere, like in SICStus, GNU, SWI, YAP. You will get now a warning about a "failed directive" or similar. So - be happy - for you can now reproduce the problem with ease!

Start adding a * at the last goal. You might try several at once. To reload after modification you might reenter that goal, or

  • in SICStus, better state ensure_loaded(shipes). This checks if the file has been modified and only reruns it if it has been reloaded

  • in SWI, enter make.

Finally, I got the following program fragment:

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

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).

So you need to understand four lines of code to understand your problem!

As others have already indicated, the problem is that once you use ship/6 and in other situations ship/5.

Another remark: In stead of (_,_,_,A,B) better write [_,_,_,A,B] which is the common list notation.

The number of arguments to the term ship(...) in the second line (after solution predicate) is wrong. It is:

middleShip(ship(_,_,_,_,'Black',_),Shipes),

while it should be:

middleShip(ship(_,_,_,'Black',_),Shipes),

I haven't checked if this works, but this is causing your solver to fail for sure.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!