2016-04-15 15 views
2

Ich versuche, das folgende Problem in Prolog zu lösen, und ich denke, ich habe es richtig codiert, aber meine Abfragen geben einfach falsch zurück. Irgendwelche Ratschläge, was man ändern sollte? Das Problem ist, wie folgt:.Logic Puzzle in Prolog - mit Listen

„Bagel Alley, der lokale Bagel-Shop, war immer ein Ort der wütenden Aktivität während des morgens auf dem Weg, wie Menschen zu arbeiten gestoppt, indem zu ihrem Kaffee und Bagel auf dem Weg Frisch gemacht Vor Ort jeden Morgen, die Bagels waren sehr beliebt und die Tatsache, dass das Geschäft hatte auch großen Kaffee war wie Zuckerguss auf dem Kuchen! Die Leute wer bei Bagel Alley arbeitete waren fröhlich und freundlich, sowie kompetent, so trotz der Eine große Menge an Kunden, die Wartezeit war nie lang oder unangenehm. "Joe und vier seiner Mitarbeiter stoppte an diesem Morgen um zu sehen, was alle schwärmten und waren angenehm überrascht, dass die sho p hat seine Reputation bis zum erreicht. Bestimmen Sie den Namen der einzelnen Mitarbeiter, welche Art von Bagel mit seinem Topping, und was Geschmack und Größe Kaffee (klein, mittel oder groß), die jeweils bestellt.“

  1. Brad bekam seinen Bagel, die wasn‘ t Weizen, mit nichts drauf. Walt bestellen einen kleinen Kaffee.

  2. die beiden Mitarbeiter, die mittelgroße Kaffee bekam derjenige war, der den Haselnuss-Geschmack bekam und derjenige, der seine Bagel bekam mit Erdnuss Butter.

  3. Wer den Zwiebelbagel aber nicht mit Butter bekam, bekam auch ein französischer Vanillekaffee, aber nicht die kleine Größe.

  4. Die fünf Mitarbeiter waren Joe, derjenige, der einen großen Kaffee bekam, derjenige, der Amaretto aromatisierten Kaffee bekam, derjenige, der einen Weizen Bagel bekam, und derjenige, der auf seinem Bagel Ei & Speck bekam.

  5. Rick hat den Blaubeer-Bagel nicht bestellt, aber er hat kolumbianischen Kaffee bekommen. Der Amaretto-Kaffee wurde mit dem Cheddar Bagel aber nicht von Walt bestellt.

  6. Der Frischkäse war nicht mit dem Blaubeer Bagel, aber es kam mit einem großen Kaffee. Der Sesambagel kam mit Butter aber Carlos bestellte es nicht.

Der Prolog Code, den ich geschrieben habe, ist hier:

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

Ich glaube, dass die Abfrage ausgeführt wird "Bagels (X)." sollte mir die Lösung für das Problem geben, aber es gibt falsch zurück. Fehle ich etwas? Vielen Dank im Voraus!

Antwort

3

Zunächst scheint es, dass die Problemstellung eine Überprüfung muss - insbesondere auf Nummer 4.

Was Sie hier haben, ist ein logischen Rätsel. Daher müssen Sie sich wirklich an den logischen Teil von Prolog halten. In Ihrem Code sehe ich jedoch (\==)/2 und (==)/2, die beide die logischen Beziehungen, die sie vorgeben darzustellen, nicht vollständig realisieren. Verwenden Sie stattdessen dif/2 bzw. (=)/2.

Aber selbst nach dem Ersetzen von diesen, die Dinge sind nicht viel besser, Ihr Programm immer noch scheitert. Mit einer reinen Definition haben Sie jedoch eine Chance, das Problem zu lokalisieren. Ihr Problem ist, dass bagels(Sols) fehlschlägt. Daher ist die aktuelle Definition zu spezialisiert, zu eng. Ich werde versuchen, es zu verallgemeinern, indem ich einige Ihrer Anforderungen lösche. Zu diesem Zweck werde ich * vor einigen Ihrer Ziele hinzufügen. Ich werde sie verallgemeinern, so dass das resultierende Programm immer noch fehlschlägt.

Was ist übrig ist eine Verallgemeinerung, die Ihnen zeigt, wo Sie haben, um Ihr Programm zu ändern. Andernfalls bleibt der Fehler bestehen.

Edit: Ich habe hervorgehoben, was mir besonders komisch vorkommt: Zwei Männer trinken 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). 

Trotzdem könnten Sie unglücklich sein: Warum gibt es so viel Code? Der Grund dafür ist, dass Sie am Anfang einige allgemeine Beobachtungen vergessen haben. Insbesondere, dass sie alle ein anderes Topping wollten. Mit diesen Informationen schrumpft das Programmfragment auf nur die hervorgehobenen Zeilen. Allerdings muss man mit folgenden Zielen beginnen: 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

Ich sehe ... Also glauben Sie, dass das Problem ist, dass das gegebene Problem zu spezifisch ist, und hat Fehler in der Art, wie es formuliert ist? Ich bin nicht sicher, wohin ich von Ihrer Verallgemeinerung gehen soll, da es die Anforderungen des Puzzles nicht erfüllen würde, wenn ich die entfernten Zeilen nicht wieder hinzufüge. – guypowermister

+1

@guypowermister: Der Sinn dieser Verallgemeinerung ist: Solange der verbleibende sichtbare Teil nicht ist modifiziert, bleibt das Problem bestehen. Sie müssen also etwas im verbleibenden sichtbaren Teil ändern. – false

+1

Schauen Sie sich den restlichen Code an: die 'Amaretto'-Verbindung sieht mir sehr komisch aus! Du sagst: Es gibt 'Joe' mit' Amaretto', aber dann gibt es jemanden, der ** nicht ** 'Joe' ist und dieser Typ sollte auch' Amaretto' haben ... – false

1

Ich habe versucht, die Lesbarkeit zu verbessern, einen DCG mit dem Staat zu übergeben um (suchen in this page ‚Implizit Staaten um vorbei‘), so dass dieser Schnipsel ist ganz anders als Ihre Lösung.

Sie können sehen, dass negativ Wissen auf zwei verschiedene Arten espressed ist: wo Menschen beteiligt ist, können wir direkt \= verwenden, da Namen immer instanziiert werden, sondern auch für andere Werte, wie kind(brad, K), verwende ich {dif(K, wheat)}, da K konnte noch nicht instanziiert werden.

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

Ach, komme ich zu viel Lösungen ... vielleicht gibt es einen Fehler in meiner Hinweise Übersetzung oder die all_different angewendet werden sollte, um alle auch Attribute, wie Hinweis n.4 getan

?- aggregate(count,S^bagels(S),N). 
N = 7.