User Tools

Site Tools


sc330_f2016:smaplesolution.pl
% Problem #1, "It's a tie", Dell Logic Puzzles, October 1999
% Each man (mr so-and-so) got a tie from a relative.
tie(cupids).
tie(happy_faces).
tie(leprechauns).
tie(reindeer).
 
mr(crow).
mr(evans).
mr(hurley).
mr(speigler).
 
relative(daughter).
relative(father_in_law).
relative(sister).
relative(uncle).
 
solve :-
    tie(CrowTie), tie(EvansTie), tie(HurleyTie), tie(SpeiglerTie),
    all_different([CrowTie, EvansTie, HurleyTie, SpeiglerTie]),
    %This predicate first chooses some ties.
    %It will choose the same tie for everybody, then repeatedly backtrack
    %choosing different ties, until the all_different predicate is satisfied.
    %It then does the same thing for relatives.
    %There is a more efficent way of doing this, but this is the simplest.
    relative(CrowRelative), relative(EvansRelative),
    relative(HurleyRelative), relative(SpeiglerRelative),
    all_different([CrowRelative, EvansRelative, HurleyRelative, SpeiglerRelative]),
 
    %each list is a triple [mr, tie, relative]
    %Notice we specify the mr, this is arbitrary we could have specified the tie
    %as long as we cover all three dimentions
    Triples = [ [crow, CrowTie, CrowRelative],
                [evans, EvansTie, EvansRelative],
                [hurley, HurleyTie, HurleyRelative],
                [speigler, SpeiglerTie, SpeiglerRelative] ],
 
    % 1. The tie with the grinning leprechauns wasn't a present from a daughter.
    %The underscore, _, is a variable that could unify with anything, and you don't care what.
    \+ member([_, leprechauns, daughter], Triples),
%Negation isn't difficult, but it's tricky. Here's what you need to remember about negation:
%Whether negation succeeds or fails, it cannot ever unify (instantiate) anything.
%You can use negation to prevent certain unifications, as above, but you cannot use it to find out anything.
    % 2. Mr. Crow's tie features neither the dancing reindeer nor the yellow happy faces.
    \+ member([crow, reindeer, _], Triples),
    \+ member([crow, happy_faces, _], Triples),
 
    % 3. Mr. Speigler's tie wasn't a present from his uncle.
    \+ member([speigler, _, uncle], Triples),
 
    % 4. The tie with the yellow happy faces wasn't a gift from a sister.
    \+ member([_, happy_faces, sister], Triples),
 
    % 5. Mr Evans and Mr. Speigler own the tie with the grinning leprechauns
    %    and the tie that was a present from a father-in-law, in some order.
    ( (member([evans, leprechauns, _], Triples),
       member([speigler, _, father_in_law], Triples)) ;
 
      (member([speigler, leprechauns, _], Triples),
       member([evans, _, father_in_law], Triples)) ),
 
    % 6. Mr. Hurley received his flamboyant tie from his sister.
    member([hurley, _, sister], Triples),
 
    tell(crow, CrowTie, CrowRelative),
    tell(evans, EvansTie, EvansRelative),
    tell(hurley, HurleyTie, HurleyRelative),
    tell(speigler, SpeiglerTie, SpeiglerRelative).
 
% Succeeds if all elements of the argument list are bound and different.
% Fails if any elements are unbound or equal to some other element.
all_different([H | T]) :- member(H, T), !, fail.
all_different([_ | T]) :- all_different(T).
all_different([_]).
 
tell(X, Y, Z) :-
    write('Mr. '), write(X), write(' got the '), write(Y),
    write(' tie from his '), write(Z), write('.'), nl.
sc330_f2016/smaplesolution.pl.txt · Last modified: 2021/06/30 23:42 (external edit)