prolog - 爱因斯坦谜语序言

标签 prolog logic zebra-puzzle

我需要一些帮助来完成我的 AI 类(class)的序言作业。问题是为爱因斯坦的谜题编写序言代码。我知道如何自己写下来,但在家庭作业中有一些限制。

 there are 5 houses
 the Englishman lives in the red house
 the Spaniard owns the dog
 coffee is drunk in the green house
 the Ukrainian drinks tea
 the green house is immediately to the right of the ivory house
 the Old Gold smoker owns snails
 Kools are smoked in the yellow house
 milk is drunk in the middle house
 the Norwegian lives in the first house
 the man who smokes Chesterelds lives in the house next to the man with the fox
 3 Kools are smoked in the house next to the house where the horse is kept
 the Lucky Strike smoker drinks orange juice
 the Japanese smokes Parliaments
 the Norwegian lives next to the blue house

我知道我需要使用列表来显示房屋,因为它们是有序的。我也想将列表用于房屋特征,但我在这里遇到了问题。

我打算使用匿名变量 房子(英国人,红色,_,_,_) .但我不知道如何为作业解释它。

以下是约束:
您应该使用以下二进制谓词符号:
owns(N,Pet)
smokes(N, Cigarette).
drinks(N, Drink).

除此之外,您可以自由使用任意数量的谓词。

这是我初始化事实的方式,但在这种情况下我不知道如何制定规则
next_to(X,Y) :- right_of(X,Y); right_of(Y,X).

owns(spaniard, dog).
drinks(ukrainian, tea).
smokes(japanese, parliaments).
right_of(ivory, green).
lives(englishman, red).
owns(X, snail) :- smokes(X, old_gold).
smokes(X, kools) :- owns(X, yellow).
smokes(X, lucky_strike) :- drinks(X, orange_juice).
drinks(X, coffee) :- owns(X, green_house).

这有点道理,但同时看起来完全错误。我不认为我可以带着这个去任何地方。 :/

最佳答案

This site致力于用 CLP(FD) 解决这些难题。但是 CLP(FD) 的全部功能在这里是多余的:当您充分描述了约束时,您的分配可以有效地解决搜索整个解决方案空间。

解决方案将由 5 栋房屋组成,其中每个属性都满足描述所施加的所有约束。

请注意对每个属性使用相同的符号(即 green 和 green_house 是错误的,请选择其中一个)。

next_to 似乎也是错误的:如果您从 1 到 5 编号,则可以计算或枚举,但指的是直接邻居。

所以完成“解决方案搜索空间”数据表示,比如

Problem = [
 house(1, Nationality1, Color1, Pet1, Drinks1, Smokes1),
 house(2, Nationality2, Color2, Pet2, Drinks2, Smokes2),
 ...
],
% place constraints
member(house(_, englishman, red, _, _, _), Problem),
member(house(_, spaniard, _, dog, _, _), Problem),
...

member/2 它是更简单的 Prolog 内置函数,但在这种情况下足以解决问题:当所有约束都已发布时,变量将绑定(bind)到适当的值。关键是成员(member)的能力非确定性选择解决方案的成员(duh)。

因此,当您需要在 2 个不同元素之间表达约束时,调用 2 次成员,并将约束放在适当的变量之间:即

the man who smokes Chesterelds lives in the house next to the man with the fox



将被翻译成
....,
member(house(N, _, _, _, _, chesterelds), Problem),
member(house(M, _, _, fox, _, _), Problem),
next_to(N, M),
...

当以这种方式表达许多约束时,请注意符号标识:在单独的过程中对每个谓词进行编码可能很有用,以避免过度的别名。但是对方
也是如此:如果同一个符号涉及多个约束,则需要绕过符号,以缩小搜索范围。

我将让您考虑“几何”谓词的正确表示:next_to 和 right_of 可以枚举,也可以通过算术表示。

关于prolog - 爱因斯坦谜语序言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9252656/

相关文章:

c - C 中的逻辑表达式

java - 如何在 Java 中使用 math.random 从文本文件打印特定文本行?

prolog - 列表中的唯一元素(Prolog)

prolog - 在 Prolog 中解答爱因斯坦之谜

prolog - 使用序言中的剪切从数据库中选择事实

Prolog 'is/2' 谓词实现

list - 如何交换序言列表中的三乘三元素?

list - 点积 Prolog/3 需要 SUM 提示

用 Prolog 编写的 RegEx 解析器

prolog - 爱因斯坦谜语中的数值比较