爱因斯坦谜语与术语列表
Posted
技术标签:
【中文标题】爱因斯坦谜语与术语列表【英文标题】:Einstein Riddle with List of terms 【发布时间】:2016-08-13 02:44:08 【问题描述】:我在 Prolog 中实现了 Einstein Riddle,我正试图找出谁在家里养了一条鱼。 我在此代码中找不到错误,并且跟踪选项对解决此问题没有帮助;)
规则:
-
挪威人住在第一宫
英国人住在红房子里。
温室就位于白宫的左侧。
丹麦人喝茶。
轻度吸烟者生活在猫饲养者旁边。
黄房子的居民抽着雪茄。
德国人抽水烟。
中心住宅的一位居民喝牛奶。
轻度吸烟者有一个喝水的邻居。
不带过滤嘴的香烟会繁殖鸟类。
瑞典犬。
挪威人住在蓝房子旁边。
饲养马的人住在黄房子旁边。
抽薄荷醇喝啤酒。
他们在温室里喝咖啡。
这是我的代码:
on_the_left(X, Y, N) :-
Y is X - 1,
\+ Y < 1,
\+ X > N.
next_to(X, Y, N) :-
( Y is X + 1;
Y is X - 1),
\+ X > N,
\+ Y > N,
\+ X < 1,
\+ Y < 1.
fish(Who) :-
Houses = [
house(1, _Color1, _From1, _Animal1, _Drink1, _Smoke1),
house(2, _Color2, _From2, _Animal2, _Drink2, _Smoke2),
house(3, _Color3, _From3, _Animal3, _Drink3, _Smoke3),
house(4, _Color4, _From4, _Animal4, _Drink4, _Smoke4),
house(5, _Color5, _From5, _Animal5, _Drink5, _Smoke5) ],
N is 5,
%-- hint 1
member(house(1, _, norway, _, _, _), Houses),
%-- hint 2
member(house(_, red, england, _, _, _), Houses),
%-- hint 3 - on_the_left
member(house(GREEN, green, _, _, _, _), Houses),
member(house(WHITE, white, _, _, _, _), Houses),
on_the_left(GREEN, WHITE, N),
%-- hint 4
member(house(_, _, denmark, _, tea, _), Houses),
%-- hint 5 - next_to
member(house(LIGHT, _, _, _, _, light), Houses),
member(house(CAT, _, _, cat, _, light), Houses),
next_to(LIGHT, CAT, N),
%-- hint 6
member(house(_, yellow, _, _, _, cigar), Houses),
%-- hint 7
member(house(_, _, germany, _, _, waterpipe), Houses),
%-- hint 8
member(house(3, _, _, _, milk, _), Houses),
%-- hint 9 - next_to
member(house(WATER, _, _, _, water, _), Houses),
next_to(LIGHT, WATER, N),
%-- hint 10
member(house(_, _, _, bird, _, nofilter), Houses),
%-- hint 11
member(house(_, _, sweden, dog, _, _), Houses),
%-- hint 12 - next_to
member(house(NORWAY, _, norway, _, _, _), Houses),
member(house(BLUE, blue, _, _, _, _), Houses),
next_to(NORWAY, BLUE, N),
%-- hint 13 - next_to
member(house(HORSE, _, _, horse, _, _), Houses),
next_to(HORSE, GREEN, N),
%-- hint 14
member(house(_, _, _, _, beer, menthol), Houses),
%-- hint 15
member(house(_, green, _, _, coffee, _), Houses),
%-- FINAL QUESTION - WHO LET THE FISH OUT?
member(house(_, _, _, fish, _, _), Houses),
member(house(_, _, Who, fish, _, _), Houses).
我尝试了很多组合但是:
?- 鱼(谁)。 假的。
编辑: 代码现在可以工作了,我改变了什么:
1* 来自:
%-- hint 5 - next_to
member(house(LIGHT, _, _, _, _, light), Houses),
member(house(CAT, _, _, cat, _, light), Houses),
收件人:
%-- hint 5 - next_to
member(house(LIGHT, _, _, _, _, light), Houses),
member(house(CAT, _, _, cat, _, _), Houses),
2* 来自:
%-- hint 13 - next_to
member(house(HORSE, _, _, horse, _, _), Houses),
next_to(HORSE, GREEN, N),
收件人:
%-- hint 13 - next_to
member(house(YELLOW, yellow, _, _, _, _), Houses),
member(house(HORSE, _, _, horse, _, _), Houses),
next_to(HORSE, YELLOW, N),
如果您正在阅读这篇文章,请查看关于辅助谓词中结构的 @Enigmativity 评论。
【问题讨论】:
真的,谢谢。我添加了一条规则。 5提示中的错误已修复,但程序仍然无法运行。 【参考方案1】:你的线索中有两个错误 - 第一个你已经用 light
吸烟者修复了。第二个是horse
的主人住在yellow
房子旁边,而不是green
。
现在,我的序言被 \+
运算符卡住了,所以我重新编写了您的辅助谓词。这就是我所做的:
现在这个谜题很好地利用了这些线索:
鱼(谁):- 房子= [ 房子(_Color1,_From1,_Animal1,_Drink1,_Smoke1), 房子(_Color2,_From2,_Animal2,_Drink2,_Smoke2), 房子(_Color3,_From3,_Animal3,_Drink3,_Smoke3), 房子(_Color4,_From4,_Animal4,_Drink4,_Smoke4), 房子(_Color5,_From5,_Animal5,_Drink5,_Smoke5)], first(house(_, norway, _, _, _), Houses), %-- 提示 1 member(house(red, england, _, _, _), Houses), %-- 提示 2 on_the_left(房子(绿色,_,_,_,_),房子(白色,_,_,_,_),房子),%--提示 3 - on_the_left member(house(_, denmark, _, tea, _), Houses), %-- 提示 4 next_to(house(_, _, _, _, light), house(_, _, cat, _, _), Houses), %-- 提示 5 - next_to member(house(yellow, _, _, _, cigar), Houses), %-- 提示 6 成员(房屋(_,德国,_,_,水管),房屋),%--提示 7 中间(房子(_,_,_,牛奶,_),房子),%--提示8 next_to(house(_, _, _, _, light), house(_, _, _, water, _), Houses), %-- 提示 9 - next_to member(house(_, _, bird, _, nofilter), Houses), %-- 提示 10 member(house(_, sweden, dog, _, _), Houses), %-- 提示 11 next_to(house(_, norway, _, _, _), house(blue, _, _, _, _), Houses), %-- 提示 12 - next_to next_to(house(_, _, horse, _, _), house(yellow, _, _, _, _), Houses), %-- 提示 13 - next_to member(house(_, _, _, beer, menthol), Houses), %-- 提示 14 member(house(green, _, _, coffee, _), Houses), %-- 提示 15 成员(房子(_,谁,鱼,_,_),房子), 写(房屋),NL。我明白了:
[房子(黄色,挪威,猫,水,雪茄),房子(蓝色,丹麦,马,茶,灯),房子(红色,英国,鸟,牛奶,无过滤器),房子(绿色,德国,鱼,咖啡,水烟), 房子(白, 瑞典, 狗, 啤酒, 薄荷)] 德国【讨论】:
谢谢,我修复了第二个错误,现在运行良好。我需要适当的睡眠;)它与我的辅助谓词版本一起使用,但像你一样编写它是更好的做法,对吧? @CryptoNewbie - 我尽量避免数字操作。 Prolog 最擅长结构化解决方案 - 所以像middle(X,[_,_,X,_,_]).
这样的谓词既简单又结构化。我还尝试将每个线索作为fish/1
谓词中的一个术语来实现——这使得它更容易阅读,因此更容易调试和维护。这是我给你的两个建议。
哪个 Prolog 在 (\+)/1
上窒息??
@false 适用于 SWI-Prolog(多线程,64 位,版本 7.2.0)
@false - Strawberry Prolog 阻塞 - “警告 4:字符串 \+ 不是运算符。”【参考方案2】:
只是为了展示另一种编码方案:
solve :- solve(Sol, From), writeln(From), maplist(writeln, Sol).
solve(Sol, From) :-
phrase( (from(1, norway)
,color(red) = from(england)
,color(GREEN, green), color(WHITE, white), GREEN is WHITE-1
,from(denmark) = drink(tea)
,smoke(Light, light), animal(Cat, cat), next_to(Light, Cat)
,color(Yellow, yellow), smoke(Yellow, cigar)
,from(germany) = smoke(waterpipe)
,drink(3, milk)
,drink(Water, water), next_to(Light, Water)
,animal(bird) = smoke(nofilter)
,from(sweden) = animal(dog)
,from(NORWAY, norway), color(BLUE, blue), next_to(NORWAY, BLUE)
,animal(HORSE, horse), next_to(HORSE, GREEN) % next_to(HORSE, Yellow)
,drink(beer) = smoke(menthol)
,color(green) = drink(coffee)
,animal(Fish, fish), from(Fish, From)
), [[1,_,_,_,_,_],
[2,_,_,_,_,_],
[3,_,_,_,_,_],
[4,_,_,_,_,_],
[5,_,_,_,_,_]
], Sol).
state(S), [A,B,C,D,E] --> [A,B,C,D,E], member(S, [A,B,C,D,E]).
color(A, B) --> state([A,B,_,_,_,_]).
from(A, B) --> state([A,_,B,_,_,_]).
animal(A, B) --> state([A,_,_,B,_,_]).
drink(A, B) --> state([A,_,_,_,B,_]).
smoke(A, B) --> state([A,_,_,_,_,B]).
X = Y -->
X=..[Fx|Ax], Y=..[Fy|Ay],
Xs=..[Fx,S|Ax], Ys=..[Fy,S|Ay]
, call(Xs), call(Ys).
next_to(X, Y) --> 1 is abs(X-Y).
【讨论】:
太棒了!目前,这也只产生false
。
@mat:我留下评论了更正% next_to(HORSE, Yellow)
。寻找错误的功劳确实归功于 Enigmativity以上是关于爱因斯坦谜语与术语列表的主要内容,如果未能解决你的问题,请参考以下文章