% Extra Credit.

% Facts
day(sunday).
day(monday).
day(wednesday).
day(friday).
day(saturday).

month(february).
month(march).
month(june).
month(july).
month(december).

before(february, march).
before(march, june).
before(june, july).
before(july, december).

before(sunday, monday).
before(monday, wednesday).
before(wednesday, friday).
before(friday, saturday).

before(december, _) :- !, fail.
before(saturday, _) :- !, fail.
before(First, Last) :- First = Last, !, fail.
before(First, Last) :- before(First, Middle), before(Middle, Last).

sister(abigail).
sister(brenda).
sister(mary).
sister(paula).
sister(tara).

solve :-
      day(AbigailDay), day(BrendaDay), day(MaryDay), day(PaulaDay), day(TaraDay),
      all_different([AbigailDay, BrendaDay, MaryDay, PaulaDay, TaraDay]),

      month(AbigailMonth), month(BrendaMonth), month(MaryMonth), month(PaulaMonth), month(TaraMonth),
      all_different([AbigailMonth, BrendaMonth, MaryMonth, PaulaMonth, TaraMonth]),

      Birthdays = [ birthday(abigail, AbigailDay, AbigailMonth),
      birthday(brenda, BrendaDay, BrendaMonth),
      birthday(mary, MaryDay, MaryMonth),
      birthday(paula, PaulaDay, PaulaMonth),
      birthday(tara, TaraDay, TaraMonth)],

      % 1 Paula was born in March but not on Saturday. Abigail's birthday was not on Friday or Wednesday.
      \+ member(birthday(paula, saturday, _), Birthdays),
      member(birthday(paula, _, march), Birthdays),
      \+ member(birthday(abigail, friday, _), Birthdays),
      \+ member(birthday(abigail, wednesday, _), Birthdays),

      % 2 The girl whose birthday is on Monday was born earlier in the year than Brenda and Mary.
      ((member(birthday(abigail, monday, _),Birthdays), before(AbigailMonth, BrendaMonth), before(AbigailMonth, MaryMonth));
    	(member(birthday(paula, monday, _),Birthdays), before(PaulaMonth, BrendaMonth), before(PaulaMonth, MaryMonth));
      (member(birthday(mary, monday, _),Birthdays), before(PaulaMonth, BrendaMonth), before(PaulaMonth, MaryMonth));
    	(member(birthday(tara, monday, _),Birthdays), before(TaraMonth, BrendaMonth), before(TaraMonth, MaryMonth))),

      % 3 Tara wasn't born in February and her birthday was on the weekend.
      \+ member(birthday(tara, _, february), Birthdays),
      (( member(birthday(tara, sunday, _), Birthdays)) ; ( member(birthday(tara, saturday, _), 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, sunday, _), Birthdays) ) ; ( member(birthday(mary, saturday, _), Birthdays))),
      member(birthday(_, sunday, june), Birthdays),

      % 5 Tara was born before Brenda, whose birthday wasn't on Friday. Mary wasn't born in July.

      \+ member(birthday(brenda, friday, _), Birthdays),
      \+ member(birthday(mary, _, july), Birthdays),
      before(TaraMonth, BrendaMonth),

      tell(abigail, AbigailDay, AbigailMonth),
      tell(brenda, BrendaDay, BrendaMonth),
      tell(mary, MaryDay, MaryMonth),
      tell(paula, PaulaDay, PaulaMonth),
      tell(tara, TaraDay, TaraMonth).


  tell(Sister, Day, Month) :- write(Sister), write(' was born on a '), write(Day),
      write(' in '), write(Month), 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([_]).
