为什么我无法通过Prolog获得船舶难题的答案?



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

有5艘船。

  1. 希腊船6点出发,载着咖啡。
  2. 中间的船有一个黑色的烟囱。
  3. 英国船九点钟启航。
  4. 有蓝色烟囱的法国船在一艘运送咖啡的船的左边。
  5. 可可船的右边是一艘开往马赛的船。
  6. 巴西船驶往马尼拉。
  7. 运输大米的船旁边是一艘有绿色烟囱的船。
  8. 一艘开往热那亚的船5点出发。
  9. 西班牙船7点出发,在开往马赛的船的右侧。
  10. 有红色烟囱的船驶往汉堡。
  11. 7点出发的船旁边是一艘有白色烟囱的船。
  12. 边境上的船运载玉米。
  13. 有黑色烟囱的船在八点离开。
  14. 运载玉米的船停靠在运载大米的船旁边。
  15. 开往汉堡的船6点启航。

哪条船去塞得港?哪条船运茶?

我在网上搜索答案,但我找不到任何。所以我参考了"斑马拼图",并据此安排了这个问题的代码。所以这就是我的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'。
我该如何解决这个问题呢?
谢谢

你问:

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

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

首先,在你的代码中添加以下代码:
:- op(950, fy, *).
*_.
:- initialization(solution(_Port, _Carrier)).

现在我们将通过在其前面添加 * 来删除一个又一个目标,然后重新运行您的程序。因此,要准备好您将多次重新运行您的程序。要加载程序,请在顶层输入:

?- [shipes].

这几乎在任何地方都有效,比如在SICStus、GNU、SWI、YAP中。您现在将得到一个关于"失败的指令"或类似的警告。所以-高兴吧-你现在可以轻松地重现这个问题了!

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

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

  • 时才重新运行它
  • 在SWI中输入make.

最后,我得到了下面的程序片段: <>之前middleShip (A,(_, _, _, _))。解决方案(PortSaidShip, teaccarrier)船=(船 (_,_,_,_,_), 船 (_,_,_,_,_), 船 (_,_,_,_,_), 船 (_,_,_,_,_), 船 (_,_,_,_,_)), * <年代>存在(船("咖啡"希腊",6日,_,_),船),middleShip(船 (_,_,_,_,' 黑色的,_),船), * <年代>存在(船("英语",9日_、_、_),船), * <年代> rightOf(船(_、_"咖啡",_,_),船("法国",_,_,"蓝色",_),船), * <年代> rightOf(船 (_,_,_,_,' 马赛的)、船("可可"_,_,_,_),船), * <年代>存在(船(巴西,_,_,_,马尼拉),船), * <年代>旁边(船(_、_、_、"绿色"_),船(_、_"大米",_,_),船), * <年代>存在(船(5 _,_,_,热那亚),船), * <年代> rightOf(船("西班牙"7 _,_,_),船 (_,_,_,_,' 马赛的)、船), * <年代>存在(船(_,_,_,"红色","汉堡"),船), * <年代>旁边(船(_,_,_,"白色",_),船(7 _,_,_,_),船), * <年代> lastShip(船(_,_,"玉米",_,_),船), * <年代>存在(船(_ _,8日,‘黑’,_),船), * <年代>旁边(船(_,_,"玉米",_,_),船(_、_"大米",_,_),船), * <年代>存在(船(6 _,_,_,"汉堡"),船), * <年代>存在(船(PortSaidShip、_、_、_塞得港),船), * <年代>存在(船(TeaCarrier _,"茶",_,_),船)。之前

所以你需要理解四行代码来理解你的问题!

正如其他人已经指出的那样,问题是一旦您使用ship/6而在其他情况下使用ship/5

另一个注意事项:(_,_,_,A,B)最好写成[_,_,_,A,B],这是常用的列表表示法。

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

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

而它应该是:

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

我还没有检查这是否有效,但这肯定会导致您的求解器失败

相关内容

  • 没有找到相关文章

最新更新