2016-04-15 30 views
2

我想在Prolog中解決以下問題,並且我認爲我已經編寫了正確的代碼,但我的查詢只是返回false。有什麼建議要改變?問題是如下:Prolog中的邏輯謎題 - 使用列表

「貝果巷,當地的麪包圈店,總是怒不可遏活動的位置時 早晨通勤的人停下來讓他們的咖啡和麪包圈在上班的 方式新鮮製作在現場每天早晨,百吉餅是非常受歡迎, 的事實店也有很大的咖啡就像錦上添花!誰在貝果巷工作的人 是開朗和友善,以及勝任,所以 儘管大量的客戶,等待是永遠長或不愉快。喬 和他的同事今天早上停的四看什麼大家都 熱烈討論,並驚喜地發現,笑p達到了其聲望。確定每個同事的名字,每個有序什麼樣以其 餡料麪包圈,什麼味道的咖啡尺寸(小,中,大)「。

  1. 布拉德得到了他的麪包圈,這WASN」牛逼小麥,沒事就可以了。沃爾特有序的小咖啡。

  2. 兩個同事誰得到了中型咖啡是一個誰得到了榛子的味道,誰得到了他的百吉餅花生 黃油。

  3. 的一個
  4. 那個得到洋蔥百吉餅,但沒有用黃油的人也得到了法國香草咖啡,但不是小尺寸。

  5. 五個同事是喬,誰得到了較大的咖啡之一,誰得到了杏仁味咖啡的人,一個誰得到了小麥麪包圈, ,誰在他的百吉餅了雞蛋&培根的一個。

  6. 瑞克未訂購的藍莓麪包圈,但他卻獲得哥倫比亞咖啡。 Amaretto咖啡與切達乾酪百吉餅一起訂購,但不是由沃爾特製作而是 。

  7. 奶油奶酪沒有配備藍莓麪包圈,但它並配備了一大杯咖啡。芝麻百吉餅配上黃油,但是卡洛斯並沒有下令。

我已經寫了序言代碼是在這裏:

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). 

我相信,運行查詢 「百吉餅(X)」。應該給我解決問題的辦法,但它會返回錯誤。我錯過了什麼嗎?提前謝謝了!

回答

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]), 
    ... 
+0

我明白了......所以你認爲問題在於給定的問題過於具體,並且在措辭方面存在錯誤?我不確定從泛化到何處,因爲它不能滿足謎題的要求,除非我添加刪除的線。 – guypowermister

+1

@guypowermister:這種泛化的要點是:只要剩下的可見部分不是修改後,問題將持續。所以你必須改變剩下的可見部分。 – false

+1

看看其餘的代碼:'amaretto'-connexion對我來說看起來很奇怪!你說:有'amaeto'的'joe',但是有一個人不是**'joe',那個人也應該有'amaretto' ... – false

1

我試圖提高可讀性,採用DCG是傳遞狀態(尋找在this page「含蓄通過狀態各地」),所以這個片段是不是你的解決方案有很大不同。

你可以看到,知識espressed兩種不同的方式:那裏的人蔘與,我們可以直接使用\=,因爲名字總是被實例化,但對於其他的值,比如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.