「7日間で7つの言語」の本を読んでいて、Prologの章に到達しました。学習演習として、私はいくつかのテキストロジックパズルを解こうとしています。パズルは次のようになります。
5人の姉妹は全員、誕生日が異なる月に、それぞれが異なる曜日に誕生日を迎えます。以下の手がかりを使用して、各姉妹の誕生日が当たる月と曜日を決定します。
- ポーラは3月に生まれましたが、土曜日には生まれませんでした。アビゲイルの誕生日は金曜日でも水曜日でもありませんでした。
- 月曜日に誕生日を迎える少女は、ブレンダとメアリーよりも年の初めに生まれました。
- タラは2月に生まれておらず、彼女の誕生日は週末でした。
- メアリーは12月に生まれたわけでも、平日の誕生日でもありませんでした。6月に誕生日を迎えた少女は日曜日に生まれました。
- タラは、誕生日が金曜日ではなかったブレンダの前に生まれました。メアリーは7月に生まれませんでした。
私の現在の実装は、おそらく経験豊富なPrologプログラマーにとっては冗談のように見えます。コードは以下に貼り付けられています。
質問を解決する方法と、コードを明確かつ高密度にする方法について、いくつかの意見をお聞かせください。
すなわち:
- 日は一意である必要があるという制限を入力しないようにするにはどうすればよいですか。
- 月は一意である必要があるという制限を入力しないようにするにはどうすればよいですか。
- 誕生日の順序に関する制限を追加します。
is_day(Day) :-
member(Day, [sunday, monday, wednesday, friday, saturday]).
is_month(Month) :-
member(Month, [february, march, june, july, december]).
solve(S) :-
S = [[Name1, Month1, Day1],
[Name2, Month2, Day2],
[Name3, Month3, Day3],
[Name4, Month4, Day4],
[Name5, Month5, Day5]],
% Five girls; Abigail, Brenda, Mary, Paula, Tara
Name1 = abigail,
Name2 = brenda,
Name3 = mary,
Name4 = paula,
Name5 = tara,
is_day(Day1), is_day(Day2), is_day(Day3), is_day(Day4), is_day(Day5),
Day1 \== Day2, Day1 \== Day3, Day1 \== Day4, Day1 \== Day5,
Day2 \== Day1, Day2 \== Day3, Day2 \== Day4, Day2 \== Day5,
Day3 \== Day1, Day3 \== Day2, Day3 \== Day4, Day3 \== Day5,
Day4 \== Day1, Day4 \== Day2, Day4 \== Day3, Day4 \== Day5,
is_month(Month1), is_month(Month2), is_month(Month3), is_month(Month4), is_month(Month5),
Month1 \== Month2, Month1 \== Month3, Month1 \== Month4, Month1 \== Month5,
Month2 \== Month1, Month2 \== Month3, Month2 \== Month4, Month2 \== Month5,
Month3 \== Month1, Month3 \== Month2, Month3 \== Month4, Month3 \== Month5,
Month4 \== Month1, Month4 \== Month2, Month4 \== Month3, Month4 \== Month5,
% Paula was born in March but not on Saturday.
member([paula, march, _], S),
Day4 \== sunday,
% Abigail's birthday was not on Friday or Wednesday.
Day1 \== friday,
Day1 \== wednesday,
% The girl whose birthday is on Monday was born
% earlier in the year than Brenda and Mary.
% Tara wasn't born in February, and
% her birthday was on the weekend.
Month5 \== february,
Day5 \== monday, Day5 \== wednesday, Day5 \== friday,
% Mary was not born in December nor was her
% birthday on a weekday.
Month3 \== december,
Day3 \== monday, Day3 \== wednesday, Day3 \== friday,
% The girl whose birthday was in June was
% born on Sunday.
member([_, june, sunday], S),
% Tara was born before Brenda, whose birthday
% wasn't on Friday.
Day2 \== friday,
% Mary wasn't born in July.
Month3 \== july.
更新chacからの回答に基づいて、パズルを解くことができました。同じレシピに従って、私たち(仕事中のプログラミング言語コンピテンシーグループ)も2番目のパズルを解くことができました。完全な実装と出力例をGitHubに要点として投稿しました。