2016-04-20 2 views
2

J'ai implémenté Einstein Riddle dans Prolog et j'essaie de savoir qui avait un poisson à la maison.
Je ne peux pas trouver à redire dans ce code et l'option de trace ne contribue pas à ce problème;)Einstein Devinette avec la liste des termes

Règles:

  1. Norvégien vit dans la première maison
  2. L'Anglais vit dans une maison rouge.
  3. La maison verte est située directement sur le côté gauche de la maison blanche.
  4. Dane boivent du thé.
  5. Fumeur léger vit à côté des éleveurs de chats.
  6. Un résident de la maison jaune fume un cigare.
  7. Allemand fume une pipe à eau. Un résident du centre du centre boit du lait.
  8. Un fumeur léger a un voisin qui boit de l'eau.
  9. Cigarettes fumigènes sans oiseaux nicheurs filtrants.
  10. Chiens de race suédoise.
  11. Le Norvégien vit à côté de la maison bleue.
  12. Eleveur de chevaux vit à côté de la maison jaune.
  13. Bière à la fumée de menthol.
  14. Dans la serre, ils boivent du café.

Voici mon code:

on_the_left(X, Y, N) :- 
    Y is X - 1, 
    \+ Y < 1, 
    \+ X > N. 

next_to(X, Y, N) :- 
    (Y is X + 1; 
     Y is X - 1), 
    \+ X > N, 
    \+ Y > N, 
    \+ X < 1, 
    \+ Y < 1. 

fish(Who) :- 
    Houses = [ 
     house(1, _Color1, _From1, _Animal1, _Drink1, _Smoke1), 
     house(2, _Color2, _From2, _Animal2, _Drink2, _Smoke2), 
     house(3, _Color3, _From3, _Animal3, _Drink3, _Smoke3), 
     house(4, _Color4, _From4, _Animal4, _Drink4, _Smoke4), 
     house(5, _Color5, _From5, _Animal5, _Drink5, _Smoke5) ], 
    N is 5, 
    %-- hint 1 
    member(house(1, _, norway, _, _, _), Houses), 
    %-- hint 2 
    member(house(_, red, england, _, _, _), Houses), 
    %-- hint 3 - on_the_left 
    member(house(GREEN, green, _, _, _, _), Houses), 
    member(house(WHITE, white, _, _, _, _), Houses), 
    on_the_left(GREEN, WHITE, N), 
    %-- hint 4 
    member(house(_, _, denmark, _, tea, _), Houses), 
    %-- hint 5 - next_to 
    member(house(LIGHT, _, _, _, _, light), Houses), 
    member(house(CAT, _, _, cat, _, light), Houses), 
    next_to(LIGHT, CAT, N), 
    %-- hint 6 
    member(house(_, yellow, _, _, _, cigar), Houses), 
    %-- hint 7 
    member(house(_, _, germany, _, _, waterpipe), Houses), 
    %-- hint 8 
    member(house(3, _, _, _, milk, _), Houses), 
    %-- hint 9 - next_to 
    member(house(WATER, _, _, _, water, _), Houses), 
    next_to(LIGHT, WATER, N), 
    %-- hint 10 
    member(house(_, _, _, bird, _, nofilter), Houses), 
    %-- hint 11 
    member(house(_, _, sweden, dog, _, _), Houses), 
    %-- hint 12 - next_to 
    member(house(NORWAY, _, norway, _, _, _), Houses), 
    member(house(BLUE, blue, _, _, _, _), Houses), 
    next_to(NORWAY, BLUE, N), 
    %-- hint 13 - next_to 
    member(house(HORSE, _, _, horse, _, _), Houses), 
    next_to(HORSE, GREEN, N), 
    %-- hint 14 
    member(house(_, _, _, _, beer, menthol), Houses), 
    %-- hint 15 
    member(house(_, green, _, _, coffee, _), Houses), 

    %-- FINAL QUESTION - WHO LET THE FISH OUT? 
    member(house(_, _, _, fish, _, _), Houses), 
    member(house(_, _, Who, fish, _, _), Houses). 

J'ai essayé beaucoup de combinaisons, mais:

- poissons (Qui)?.
faux.

Edit:
code travaille maintenant, ce que j'ai changé:

1 * De:

%-- hint 5 - next_to 
member(house(LIGHT, _, _, _, _, light), Houses), 
member(house(CAT, _, _, cat, _, light), Houses), 

Pour:

%-- hint 5 - next_to 
    member(house(LIGHT, _, _, _, _, light), Houses), 
    member(house(CAT, _, _, cat, _, _), Houses), 

2 * De:

%-- hint 13 - next_to 
member(house(HORSE, _, _, horse, _, _), Houses), 
next_to(HORSE, GREEN, N), 

Pour:

%-- hint 13 - next_to 
member(house(YELLOW, yellow, _, _, _, _), Houses), 
member(house(HORSE, _, _, horse, _, _), Houses), 
next_to(HORSE, YELLOW, N), 

Si vous lisez ce regard à @Enigmativity commentaire sur les structures en aide prédicats aswell.

+0

Vrai, merci. J'ai ajouté une règle. Erreur dans 5 indice est réparé mais le programme ne fonctionne toujours pas. – CryptoNewbie

Répondre

3

Vous avez eu deux erreurs dans vos indices - la première que vous avez déjà fixée avec le fumeur light. La deuxième est que le propriétaire horse vit à côté de la maison yellow, pas le green.

Maintenant, mon prologue s'est étouffé sur l'opérateur \+ alors j'ai recodé vos prédicats d'aide. Voilà ce que je l'ai fait:

 
first(H,[H|_]). 

on_the_left(X,Y,[X,Y|_]). 
on_the_left(X,Y,[_|Hs]) :- on_the_left(X,Y,Hs). 

next_to(X,Y,[X,Y|_]). 
next_to(X,Y,[Y,X|_]). 
next_to(X,Y,[_|Hs]) :- next_to(X,Y,Hs). 

middle(X,[_,_,X,_,_]). 

Maintenant puzzle travaillé bien avec ces indices:

 
fish(Who) :- 
    Houses = [ 
     house(_Color1, _From1, _Animal1, _Drink1, _Smoke1), 
     house(_Color2, _From2, _Animal2, _Drink2, _Smoke2), 
     house(_Color3, _From3, _Animal3, _Drink3, _Smoke3), 
     house(_Color4, _From4, _Animal4, _Drink4, _Smoke4), 
     house(_Color5, _From5, _Animal5, _Drink5, _Smoke5) ], 
    first(house(_, norway, _, _, _), Houses), %-- hint 1 
    member(house(red, england, _, _, _), Houses), %-- hint 2 
    on_the_left(house(green, _, _, _, _), house(white, _, _, _, _), Houses), %-- hint 3 - on_the_left 
    member(house(_, denmark, _, tea, _), Houses), %-- hint 4 
    next_to(house(_, _, _, _, light), house(_, _, cat, _, _), Houses), %-- hint 5 - next_to 
    member(house(yellow, _, _, _, cigar), Houses), %-- hint 6 
    member(house(_, germany, _, _, waterpipe), Houses), %-- hint 7 
    middle(house(_, _, _, milk, _), Houses), %-- hint 8 
    next_to(house(_, _, _, _, light), house(_, _, _, water, _), Houses), %-- hint 9 - next_to 
    member(house(_, _, bird, _, nofilter), Houses), %-- hint 10 
    member(house(_, sweden, dog, _, _), Houses), %-- hint 11 
    next_to(house(_, norway, _, _, _), house(blue, _, _, _, _), Houses), %-- hint 12 - next_to 
    next_to(house(_, _, horse, _, _), house(yellow, _, _, _, _), Houses), %-- hint 13 - next_to 
    member(house(_, _, _, beer, menthol), Houses), %-- hint 14 
    member(house(green, _, _, coffee, _), Houses), %-- hint 15 
    member(house(_, Who, fish, _, _), Houses), 
    write(Houses), nl. 

J'ai obtenu:

 
[house(yellow, norway, cat, water, cigar), house(blue, denmark, horse, tea, light), house(red, england, bird, milk, nofilter), house(green, germany, fish, coffee, waterpipe), house(white, sweden, dog, beer, menthol)] 
germany 
+0

Merci, j'ai réparé la deuxième erreur et son fonctionnement bien maintenant. J'ai besoin de dormir propablement;) Son travail avec ma version de prédicats d'aide, mais est une meilleure pratique pour l'écrire comme vous, non? – CryptoNewbie

+0

@CryptoNewbie - J'essaie d'éviter les opérations numériques si possible. Prolog est le meilleur des solutions structurelles - donc un prédicat comme 'middle (X, [_, _, X, _, _]). Est simple et structurel. J'essaie également d'implémenter chaque indice comme un seul terme dans le prédicat 'fish/1' - ce qui le rend beaucoup plus facile à lire et donc plus facile à déboguer et à maintenir. Ce serait mes deux suggestions pour vous. – Enigmativity

+1

Quels Prolog étouffe sur '(\ +)/1' ?? – false

1

juste pour montrer un schéma de codage alternatif:

solve :- solve(Sol, From), writeln(From), maplist(writeln, Sol). 

solve(Sol, From) :- 
    phrase((from(1, norway) 
     ,color(red) = from(england) 
     ,color(GREEN, green), color(WHITE, white), {GREEN is WHITE-1} 
     ,from(denmark) = drink(tea) 
     ,smoke(Light, light), animal(Cat, cat), next_to(Light, Cat) 
     ,color(Yellow, yellow), smoke(Yellow, cigar) 
     ,from(germany) = smoke(waterpipe) 
     ,drink(3, milk) 
     ,drink(Water, water), next_to(Light, Water) 
     ,animal(bird) = smoke(nofilter) 
     ,from(sweden) = animal(dog) 
     ,from(NORWAY, norway), color(BLUE, blue), next_to(NORWAY, BLUE) 
     ,animal(HORSE, horse), next_to(HORSE, GREEN) % next_to(HORSE, Yellow) 
     ,drink(beer) = smoke(menthol) 
     ,color(green) = drink(coffee) 
     ,animal(Fish, fish), from(Fish, From) 
    ), [[1,_,_,_,_,_], 
     [2,_,_,_,_,_], 
     [3,_,_,_,_,_], 
     [4,_,_,_,_,_], 
     [5,_,_,_,_,_] 
    ], Sol). 

state(S), [A,B,C,D,E] --> [A,B,C,D,E], {member(S, [A,B,C,D,E])}. 

color(A, B) --> state([A,B,_,_,_,_]). 
from(A, B) --> state([A,_,B,_,_,_]). 
animal(A, B) --> state([A,_,_,B,_,_]). 
drink(A, B) --> state([A,_,_,_,B,_]). 
smoke(A, B) --> state([A,_,_,_,_,B]). 

X = Y --> { 
    X=..[Fx|Ax], Y=..[Fy|Ay], 
    Xs=..[Fx,S|Ax], Ys=..[Fy,S|Ay] 
}, call(Xs), call(Ys). 

next_to(X, Y) --> {1 is abs(X-Y)}. 
+0

Génial! Actuellement, cela ne donne que "false". – mat

+0

@mat: Je suis parti commenté la correction '% next_to (HORSE, Yellow)'. Le crédit pour la chasse aux bogues va en effet à l'énigmativité – CapelliC