%entities
child(joanne).
child(lou).
child(ralph).
child(winnie).

friend(grizzlybear).
friend(moose).
friend(seal).
friend(zebra).

adventure(circus).
adventure(rockband).
adventure(spaceship).
adventure(train).


solve :-
	 
	friend(JoannaFriend), friend(LouFriend), friend(RalphFriend), friend(WinnieFriend),
	all_different([JoannaFriend, LouFriend, RalphFriend, WinnieFriend]),

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

	Stories = [ story(joanna, JoannaFriend, JoannaAdventure),
		story(lou, LouFriend, LouAdventure),
		story(ralph, RalphFriend, RalphAdventure),
		story(winnie, WinnieFriend, WinnieAdventure) ],
	
	\+ member(story(joanna, seal, _), Stories),
	\+ member(story(lou, seal, _), Stories),
	\+ member(story(_, seal, spaceship), Stories),
	\+ member(story(_, seal, train), Stories),

	\+ member(story(joanna, grizzlybear,_), Stories),
	member(story(joanna, _, circus), Stories),

	member(story(winnie, zebra, _), Stories),

	\+ member(story(_, grizzlybear, spaceship), Stories),

	tell(joanna, JoannaFriend, JoannaAdventure),
	tell(lou, LouFriend, LouAdventure),
	tell(ralph, RalphFriend, RalphAdventure), 
	tell(winnie, WinnieFriend, WinnieAdventure).

tell(Who, With, Where) :- write(Who), write(' and '), write(With), write(' went to a '), write(Where), 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([_]).