为什么我无法通过Prolog获得有关“拼图游戏"的答案? [英] Why I can't get an answer for the Ship Puzzle with Prolog?

查看:81
本文介绍了为什么我无法通过Prolog获得有关“拼图游戏"的答案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Prolog解决Ship Puzzle难题. 这是事实.

I need to solve the Ship Puzzle problem with using Prolog. Here are the facts.

有5艘船.

There are 5 ships.

  1. 这艘希腊船六点钟离开,载着咖啡.
  2. 中间的船上有一个黑色的烟囱.
  3. 英国船在九点离开.
  4. 带有蓝色烟囱的法国船在载有咖啡的船的左侧.
  5. 载有可可的船只右侧是前往马赛的船只.
  6. 这艘巴西船正驶向马尼拉.
  7. 运送大米的船旁边是一艘带绿色烟囱的船.
  8. 去热那亚的船五点钟离开.
  9. 西班牙船从七点出发,在去马赛的船的右侧.
  10. 带红色烟囱的船去了汉堡.
  11. 在七点离开的船旁边是一艘带有白色烟囱的船.
  12. 边境上的船上载着玉米.
  13. 带有黑色烟囱的船八点离开.
  14. 运送玉米的船锚定在运送水稻的船旁边.
  15. 去汉堡的船六点出发.
  1. The Greek ship leaves at six and carries coffee.
  2. The Ship in the middle has a black chimney.
  3. The English ship leaves at nine.
  4. The French ship with blue chimney is to the left of a ship that carries coffee.
  5. To the right of the ship carrying cocoa is a ship going to Marseille.
  6. The Brazilian ship is heading for Manila.
  7. Next to the ship carrying rice is a ship with a green chimney.
  8. A ship going to Genoa leaves at five.
  9. The Spanish ship leaves at seven and is to the right of the ship going to Marseille.
  10. The ship with a red chimney goes to Hamburg.
  11. Next to the ship leaving at seven is a ship with a white chimney.
  12. The ship on the border carries corn.
  13. The ship with a black chimney leaves at eight.
  14. The ship carrying corn is anchored next to the ship carrying rice.
  15. The ship to Hamburg leaves at six.

哪个船去塞得港?哪艘船上载茶?

Which ship goes to Port Said? Which ship carries tea?

我在互联网上搜索答案,但找不到任何答案.因此,我将其称为斑马之谜",因此我为该问题安排了代码.所以这是我的Prolog代码的问题.

I search internet for answers, but I could not find any. So I refer 'The Zebra Puzzle' and accordingly I arranged the code for this problem. So this is my Prolog code the problem.

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'.
那我该如何解决呢?
谢谢

But when I run the program it will say 'false'.
So how can I solve this?
thank you

推荐答案

您问过:

那我该如何解决呢?

So how can I solve this?

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

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

这几乎可以在任何地方使用,例如在SICStus,GNU,SWI和YAP中.您现在将收到有关指令失败"或类似内容的警告.所以-开心-因为您现在可以轻松重现问题了!

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

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

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

在SWI中,输入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!

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

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

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

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

这篇关于为什么我无法通过Prolog获得有关“拼图游戏"的答案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆