我正试图在Prolog中解决以下问题,我认为我对它进行了正确的编码,但我的查询只是返回false。有什么改变的建议吗?问题如下:
"Bagel Alley,当地的百吉饼店,在早上通勤时,人们在路上停下来喝咖啡和吃百吉饼工作方式。每天早上在现场新鲜制作的百吉饼非常受欢迎事实上,这家店也有很棒的咖啡,这简直是锦上添花!人民在Bagel Alley工作的人都很愉快、友好,也很能干,所以尽管顾客众多,但等待的时间从不长,也从不令人不快。乔他的四个同事今天早上过来看看大家都怎么样胡言乱语,惊喜地发现这家商店没有辜负它的期望名誉确定每位同事的名字,用什么样的百吉饼浇头,以及每种咖啡的口味和大小(小、中或大)。"
-
布拉德拿到了他的百吉饼,不是小麦,上面什么都没有。沃尔特点了一小杯咖啡。
-
得到中等大小咖啡的两位同事是一位得到榛子味的,另一位得到花生百吉饼的黄油
-
那个买了洋葱百吉饼,但没有加黄油的,还买了法国香草咖啡,但不是小尺寸的。
-
这五个同事是乔,一个喝了一大杯咖啡的,一个吃了苦杏仁味咖啡的,还有一个吃小麦百吉饼的,而那个得到鸡蛋的人&他百吉饼上的培根。
-
里克没有点蓝莓百吉饼,但他点了哥伦比亚咖啡。阿玛雷托咖啡是和切达百吉饼一起点的,但不是沃尔特写的。
-
奶油奶酪没有配蓝莓百吉饼,但它配了一大杯咖啡。芝麻百吉饼配黄油,但是卡洛斯没有点。
我写的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。我是不是错过了什么?非常感谢!
首先,问题陈述似乎需要一些回顾,特别是第4点。
这里有一个逻辑谜题。因此,您确实需要坚持Prolog的逻辑部分。然而,在您的代码中,我看到了(==)/2
和(==)/2
,它们都没有完全实现它们所表示的逻辑关系。相反,请分别使用dif/2
和(=)/2
。
但即使更换了这些,情况也没有好到哪里去,你的程序仍然会失败。然而,使用纯定义,您有机会本地化问题。您的问题是bagels(Sols)
失败。因此,目前的定义过于专业化,过于狭隘。因此,我将尝试通过删除您的一些要求来概括它。为此,我将在您的一些目标前面添加*
。我将对它们进行归纳,使生成的程序仍然失败。
剩下的是一个概括,它向您显示有修改程序的位置。否则,错误将持续存在。
编辑:我强调了一件在我看来特别奇怪的事:两个男人在喝苦杏仁酒。
:-op(950,fy,*)。*_。百吉饼(Sol):-Sol=[[,_,_,_],[,_,,_,],[_,_,成员([brad,X,plain,_,_],Sol),dif(X,小麦),成员([walt,_,_,small,_],Sol),成员([,_,_,medium 1,榛子],Sol),*成员([_,_,peanut_butter,medium 2,_],Sol),成员([_,洋葱,Y,Z,french_vanilla],Sol),*dif(Y,黄油),dif(Z,小),成员([joe,Ja,Jb,Jc,Jd],Sol),*dif(Ja,小麦),*dif(Jb,egg_bacon),dif(Jc,大),Jd=苦杏仁,*成员([La,Lb,Lc,large,Ld],Sol),*dif(La,joe),*dif(Lb,小麦,成员([Aa,Ab,Ac,Ad,苦杏仁],Sol),dif(Aa,joe),*dif(Ab,小麦),*dif(Ac,egg_bacon)*,成员([Wa,小麦,Wb,Wc,Wd],Sol),*dif(Wa,joe),*dif(Wb,egg_bacon),dif(Wc,大),dif(Wd,苦杏仁),成员([Ea,Eb,egg_bacon,Ec,Ed],Sol),*dif(Ea,joe),dif(Eb,小麦),*dif(Ec,大),dif(Ed,苦杏仁),成员([rick,R,_,_,columbian],Sol),*dif(R,蓝莓),*成员([A,cheddar,_,_,amaretto],Sol),*dif(A,walt),成员([_,B,cream_cheese,large,_],Sol),*dif(B,蓝莓),*成员([C,芝麻,黄油,_,_],Sol),*dif(C,carlos),*成员([,_,_,other,_],Sol),*成员([,_,_,其他],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]),
...
我试图提高可读性,使用DCG来传递状态(在本页中查找"隐式传递状态"),所以这个片段与您的解决方案非常不同。
您可以看到负面知识以两种不同的方式表达:在涉及人员的地方,我们可以直接使用=
,因为名称总是实例化的,但对于其他值,如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.