このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1291471791/303
#  [1] 授業単元:プログラミング  
#   
#  [2] 問題文(含コード&リンク):  
#  以下のようなカレンダープログラム mycal を作成せよ。 
#  ◦ 引数なしで実行されると、今月のカレンダーを出力する 
#  ◦ 引数1個で実行されると、その引数を月とみなし、その年のその月のカレンダーを出力する 
#  ◦ 引数2個で実行されると、第一引数を月、第二引数を年とみなしてカレンダーを出力する。 
#   
#  

私のカレンダー :-
        今日(_年,_月,_),
        日曜から開始するカレンダー(_年,_月).

私のカレンダー(_月) :-
        今日(_年,_,_),
        日曜から開始するカレンダー(_年,_月).

私のカレンダー(_月,_年) :-
        日曜から開始するカレンダー(_年,_月).

日曜から開始するカレンダー(_年,_月) :-
        その月の日数(_年,_月,_日数),
        'Zellerの公式を用いて曜日を得る'(_年,_月,1,_曜日を表す値,_曜日),
        length(L,35),
        日付を埋める(1,_日数,L),
        ならびの回転(右方向,_曜日を表す値,L,L1),
        日曜から開始するカレンダーを表示する(_年,_月,L1).

'Zellerの公式を用いて曜日を得る'(_年,1,_日,_曜日を表す値,_曜日) :-
        前年(_年,_前年),
        'Zellerの公式を用いて曜日を得る'(_前年,13,_日,_曜日を表す値,_曜日),!.
'Zellerの公式を用いて曜日を得る'(_年,2,_日,_曜日を表す値,_曜日) :-
        前年(_年,_前年),
        'Zellerの公式を用いて曜日を得る'(_前年,14,_日,_曜日を表す値,_曜日),!.
'Zellerの公式を用いて曜日を得る'(_年,_月,_日,_曜日を表す値,_曜日) :-
        _曜日を表す値 is (_年 + _年 // 4 - _年 // 100 + _年 // 400 + ((13 * _月 + 8) // 5 + _日)) mod 7,
        曜日を表す値(_曜日を表す値,_曜日),!.

曜日を表す値(0,日曜).
曜日を表す値(1,月曜).
曜日を表す値(2,火曜).
曜日を表す値(3,水曜).
曜日を表す値(4,木曜).
曜日を表す値(5,金曜).
曜日を表す値(6,土曜).

その月の日数(_年,_月,31) :-
        append(_,[_月|_],[1,3,5,7,8,10,12]),!.
その月の日数(_年,_月,30) :-
        append(_,[_月|_],[4,6,9,11]),!.
その月の日数(_年,2,29) :-
        うるう年(_年),!.
その月の日数(_年,2,28) :-
        \+(うるう年),!.

うるう年(_年) :-
        0 is _年 mod 400,!.
うるう年(_年) :-
        0 is _年 mod 100,
        !,fail.
うるう年(_年) :-
        0 is _年 mod 4,!.
うるう年(_年) :-
        \+(0 is _年 mod 4),
        fail.

前年(_年,_前年) :-
        _前年 is _年 - 1.

日付を埋める(_日数,_日数,[_日数|_]) :- !.
日付を埋める(N,_日数,[N|R]) :-
        N2 is N + 1,
        日付を埋める(N2,_日数,R).

日曜から開始するカレンダーを表示する(_年,_月,L) :-
        write_formatted('        %t 年 %t 月\n\n 日  月  火  水  木  金  土\n',[_年,_月]),
        カレンダーの週間表示(L).

カレンダーの週間表示([]) :- !.
カレンダーの週間表示([_1,_2,_3,_4,_5,_6,_7|R]) :-
        日毎の表示([_1,_2,_3,_4,_5,_6,_7]),
        カレンダーの週間表示(R).

日毎の表示([]) :- !.
日毎の表示([D|R]) :-
        integer(D),
        write_formatted(' %2d ',[D]),
        日毎の表示(R).
日毎の表示([D|R]) :-
        var(D),
        write('    '),
        日毎の表示(R).

今日(_年整数,_月整数,_日整数) :-
        Time is time,
        localtime(Time,_年整数,_月整数,_日整数,_曜日番号,_年初からの経日,_時,_分,_秒).

ならびの回転(右方向,N,L1,L2) :-
        length(R,N),
        append(L0,R,L1),
        append(R,L0,L2),!.