% Facts
friend(grizzly_bear).
friend(moose).
friend(seal).
friend(zebra).

kid(joanne).
kid(lou).
kid(ralph).
kid(winnie).

adventure(circus).
adventure(rock_band).
adventure(spaceship).
adventure(train).

solve :-
    adventure(JoanneAdventure), adventure(LouAdventure), adventure(RalphAdventure),
    adventure(WinnieAdventure),
    all_different([JoanneAdventure, LouAdventure, RalphAdventure, WinnieAdventure]),

    friend(JoanneFriend), friend(LouFriend), friend(RalphFriend), friend(WinnieFriend),
    all_different([JoanneFriend, LouFriend, RalphFriend, WinnieFriend]),



    Stories = [ story(joanne, JoanneAdventure, JoanneFriend),
              story(lou, LouAdventure, LouFriend),
              story(ralph, RalphAdventure, RalphFriend),
              story(winnie, WinnieAdventure, WinnieFriend) ],

    % 1.The seal (who isn't the creation of either Joanne or Lou) neither rode to the moon in a spaceship nor took a trip around the world on a magic train.
    \+ member(story(joanne,_,seal), Stories),
    \+ member(story(lou,_,seal), Stories),
    \+ member(story(_,spaceship,seal), Stories),
    \+ member(story(_,train,seal),Stories),

    % 2.Joanne's imaginary friend (who isn't the grizzly bear) went to the circuis
    \+ member(story(joanne,_,grizzly_bear),Stories),
       member(story(joanne,circus,_),Stories),

    % 3. Winnie's imaginary friend is a zebra.
       member(story(winnie,_,zebra), Stories),

    % 4. The grizzly bear didn't board the spaceship to the moon.
     \+ member(story(_,spaceship,grizzly_bear),Stories),


    tell(joanne, JoanneAdventure, JoanneFriend),
    tell(lou, LouAdventure, LouFriend),
    tell(ralph, RalphAdventure, RalphFriend),
    tell(winnie, WinnieAdventure, WinnieFriend).

tell(Kid, Adventure, Friend) :-  write(Kid), write('\'s adventure was the '), write(Adventure),
    write(' with '), write(Friend), write('.'), nl.

% If the head of the list is in the tail, fail.
all_different([Head|Tail]) :- member(Head, Tail), !, fail.
% Otherwise, check the tail of the list.
all_different([_|Tail]) :- all_different(Tail).
% If there's only one thing in the list, it's fine.
all_different([_]).
