%imaginary friends
friend('grizzly bear').
friend(moose).
friend(seal).
friend(zebra).

%the children
author(joanne).
author(lou).
author(ralph).
author(winnie).

%the activities
plot(circus).
plot('rock band').
plot(spaceship).
plot(train).

solve :-
	%book(author, protag, plot)
	Books = [book(joanne, JoFriend, JoPlot), book(lou, LoFriend, LoPlot),
          book(ralph, RaFriend, RaPlot), book(winnie, WiFriend, WiPlot)],
    
    %type-restricting
    friend(JoFriend), friend(LoFriend), friend(RaFriend), friend(WiFriend),
    plot(JoPlot), plot(LoPlot), plot(RaPlot), plot(WiPlot),
    
    %uniqueness
    all_different([JoFriend, LoFriend, RaFriend, WiFriend]),
    all_different([JoPlot, LoPlot, RaPlot, WiPlot]),

	%rule 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 in a train
	\+member(book(joanne, seal, _), Books), \+member(book(lou, seal, _),Books),
	\+member(book(_,seal, spaceship), Books), \+member(book(_,seal,train),Books),

	%rule 2: joanne's imaginary friend (who isn't the grizzly bear) went to the circus
	\+member(book(joanne, 'grizzly bear', _), Books),
	member(book(joanne, _, circus), Books),

	%rule 3: winnie's imaginary friend is a zebra
	member(book(winnie, zebra, _), Books),

	%rule 4: the grizzly bear didn't board the spaceship to the moon
	\+member(book(_,'grizzly bear', spaceship), Books),
    
    tell(joanne, JoFriend, JoPlot),
    tell(lou, LoFriend, LoPlot),
    tell(ralph, RaFriend, RaPlot),
    tell(winnie, WiFriend, WiPlot).


tell(Author, Protag, Plot) :- write(Author), write(' wrote about the '), write(Protag),
    write(' exploring the '), write(Plot), 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([_]).
