为什么我无法通过Prolog获得Ship Puzzle的答案?

时间:2015-06-09 18:21:31

标签: prolog zebra-puzzle

我需要使用Prolog来解决Ship Puzzle问题。 以下是事实。

  

共有5艘船。

     
      
  1. 希腊船只在六点起飞,带着咖啡。
  2.   
  3. 中间的船有一个黑色的烟囱。
  4.   
  5. 英国船只在9点离开。
  6.   
  7. 带有蓝色烟囱的法国船只位于运载咖啡的船的左侧。
  8.   
  9. 载着可可的船的右边是一艘前往马赛的船。
  10.   
  11. 这艘巴西船正前往马尼拉。
  12.   
  13. 在运载大米的船旁边是一艘带有绿色烟囱的船。
  14.   
  15. 一艘前往热那亚的船只在五点离开。
  16.   
  17. 西班牙船在七点离开,在船的右边,前往马赛。
  18.   
  19. 带红色烟囱的船前往汉堡。
  20.   
  21. 在七号船离开的旁边是一艘带有白色烟囱的船。
  22.   
  23. 边境的船上有玉米。
  24.   
  25. 带有黑色烟囱的船只在八点落下。
  26.   
  27. 运载玉米的船停泊在运载大米的船旁。
  28.   
  29. 前往汉堡的船只在六点离开。
  30.         

    哪艘船去了赛义德港?哪艘船载茶?

我在网上搜索答案,但我找不到任何答案。所以我引用了“斑马拼图”#39;因此我安排了这个问题的代码。所以这是我的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).

但是当我运行该程序时,它会说“假”'。那么我该如何解决这个问题?
谢谢

2 个答案:

答案 0 :(得分:6)

你问:

  

那我怎么解决这个问题呢?

以下是一般方法,总是适用于像您这样的纯粹,单调的Prolog程序。您的实际问题是特定目标应该成功,但它失败了。所以你遇到了意外失败。为了本地化您的程序的负责部分,我们现在将系统地推广您的程序。一步步。直到我们有一个小小的程序片段。此技术有时称为程序切片,有时称为程序修改

首先,在代码中添加以下内容:

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

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

现在,我们将在其中删除一个目标,在其前面添加 * ,然后重新运行您的程序。所以要做好准备,重新运行你的程序几次。要加载程序,请输入toplevel:

?- [shipes].

这几乎适用于所有地方,例如SICStus,GNU,SWI,YAP。您现在将收到关于"失败指令的警告"或类似的。所以 - 快乐 - 因为你现在可以轻松地重现问题!

开始在最后一个目标添加 * 。你可以一次尝试几个。 要在修改后重新加载,您可以重新进入该目标,或

  • 在SICStus中,更好的状态ensure_loaded(shipes).这将检查文件是否已被修改,只有在重新加载后才重新运行

  • 在SWI中
  • ,输入make.

最后,我得到了以下程序片段:

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

因此,您需要了解四行代码才能理解您的问题!

正如其他人已经指出的那样,问题在于您使用ship/6和其他情况ship/5

另一句话:代替(_,_,_,A,B)更好地写[_,_,_,A,B]这是常见的列表符号。

答案 1 :(得分:1)

第二行中的术语ship(...)的参数数量(在解决方案谓词之后)是错误的。它是:

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

虽然它应该是:

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

我还没有检查过这是否有效,但这会导致你的求解器失败。