%% Facts

contestants(joanne).
contestants(lou).
contestants(ralph).
contestants(winnie).

animal(grizzly_bear).
animal(moose).
animal(seal).
animal(zebra).

adventure(circus).
adventure(rock_band).
adventure(spaceship).
adventure(train).
    
    
solve_adventure :- 
    animal(JoanneAnimal), animal(LouAnimal), animal(RalphAnimal), animal(WinnieAnimal),
	all_different([JoanneAnimal, LouAnimal, RalphAnimal, WinnieAnimal]), 

    adventure(JoanneAdventure), adventure(LouAdventure), adventure(RalphAdventure), 
    adventure(WinnieAdventure),
    all_different([JoanneAdventure, LouAdventure, RalphAdventure, WinnieAdventure]),

    Imaginary_friend = [ imaginary_friend(joanne, JoanneAnimal, JoanneAdventure),
				         imaginary_friend(lou, LouAnimal, LouAdventure),
				         imaginary_friend(ralph, RalphAnimal, RalphAdventure),
				         imaginary_friend(winnie, WinnieAnimal, WinnieAdventure) ],
    
    % 1. The seal didn’t ride the spaceship or the magic trian
    % 2. The seal is neither the creation of lou or Joanne
    
    \+ member(imaginary_friend(_, seal, spaceship), Imaginary_friend),
    \+ member(imaginary_friend(lou, seal, _), Imaginary_friend),
    \+ member(imaginary_friend(_, seal, train), Imaginary_friend),
    \+ member(imaginary_friend(joanne, seal, _), Imaginary_friend),
    
 
    % 3. Joanne’s imaginary friend (who isn't the grizzly bear)went to the circus
       member(imaginary_friend(joanne, _, circus), Imaginary_friend),
    \+ member(imaginary_friend(joanne, grizzly_bear, _), Imaginary_friend),
 
    % 4. Winnie’s imaginary friend is a zebra 
       member(imaginary_friend(winnie, zebra, _), Imaginary_friend),

    % 5. The grizzly bear didin’t board the spaceship to the moon
    \+ member(imaginary_friend(_, grizzly_bear, spaceship), Imaginary_friend),

    
    tell(joanne, JoanneAnimal, JoanneAdventure),
    tell(lou, LouAnimal, LouAdventure),
    tell(ralph, RalphAnimal, RalphAdventure),
    tell(winnie, WinnieAnimal, WinnieAdventure).
    
tell(Contestant, Animal, Adventure) :- write(Contestant), write(' and '), write(Animal),
write(' went on '), write(Adventure), write(' adventure '), 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([_]).