## Solving Logic Puzzles in Prolog: Puzzle 3 of 3

In this post we solve another small logic puzzle in Prolog, similar to the previous two logic puzzles (these are available here and here).

## The puzzle

There are four researchers: Ainsley, Madeline, Sophie and Theodore. The goal is to find out their sports competition discipline, birth year and research interests (while knowing that each of the mentioned attributes is different amongst them). In order so solve the puzzle, a couple of hints is provided from which the solution can be derived:

- The competition for Theodore or Ainsley is javelin.
- The researcher interested in hurricane research has relay as sports subject.
- Sophie is not the researcher who has relay as sports subject.
- Either the researcher who has longjump as sports subject or Theodore was born in 1933 – the other one was born in 1921.
- The researcher with relay as sports subject was born before Theodore.
- The researcher interested in wildfires was born after the researcher doing longjumps for sports.
- Neither Sophie nor Ainsley are researching wildfires.
- The researcher interested in earthquakes has either hurdle or javelin as sports interest.
- The researcher interested in earthquakes was born in 1933.
- Madeline was not born in 1921.

## Solving the puzzle in Prolog

In our Prolog implementation we ask for a solution that a) ensures that all sports subjects, research interests and birth years exist once and b) fulfills the rules mentioned above:

% #################################################################### % Logic puzzle solver. % % Read definition to prolog: % ['puzzle.pl']. % % 2) Ask for solutions: % solve(Ainsley, Madeline, Sophie, Theodore). % % Rainhard Findling % 10/2015 % #################################################################### all_members([H],L2) :- member(H,L2). all_members([H|T],L2) :- member(H,L2), all_members(T, L2). and([H]) :- H. and([H|T]) :- H, and(T). or([H]) :- H,!. or([H|_]) :- H,!. or([_|T]) :- or(T). solve(Ainsley, Madeline, Sophie, Theodore) :- All = [Ainsley, Madeline, Sophie, Theodore], Ainsley = [Ainsley_Year, Ainsley_Competition, Ainsley_Disaster], Madeline = [Madeline_Year, Madeline_Competition, Madeline_Disaster], Sophie = [Sophie_Year, Sophie_Competition, Sophie_Disaster], Theodore = [Theodore_Year, Theodore_Competition, Theodore_Disaster], % we know what all variable must be all_members([1920, 1921, 1933, 1973], [Ainsley_Year, Madeline_Year, Sophie_Year, Theodore_Year]), all_members([hurdle, relay, javelin, longjump], [Ainsley_Competition, Madeline_Competition, Sophie_Competition, Theodore_Competition]), all_members([earthquakes, hurricanes, tornados, wildfires], [Ainsley_Disaster, Madeline_Disaster, Sophie_Disaster, Theodore_Disaster]), % c1 or([Ainsley_Competition = javelin, Theodore_Competition = javelin]), % c2 member([_, relay, hurricanes], All), % c3 not(Sophie_Competition = relay), % c4 member([C4_Year, longjump, _], All), or([and([Theodore_Year = 1921, C4_Year = 1933]), and([Theodore_Year = 1933, C4_Year = 1921])]), % c5 member([C5_Year, relay, _], All), Theodore_Year > C5_Year, % c6 member([C6_1_Year, longjump, _], All), member([C6_2_Year, _, wildfires], All), C6_1_Year < C6_2_Year, % c7 not(Sophie_Disaster = wildfires), not(Ainsley_Disaster = wildfires), % c8 member([_, C8_competition, earthquakes], All), not(C8_competition = hurdle), not(C8_competition = javelin), % c9 member([1933, _, earthquakes], All), % c10 not(Madeline_Year = 1921).

Using this implementation, if we ask for a solution, the single possible solution is presented:

['puzzle.prolog']. % puzzle.prolog compiled 0.00 sec, 13 clauses true. ?- solve(Ainsley, Madeline, Sophie, Theodore). Ainsley = [1920, relay, hurricanes], Madeline = [1973, hurdle, wildfires], Sophie = [1933, longjump, earthquakes], Theodore = [1921, javelin, tornados] ;