我正在尝试解决Prolog中的以下问题,我认为我已将其编码正确,但我的查询只是返回false。关于改变什么的任何建议?问题如下:
" Bagel Alley,当地的百吉饼店,在此过程中始终是一个激烈的活动场所 上午通勤,因为人们停下来喝咖啡和面包圈 工作方式。每天早上新鲜制作,百吉饼非常受欢迎 事实上,这家商店也有很棒的咖啡,就像锦上添花!人民 在Bagel Alley工作的人既开朗又友好,也很有能力 尽管客户数量很大,但等待时间并不长或令人不愉快。乔 今天早上他的四个同事停下来看看每个人都是谁 发现并且惊喜地发现这家商店辜负了它 声誉。确定每个同事的名字,用什么样的百吉饼 打顶,以及每种咖啡的口味和大小(小,中或大)。"
布拉德得到了他的百吉饼,这不是小麦,没有任何东西。沃尔特点了一杯小咖啡。
两个喝中等咖啡的同事是榛子风味的人和拿着花生的百吉饼的人 黄油。
那个拿着洋葱百吉饼而不是黄油的人也买了法国香草咖啡,但不是那么小。
五个同事是Joe,一个拿着大咖啡的人,一个拿着Amaretto风味的咖啡,一个拿着小麦面包的人, 和那个得到鸡蛋和蛋的人培根在他的百吉饼上。
Rick没有订购蓝莓面包圈,但他确实得到了哥伦比亚咖啡。 Amaretto咖啡是用切达干酪面包卷订购的 不是沃尔特。
奶油奶酪没有配蓝莓百吉饼,但确实带有一大杯咖啡。芝麻百吉饼配黄油但是 卡洛斯没有点它。
我写的Prolog代码在这里:
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。我错过了什么吗?非常感谢提前!
答案 0 :(得分:3)
首先,似乎问题陈述需要一些审查 - 特别是第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), *member([_,_,peanut_butter,medium2,_], Sol), member([_,onion,Y,Z,french_vanilla], Sol), *dif(Y,butter), dif(Z,small), member([joe,Ja,Jb,Jc,Jd], Sol), *dif(Ja,wheat), *dif(Jb,egg_bacon), dif(Jc,large), Jd=amaretto, *member([La,Lb,Lc,large,Ld], Sol), *dif(La,joe), *dif(Lb,wheat), *dif(Lc,egg_bacon), *dif(Ld,amaretto), member([Aa,Ab,Ac,Ad,amaretto], Sol), dif(Aa,joe), *dif(Ab,wheat), *dif(Ac,egg_bacon), *dif(Ad,large), member([Wa,wheat,Wb,Wc,Wd], Sol), *dif(Wa, joe), *dif(Wb, egg_bacon), dif(Wc, large), dif(Wd, amaretto), member([Ea,Eb,egg_bacon,Ec,Ed], Sol), *dif(Ea, joe), dif(Eb, wheat), *dif(Ec, large), dif(Ed, amaretto), member([rick,R,_,_,columbian], Sol), *dif(R,blueberry), *member([A,cheddar,_,_,amaretto], Sol), *dif(A,walt), member([_,B,cream_cheese,large,_], Sol), *dif(B,blueberry), *member([C,sesame,butter,_,_], Sol), *dif(C, carlos), *member([_,_,_,other,_], Sol), *member([_,_,_,_,other], Sol).
不过,你可能会不高兴:为什么还剩下这么多代码?这样做的原因是你忘了在开始时陈述一些一般性的观察。特别是他们想要所有不同的浇头。利用该信息,程序片段缩小到仅突出显示的行。但是,必须使用library(lambda)
开始实现以下目标。
bagels(Sol):-
Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
maplist(Sol+\P^member([P|_], Sol),
[brad,walt,joe,rick,carlos]),
maplist(Sol+\D^member([_,_,_,_,D], Sol),
[amaretto,french_vanilla,hazelnut,columbian,other]),
...
答案 1 :(得分:1)
我尝试提高可读性,使用DCG传递状态(查找'隐式传递this page中的状态),所以这个代码段与你的解决方案。
您可以看到否定知识以两种不同的方式表达:人们参与其中,我们可以直接使用\=
,因为名称总是被实例化,但是对于其他值,例如kind(brad, K)
,我使用{dif(K, wheat)}
,因为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)], _).
唉,我得到了太多的解决方案...也许我的提示中有一个错误'翻译,或all_different也应该应用于所有属性,如提示n.4所做。
?- aggregate(count,S^bagels(S),N).
N = 7.