% Solution to the Extra Credit Birthday logic puzzle.

% Facts
sister(abigail).
sister(brenda).
sister(mary).
sister(paula).
sister(tara).

month(february).
month(march).
month(june).
month(july).
month(december).

day(sunday).
day(monday).
day(wednesday).
day(friday).
day(saturday).

solve :-
    month(AbigailMonth), month(BrendaMonth), month(MaryMonth), month(PaulaMonth),
    month(TaraMonth),
    all_different([AbigailMonth, BrendaMonth, MaryMonth, PaulaMonth, TaraMonth]),

    day(AbigailDay), day(BrendaDay), day(MaryDay), day(PaulaDay), day(TaraDay),
    all_different([AbigailDay, BrendaDay, MaryDay, PaulaDay, TaraDay]),



    Birthdays = [ birthday(abigail, AbigailMonth, AbigailDay),
                  birthday(brenda, BrendaMonth, BrendaDay),
                  birthday(mary, MaryMonth, MaryDay),
                  birthday(paula, PaulaMonth, PaulaDay),
                  birthday(tara, TaraMonth, TaraDay) ],


    % 1. Paula was born in March but not on Saturday. Abigail's birthday was not on Friday or Wednesday
    member(birthday(paula, march, _), Birthdays),
    \+ member(birthday(paula, _, saturday), Birthdays),
    \+ member(birthday(abigail, _, friday), Birthdays),
    \+ member(birthday(abigail, _, wednesday), Birthdays),

    % 2. Girl whose birthday is on Monday was born earlier in the year than Brenda and Mary
    \+ member(birthday(brenda, february, _), Birthdays),
    \+ member(birthday(mary, february, _), Birthdays),
    \+ member(birthday(_, july, monday), Birthdays),
    \+ member(birthday(_, december, monday), Birthdays),

    % 3. Tara wasn't born in February and her birthday was on the weekend
    \+ member(birthday(tara, february, _), Birthdays),
    ( member(birthday(tara, _, saturday), Birthdays) ;
      member(birthday(tara, _, sunday), Birthdays) ),

    % 4. Mary was not born in December nor was her birthday on a weekday. The girl whose birthday
    %    was in June was born on Sunday.
    \+ member(birthday(mary, december, _), Birthdays),
    ( member(birthday(mary, _, saturday), Birthdays) ;
      member(birthday(mary, _, sunday), Birthdays) ),
    member(birthday(_, june, sunday), Birthdays),

    % 5. Tara was born before Brenda, whose birthday wasn't on a Friday. Mary wasn't born in July.
    \+ member(birthday(tara, december, _), Birthdays),
    \+ member(birthday(brenda, february, _), Birthdays),
    \+ member(birthday(brenda, _, friday), Birthdays),
    \+ member(birthday(mary, july, _), Birthdays),

    
    tell(abigail, AbigailMonth, AbigailDay),
    tell(brenda, BrendaMonth, BrendaDay),
    tell(mary, MaryMonth, MaryDay),
    tell(paula, PaulaMonth, PaulaDay),
    tell(tara, TaraMonth, TaraDay).

tell(Sister, Month, Day) :- write(Sister), write(' was born in '), write(Month), write(' on a '),
    write(Day), 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([_]).

