【问题标题】:Solving Einstein Riddle in Prolog在 Prolog 中解决爱因斯坦之谜
【发布时间】:2018-01-31 01:54:16
【问题描述】:

我正在尝试在 Prolog 中解决 Einstein Riddle

我编写的程序有问题,基本方法是添加所有约束并让 Prolog 找出唯一可能的解决方案。

问题是 Prolog 找到 0 个解决方案。我已经隔离了使程序从给定解决方案变为无解决方案的约束,但我不明白为什么。

/*There are five houses*/
exists(A, list(A,_,_,_,_)).
exists(A, list(_,A,_,_,_)).
exists(A, list(_,_,A,_,_)).
exists(A, list(_,_,_,A,_)).
exists(A, list(_,_,_,_,A)).

middle_house(A, list(_,_,A,_,_)).

first_house(A, list(A,_,_,_,_)).

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

/* each statement will be described using the clues 
house conatins: Color,Owner, Drinks, Smokes, Pet*/
riddle(Houses):-
    /*exists(house(red, englishman, _,_,_),Houses),*/
    nextTo(house(_,norwegian,_,_,_), house(blue,_,_,_,_), Houses),
    exists(house(_,spanish,_,_, dog), Houses),
    exists(house(green, _, coffee, _,_), Houses),
    exists(house(_, ukrain, tea,_,_), Houses),
    nextTo(house(white,_,_,_,_), house(green,_,_,_,_), Houses),
    exists(house(_,_,_,marlbero, cat),Houses),
    exists(house(yellow,_,_,time,_), Houses),
    middle_house(house(_,_,milk,_,_), Houses),
    first_house(house(_,norwegian,_,_,_), Houses),
    nextTo(house(_,_,_,_,fox), house(_,_,_,montena,_), Houses),
    nextTo(house(_,_,_,time,_), house(_,_,_,_,horse), Houses),
        exists(house(_,_,orange,lucky,_), Houses),
    exists(house(_,japanese,parlament,_), Houses).

目前的解决方案是这样的:

?- riddle(Houses).
Houses = list( house(green, norwegian, coffee, marlbero, cat),
               house(white, spanish, orange, lucky, dog),
               house(yellow, norwegian, milk, time, fox),
               house(blue, ukrain, tea, montena, horse),
               house(_G7257, japanese, parlament, _G7260)).

如果我取消注释第一行,那么相同的语句将返回 false。

我想帮助理解为什么会这样。 我注意到在部分解决方案中,挪威语出现了两次,这可能表明存在问题。

【问题讨论】:

  • 另外,nextTo(house(white,_,_,_,_), house(green,_,_,_,_), Houses) 的限制还不够。根据最初的谜题,绿色房子是右侧白宫,而不仅仅是旁边
  • 这一行(riddle/1 谓词的最后一行)缺少一个 house 参数:exists(house(_,japanese,parlament,_), Houses)。应该是exists(house(_,japanese,_,parlament,_), Houses)

标签: prolog zebra-puzzle


【解决方案1】:

这是您自己解决此问题的一般方法。实际上,您确实从一个非常有希望的方向开始:您试图删除目标。但是,在你的案子中,谁有过错?您注释掉的行还是其他行?你不能肯定地说,因为生成的程序已经工作了。但是有一个非常相似且更有希望的方法:尝试尽可能泛化您的程序,使其仍然失败。通过这种方式,您将获得一个负责失败的较小程序。也就是说,在剩余的可见部分内一定是错误

这是我通过删除目标(在前面添加 *)并将某些术语替换为 _ 得到的结果。

:- 初始化(谜语(_Sol))。 :- op(950, fy, *)。 *_。 谜语(房屋):- 存在(房子(红色,_/* englishman */, _,_,_),房子), nextTo(房子(_,_/* 挪威 */,_,_,_), 房子(蓝色,_,_,_,_), 房子), * exists(house(_,spanish,_,_, dog), Houses), * 存在(房子(绿色,_,咖啡,_,_),房子)* exists(house(_, ukrain, tea,_,_), Houses), nextTo(房子(白色,_,_,_,_), 房子(绿色,_,_,_,_), 房子), * 存在(房子(_,_,_,marlbero, cat),Houses), 存在(房子(黄色,_,_,_/* 时间 */,_), 房子), * middle_house(house(_,_,milk,_,_), Houses), * first_house(house(_,norwegian,_,_,_), Houses), * nextTo(房子(_,_,_,_,fox), 房子(_,_,_,montena,_), 房子), * nextTo(house(_,_,_,time,_), house(_,_,_,_,horse), Houses), * 存在(房子(_,_,orange,lucky,_), Houses), 存在(房子(_,_/* 日语 */,_/* 议会 */,_), 房子)。

这个片段仍然失败,因此错误必须在程序的可见部分。

所有的房子颜色都存在似乎是必不可少的。只有一个目标根本不包含任何房屋颜色……看到了吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 2011-05-24
    • 2016-08-17
    • 2015-09-15
    • 2012-06-22
    • 1970-01-01
    相关资源
    最近更新 更多