%Facts
author(joanne).
author(lou).
author(ralph).
author(winnie).
friend(grizzly_bear).
friend(moose).
friend(seal).
friend(zebra).
adventure(circus).
adventure(rock_band).
adventure(spaceship).
adventure(train).

solve :-
	friend(JoanneFriend), friend(LouFriend), friend(RalphFriend), friend(WinnieFriend),
	all_different([JoanneFriend, LouFriend, RalphFriend, WinnieFriend]),
	adventure(JoanneAdventure), adventure(LouAdventure),
	adventure(RalphAdventure), adventure(WinnieAdventure),
	all_different([JoanneAdventure, LouAdventure, RalphAdventure, WinnieAdventure]),
	

	Stories = [ story(joanne, JoanneFriend, JoanneAdventure),
				story(lou, LouFriend, LouAdventure),
				story(ralph, RalphFriend, RalphAdventure),
				story(winnie, WinnieFriend, WinnieAdventure)],
							
% 1. The seal neither rode to the moon in a spaceship nor took a trip on a magic train. Seal is not a creation of joanne or lou.
\+ member(story(joanne, seal,_), Stories),
\+ member(story(lou, seal, _), Stories),
\+ member(story(_, seal,spaceship), Stories),
\+ member(story(_, seal,train), Stories),


% 2. Joanne's imaginary friend who isnt the grizzly bear went to thr circus.
\+ 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.
\+ member(story(_, grizzly_bear, spaceship), Stories),

tell(joanne, JoanneFriend, JoanneAdventure),
tell(lou, LouFriend, LouAdventure),
tell(ralph, RalphFriend, RalphAdventure),
tell(winnie, WinnieFriend, WinnieAdventure).

tell(Writer, ImaginaryFriend, Adventure) :- write('The author is '), write(Writer), write(' and their imaginary friend is '),
write(ImaginaryFriend), write(' and the adventure it went on was on a '), 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([_]).
