我正在尝试解决Prolog中的爱因斯坦之谜。
我对我编写的程序有困难,基本方法是添加所有约束并让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。
我想帮助理解为什么会这样。 我注意到,在部分解决方案中,挪威语出现了两次,这可能表明问题所在。
这是您自己解决此问题的一般方法。 实际上,你真的开始了一个非常有前途的方向:你试图删除目标。但是,在你的案子里,谁有错呢?您注释掉的行还是其余的?您不能肯定地说,因为生成的程序已经运行。但是有一种非常相似且更有前途的方法:尝试尽可能多地概括您的程序,使其仍然失败。通过这种方式,您将获得一个较小的程序,该程序负责失败。也就是说,在剩余的可见部分必须是一个错误!
这是我通过删除目标(在前面添加 *(和用 _ 替换一些术语得到的。
:- 初始化(谜语(_Sol((. :- op(950, fy, *(. *_. 谜语(房屋(:- 存在(房子(红色,_/*英国人*/,_,_(,房子(, 下一页到(房子(_,_/*挪威语*/,_,_,_(, 房子(蓝色,_,_,_,_(, 房子(,*存在(房子(_,西班牙语,_,_,狗(,房子(,*存在(房子(绿色, _, 咖啡, _,_(, 房子(,*存在(房子(_, 乌克兰, 茶,_,_(, 房子(,下一页到(房子(白色,_,_,_,_(,房子(绿色,_,_,_,_(,房子(,*存在(房子(_,_,_,马尔贝罗,猫(,房子(,存在(房子(黄色,_,_,_/*时间*/,_(,房子(,*middle_house(房子(_,_,牛奶,_,_(, 房子(,*first_house(房子(_,挪威语,_,_,_(,房子(,*下一页到(房子(_,_,_,狐狸(, 房子(_,_,_,蒙特纳,_(, 房子(,*下一页(房子(_,_,_,时间,_(, 房子(_,_,_,马(, 房子(,*存在(房子(_,_,橙色,幸运,_(, 房子(,存在(房子(_,_/*日语*/,_/*parlament*/,_(, 房子(。
此片段仍然失败,因此错误必须在程序的可见部分。
似乎必须存在所有房屋颜色。只有一个目标完全不包含任何房屋颜色......看到了吗?