Prolog中的逻辑难题——使用列表
我正试图用Prolog解决以下问题,我认为我的代码编写正确,但我的查询只返回false。有什么改变的建议吗?问题如下: “百吉饼巷,当地的百吉饼店,在节日期间一直是一个活动猖獗的地方 早上的通勤时间,人们停下来在路边买咖啡和百吉饼 工作方式。每天早上现场制作新鲜的百吉饼,非常受欢迎,也非常美味 事实上,这家商店也有很棒的咖啡,就像蛋糕上的糖霜一样 在百吉坊工作的人都很开朗、友好,而且能干,所以 尽管顾客很多,但等待的时间从来都不长也不令人不快 今天早上他的四个同事过来看看每个人都做了些什么 他们到处胡言乱语,惊喜地发现这家商店没有辜负他们的期望 声誉。确定每个同事的名字,用它的名字做什么样的百吉饼 浇头,以及每种咖啡的口味和大小(小、中、大)。”Prolog中的逻辑难题——使用列表,prolog,zebra-puzzle,program-slicing,Prolog,Zebra Puzzle,Program Slicing,我正试图用Prolog解决以下问题,我认为我的代码编写正确,但我的查询只返回false。有什么改变的建议吗?问题如下: “百吉饼巷,当地的百吉饼店,在节日期间一直是一个活动猖獗的地方 早上的通勤时间,人们停下来在路边买咖啡和百吉饼 工作方式。每天早上现场制作新鲜的百吉饼,非常受欢迎,也非常美味 事实上,这家商店也有很棒的咖啡,就像蛋糕上的糖霜一样 在百吉坊工作的人都很开朗、友好,而且能干,所以 尽管顾客很多,但等待的时间从来都不长也不令人不快 今天早上他的四个同事过来看看每个人都做了些什么 他们
bagels(Sol):-
Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
member([brad,X,plain,_,_], Sol), X \== wheat,
member([walt,_,_,small,_], Sol),
member([_,_,_,medium1,hazelnut], Sol),
member([_,_,peanut_butter,medium2,_], Sol),
member([_,onion,Y,Z,french_vanilla], Sol), Y \== butter, Z \== small,
member([joe,Ja,Jb,Jc,Jd], Sol),Ja\==wheat,Jb\==egg_bacon,Jc\==large,Jd==amaretto,
member([La,Lb,Lc,large,Ld], Sol), La\==joe,Lb\==wheat,Lc\==egg_bacon,Ld\==amaretto,
member([Aa,Ab,Ac,Ad,amaretto], Sol), Aa\==joe,Ab\==wheat,Ac\==egg_bacon,Ad\==large,
member([Wa,wheat,Wb,Wc,Wd], Sol), Wa\==joe,Wb\==egg_bacon,Wc\==large,Wd\==amaretto,
member([Ea,Eb,egg_bacon,Ec,Ed], Sol), Ea\==joe,Eb\==wheat,Ec\==large,Ed\==amaretto,
member([rick,R,_,_,columbian], Sol),R\==blueberry,
member([A,cheddar,_,_,amaretto], Sol), A\==walt,
member([_,B,cream_cheese,large,_], Sol), B\==blueberry,
member([C,sesame,butter,_,_], Sol), C \== carlos,
member([_,_,_,other,_], Sol),
member([_,_,_,_,other], Sol).
我相信运行查询“bagels(X)”,应该可以为我提供问题的解决方案,但它返回false。我错过什么了吗?非常感谢 首先,问题陈述似乎需要一些审查——特别是第4点 这是一个逻辑难题。因此,您确实需要坚持Prolog的逻辑部分。但是,在您的代码中,我看到了
(\==)/2
和(==)/2
,它们都没有完全实现它们假装表示的逻辑关系。相反,请分别使用dif/2
和(=)/2
但是,即使在替换了它们之后,情况也没有改善多少,您的程序仍然失败。然而,有了一个纯粹的定义,你就有机会将问题局部化。您的问题是bagels(Sols)
失败。因此,目前的定义过于专业化,过于狭窄。因此,我将尝试通过删除您的一些要求来概括它。为此,我将在您的一些目标前面添加*
。我将对它们进行概括,使生成的程序仍然失败
剩下的是一个概括,它向您展示了您必须修改程序的地方。否则,错误将持续存在
编辑:我强调了我觉得特别奇怪的事情:两个男人在喝苦杏仁酒
:- op(950, fy, *).
*_.
bagels(Sol):-
Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
member([brad,X,plain,_,_], Sol),
dif(X,wheat),
member([walt,_,_,small,_], Sol),
member([_,_,_,medium1,hazelnut], Sol),
* 我试图提高可读性,使用DCG传递状态(在中查找“隐式传递状态”),因此此代码段与您的解决方案非常不同 你可以看到负面知识以两种不同的方式表达:当涉及到人时,我们可以直接使用
\=
,因为名字总是被实例化,但是对于其他值,比如kind(brad,K)
,我使用{dif(K,小麦)}
,因为K还不能被实例化
state(S), [state(T)] --> [state(T)], {member(S, T)}.
kind(P, K) --> state([P, K, _, _, _]).
topping(P, T) --> state([P, _, T, _, _]).
flavor(P, F) --> state([P, _, _, F, _]).
size(P, S) --> state([P, _, _, _, S]).
hint1 -->
kind(brad, K), {dif(K, wheat)}, topping(brad, plain), size(walt, small).
hint2 -->
size(P1, medium), size(P2, medium), {P1 \= P2},
flavor(P1, hazelnut), topping(P2, peanut_butter).
hint3 -->
kind(P, onion), flavor(P, french_vanilla), size(P, S), {dif(S, small)}.
hint4 -->
size(P1, large), flavor(P2, amaretto), kind(P3, wheat), topping(P4, egg_bacon),
{forall(select(X, [joe,P1,P2,P3,P4], Ps), maplist(\=(X), Ps))}.
hint5 -->
kind(rick, K), {dif(K, blueberry)}, flavor(rick, columbian),
kind(P, cheddar), flavor(P, amaretto), {P \= walt}.
hint6 -->
topping(P1, cream_cheese), kind(P2, blueberry), {P1 \= P2}, size(P1, large),
kind(P, sesame), topping(P, butter), {P \= carlos}.
bagels(Sol):- Sol =
[[brad,_,_,_,_],
[walt,_,_,_,_],
[joe,_,_,_,_],
[rick,_,_,_,_],
[carlos,_,_,_,_]],
phrase((hint1, hint2, hint3, hint4, hint5, hint6), [state(Sol)], _).
唉,我得到了太多的解决方案。。。也许我的提示翻译中有一个bug,或者所有不同的属性也应该应用于所有属性,就像提示n.4一样
?- aggregate(count,S^bagels(S),N).
N = 7.
我懂了。。。那么,您是否认为问题在于给定的问题过于具体,并且在措辞上存在错误?我不确定从你的概括到哪里去,因为它不能满足谜题的要求,除非我将删除的行添加回。@guypowermister:这个概括的要点是:只要剩下的可见部分没有修改,问题就会继续存在。所以你必须在剩下的可见部分做些改变。看看剩下的代码:
amaretto
-我觉得connexion很奇怪!你说:joe
有amaretto
但是,有人不是joe
,那家伙也应该有amaretto
,哦!这实际上可能就是问题所在。这意味着joe没有苦杏仁酒,但我在编写代码时错过了“\”。@guypowermister:这只是试图保持答案简短的功能。
?- aggregate(count,S^bagels(S),N).
N = 7.