このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1357748713/874
#  ../test/read.cgi/tech/1357748713/775 
#  http://pc11.2ch.net/test/read.cgi/tech/1202135539/607 
#  [1] 授業単元:プログラミング 
#  [2] 問題文 :キーボードから西暦と月を入力するとカレンダーを 
#        表示するプログラムを作成せよ 
#  

キーボードから西暦と月を入力するとカレンダーを表示する :-
        キーボードから西暦と月を入力すると(_西暦,_月),
        カレンダーを表示する(_西暦,_月).

キーボードから西暦と月を入力すると(_西暦,_月) :-
        整数を得る(西暦,true,_西暦),
        整数を得る(月,between(1,12,_月),_月).

カレンダーを表示する(_西暦,_月) :-
        カレンダーを(_西暦,_月,_カレンダー),
        表示する(_西暦,_月,_カレンダー).

カレンダーを(_西暦,_月,_カレンダー) :-
        月末日(_西暦,_月,_月末日),
        'Zellerの公式を用いて曜日を得る'(_年,_月,1,_曜日を表す値,_曜日),
        findall(D,between(1,_月末日,D),L1),
        カレンダーの先頭に0を詰める(L1,L2),
        '7個組に分解'(L2,_カレンダー).        

月末日(_西暦,2,29) :-
        うるう年(_西暦),!.
月末日(_,2,28) :- !.
月末日(_,_月,31) :-
        member(_月,[1,3,5,7,8,10,12]),!.
月末日(_,_月,30) :-
        member(_月,[4,6,9,11]),!.

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

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

'Zellerの公式で使う曜日を表す値'(0,日曜).
'Zellerの公式で使う曜日を表す値'(1,月曜).
'Zellerの公式で使う曜日を表す値'(2,火曜).
'Zellerの公式で使う曜日を表す値'(3,水曜).
'Zellerの公式で使う曜日を表す値'(4,木曜).
'Zellerの公式で使う曜日を表す値'(5,金曜).
'Zellerの公式で使う曜日を表す値'(6,土曜).

all([],_).
all([V|R],V) :-
       all(R,V).

カレンダーの先頭に0を詰める(L1,L2) :-
        length(L0,_曜日を表す値),
        append(L0,L1,L2),
        all(L0,0),!.

'7個組に分解'([],[]) :- !.
'7個組に分解'([_1,_2,_3,_4,_5,_6,_7|R1],[[_1,_2,_3,_4,_5,_6,_7]|R2]) :-
        '7個組に分解'(R1,R2),!.
'7個組に分解'(L,[L]).

表示する(_西暦,_月,_カレンダー) :-
        writef('\n%8r年 %t月\n\n',[_西暦,_月]),
        member(L,_カレンダー),
        一行表示する(L),
        fail.
表示する(_西暦,_月,_カレンダー) :-
        write('\n').

一行表示する([]) :-
        write('\n').
一行表示する([0|R]) :-
        writef('%3r',[' ']),
        一行表示する(R),!.
一行表示する([N|R]) :-
        writef('%3r',[N]),
        一行表示する(R).