Prolog中的逻辑难题-使用列表 [英] Logic Puzzle in Prolog - using lists

查看:92
本文介绍了Prolog中的逻辑难题-使用列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决Prolog中的以下问题,并且我想我已经对它进行了正确编码,但是我的查询只是返回false.有什么建议可以更改吗?问题如下:

I am trying to solve the following problem in Prolog, and I think I have coded it right, but my queries simply return false. Any advice on what to change? The problem is as follows:

百吉饼巷(Bagel Alley),当地的百吉饼商店,在 早上下班途中人们停下来喝咖啡和百吉饼. 工作方式.百吉饼每天早上在现场新鲜制作,非常受欢迎, 这家商店还提供优质咖啡的事实就像锦上添花!人民 在Bagel Alley工作的人开朗而友善,而且能干,所以 尽管有大量的客户,但等待从未是漫长或令人不愉快的.乔 今天早上他的四个同事停下来看看大家 到处乱逛,惊喜地发现这家商店辜负了它的声誉. 名声.确定每个同事的名字,什么样的百吉饼与它 打顶,以及每种咖啡的口味和大小(小,中或大)如何."

"Bagel Alley, the local bagel shop, was always a location of furious activity during the morning commute as people stopped by to get their coffee and bagel on the way to work. Fresh made on site each morning, the bagels were highly popular and the fact that the shop also had great coffee was like icing on the cake! The people who worked at Bagel Alley were cheerful and friendly, as well as competent, so despite the large volume of customers, the wait was never long or unpleasant. Joe and four of his coworkers stopped by this morning to see what everyone was raving about and were pleasantly surprised to find that the shop lived up to its reputation. Determine the name of each coworker, what kind of bagel with its topping, and what flavor and size of coffee (small, medium, or large) each ordered."

  1. 布拉德(Brad)拿到了不是小麦的百吉饼,上面没有任何东西.沃尔特点了一杯咖啡.

  1. Brad got his bagel, which wasn’t wheat, with nothing on it. Walt ordered a small coffee.

获得中型咖啡的两个同事是榛子味的人和用花生面包圈的人 黄油.

The two coworkers who got medium sized coffees were the one who got the hazelnut flavor and the one who got his bagel with peanut butter.

得到洋葱百吉饼但不加黄油的人,也得到了法国香草咖啡,但体积不小.

The one who got the onion bagel, but not with butter, also got a French vanilla coffee, but not the small size.

这五个同事是Joe,一个喝了大咖啡的人,一个喝了Amaretto风味咖啡的人,一个喝了小麦百吉饼的人, 还有那个拿到鸡蛋和鸡蛋的人培根面包上的培根.

The five coworkers were Joe, the one who got a large coffee, the one who got Amaretto flavored coffee, the one who got a wheat bagel, and the one who got egg & bacon on his bagel.

Rick没点蓝莓百吉饼,但他确实得到了哥伦比亚咖啡. Amaretto咖啡与切达百吉饼一起订购,但 不是沃尔特.

Rick didn’t order the blueberry bagel but he did get Columbian coffee. The Amaretto coffee was ordered with the cheddar bagel but not by Walt.

奶油芝士没有蓝莓百吉饼,但确实有大杯咖啡.芝麻百吉饼加黄油,但 卡洛斯没有订购.

The cream cheese did not come with the blueberry bagel but it did come with a large coffee. The sesame bagel came with butter but Carlos didn’t order it.

我编写的Prolog代码在这里:

The Prolog code I have written is here:

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.我想念什么吗?提前非常感谢!

I believe that running the query "bagels(X)." should give me the solution to the problem, but it returns false. Am I missing something? Many thanks in advance!

推荐答案

首先,似乎问题陈述需要进行一些审查-特别是第4点.

First, it seems that the problem statement needs some review - in particular point 4.

这里有一个逻辑难题.因此,您确实需要坚持Prolog的逻辑部分.但是,在您的代码中,我看到了(\==)/2(==)/2,它们都没有完全实现它们假装表示的逻辑关系.而是分别使用dif/2(=)/2.

What you have here is a logical puzzle. Thus you really need to stick to the logical part of Prolog. However, in your code I see (\==)/2 and (==)/2 which both do not fully realize the logical relations they pretend to represent. Instead, use dif/2 and (=)/2 respectively.

但是即使替换了这些,情况也不会好得多,您的程序仍然会失败.但是,使用纯粹的定义,您就有机会本地化问题.您的问题是bagels(Sols)失败.因此,当前的定义过于专业化,过于狭窄.因此,我将尝试通过删除一些要求来对其进行概括.为此,我将在您的某些目标之前添加*.我将对它们进行泛化,以使生成的程序仍然失败.

But even after replacing those, things are not much better, your program still fails. However, with a pure definition you have a chance to localize the problem. Your problem is that bagels(Sols) fails. Thus, the current definition is too specialized, too narrow. So I will try to generalize it by removing some of your requirements. To this end, I will add * in front of some of your goals. I will generalize them such that the resulting program still fails.

剩下的是一种概括,向您显示修改程序的位置.否则,错误将继续存在.

What is left is a generalization that shows you where you will have to modify your program. Otherwise, the error will persist.

我已经突出显示了对我来说尤为奇怪的东西:两名男子喝了杏仁酒.

I have highlighted what looks particularly odd to me: Two men drinking amaretto.


:- 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) 从以下目标开始.

Still, you might be unhappy: Why is there so much code left? The reason for this is that you forgot to state some general observations in the beginning. In particular that they wanted all a different topping. With that information the program fragment shrinks down to just the lines highlighted. However, one has to start with the following goals using 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]),
    ...

这篇关于Prolog中的逻辑难题-使用列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆