2016-04-15 1 views
2

J'essaie de résoudre le problème suivant dans Prolog, et je pense que je l'ai bien codé, mais mes requêtes retournent simplement false. Des conseils sur quoi changer? Le problème est le suivant:.Logic Puzzle dans Prolog - en utilisant les listes

« Bagel Alley, le magasin de bagel local, a toujours été un lieu d'activité furieuse pendant le trajet du matin que les gens se sont arrêtés pour obtenir leur café et bagel sur la façon de travailler la fraîcheur Sur le site chaque matin, les bagels étaient très populaires et le fait que le magasin avait aussi du bon café était comme la cerise sur le gâteau! Les personnes qui travaillaient à Bagel Alley étaient gaies et amicales, ainsi que compétentes, donc malgré le fait que Un grand nombre de clients, l'attente n'a jamais été longue ou désagréable Joe et et quatre de ses collègues se sont arrêtés ce matin pour voir ce que tout le monde était ravi et ont été agréablement surpris de constater que le sho p a vécu jusqu'à sa réputation . Déterminer le nom de chaque collaborateur, quel genre de bagel avec son nappage , et quelle saveur et la taille du café (petite, moyenne ou grande) chacun commandés. »

  1. Brad a obtenu son bagel, ce qui n » était pas t de blé, avec rien dessus. Walt commandé un petit café.

  2. les deux collègues qui ont obtenu des cafés de taille moyenne ont été celui qui a la saveur de noisette et celui qui a obtenu son bagel avec du beurre d'arachide .

  3. Celui qui a obtenu le bagel à l'oignon, mais pas avec du beurre, a aussi un café à la vanille française, mais pas la petite taille.

  4. Les cinq collègues de travail étaient Joe, celui qui a obtenu un grand café, celui qui a obtenu le café aromatisé Amaretto, celui qui a obtenu un bagel de blé, et celui qui a obtenu le bacon oeuf & sur son bagel. Rick n'a pas commandé le bagel aux myrtilles, mais il a reçu du café colombien. Le café Amaretto a été commandé avec le bagel cheddar, mais pas par Walt.

  5. Le fromage à la crème n'était pas fourni avec le bagel aux myrtilles mais il était accompagné d'un grand café. Le sésame bagel est venu avec du beurre mais Carlos ne l'a pas commandé.

Le code Prolog je l'ai écrit est ici:

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

Je crois que la requête en cours d'exécution "bagels (X)." devrait me donner la solution au problème, mais il renvoie faux. Est-ce que je manque quelque chose? Merci d'avance!

Répondre

3

Tout d'abord, il semble que l'énoncé du problème a besoin d'un examen - en particulier le point 4.

Qu'est-ce que vous avez ici est un logique puzzle. Vous devez donc vous en tenir à la partie logique de Prolog. Cependant, dans votre code, je vois (\==)/2 et (==)/2 qui ne réalisent pas complètement les relations logiques qu'ils prétendent représenter. Au lieu de cela, utilisez dif/2 et (=)/2 respectivement.

Mais même après avoir remplacé ceux-ci, les choses ne vont pas beaucoup mieux, votre programme échoue toujours. Cependant, avec une définition pure vous avez une chance de localiser le problème. Votre problème est que bagels(Sols) échoue. Ainsi, la définition actuelle est trop spécialisée, trop étroite. Je vais donc essayer de généraliser en supprimant certaines de vos exigences. À cette fin, je vais ajouter * en face de certains de vos objectifs. Je vais les généraliser de telle sorte que le programme résultant échoue toujours.

Ce qui reste est une généralisation qui vous montre où vous aurez ont pour modifier votre programme. Sinon, l'erreur persistera.

Edit: J'ai mis en évidence ce qui me semble particulièrement étrange: Deux hommes buvant de l'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). 

encore, vous pourriez être malheureux: Pourquoi est-il si le code reste plus grand chose? La raison en est que vous avez oublié d'énoncer quelques observations générales au début. En particulier qu'ils voulaient tous une garniture différente. Avec cette information, le fragment du programme se réduit aux seules lignes mises en évidence. Cependant, il faut commencer par les objectifs suivants en utilisant 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

Je vois ... Donc, croyez-vous que le problème est que le problème donné est trop spécifique, et a des erreurs dans la façon dont il est libellé? Je ne sais pas où aller à partir de votre généralisation, car il ne répondrait pas aux exigences du puzzle, à moins que j'ajoute les lignes supprimées. – guypowermister

+1

@guypowermister: Le point de cette généralisation est: Tant que la partie visible restante n'est pas modifié, le problème persistera. Vous devez donc changer quelque chose dans la partie visible restante. – false

+1

Regardez le code restant: la connexion 'amaretto' me semble très étrange! Vous dites: il y a 'joe' avec' amaretto' mais ensuite, il y a quelqu'un qui est ** pas ** 'joe' et ce gars devrait avoir' amaretto', aussi ... – false

1

J'ai essayé d'améliorer la lisibilité, en utilisant un DCG pour passer l'état autour de (chercher « passer Implicitement états autour » dans this page), de sorte que cet extrait est très différent de votre solution.

Vous pouvez voir que négatif connaissances est espressed de deux façons différentes: où les gens sont impliqués, nous pouvons utiliser directement \=, puisque les noms sont toujours instanciées, mais pour d'autres valeurs, comme kind(brad, K), j'utiliser {dif(K, wheat)}, puisque K pourrait ne pas être instancié pour l'instant.

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

Hélas, je reçois des solutions trop ... peut-être il y a un bug dans la traduction de mes notes, ou all_different doit être appliqué à tous les attributs aussi bien, comme cela se fait pour soupçon N.4

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