
%%%%% solution to exercise 4.4 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

:- lib(ic).


einstein :-
	% encode persons as numbers
	Marc = 1,
	Joey = 2,
	Sandra = 3,
	Ellen = 4,

	% each person (number) has exactly one drink and sport
	Drink = [Tea, Water, Coffee, Beer],
	Sport = [Hiking, Volley, Basket, Tennis],
	Drink #:: [1..4],
	Sport #:: [1..4],
	alldifferent(Drink),
	alldifferent(Sport),

	% clues
	Joey #= Beer,						% 1)
	Marc #\= Tea, Marc #\= Volley,				% 2)
	#=(Sandra,Hiking,T1), #=(Joey,Basket,T2), T1 + T2 #= 1,	% 3)
	Coffee #= Basket,					% 4)
	Sandra #= Tea => Ellen #= Basket,			% 5)
	Water #= Tennis or Water #= Volley,			% 6)

	% instantiate variables
	term_variables([Drink,Sport],Vars),
	labeling(Vars),

	% output
	PersonNames = [Marc-marc, Joey-joey, Sandra-sandra, Ellen-ellen],
	DrinkNames = [Tea-tea, Water-water, Coffee-coffee, Beer-beer],
	SportNames = [Hiking-hiking, Volley-volley, Basket-basket, Tennis-tennis],
	(foreach((Number-Name),PersonNames),
	 param(DrinkNames,SportNames) do
		memberchk((Number-Drink),DrinkNames),
		memberchk((Number-Sport),SportNames),
		printf("%w: drinks %w, does %w%n",[Name, Drink, Sport])
	).

