このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1339338438/190
#  [1] プログラミング入門 
#  [2]  
#   
#  課題1 a[5] ={1, 3, 5, 2, -1} であるとき最も大きい値と小さい値を表示するプログラムを作成する。 
#   
#  課題2 a[2][2] = {{1,2},{3,4}},  b[2][1]={{1},{3}} のとき行列aとbを掛け算した結果a*b を出力する。(難しいかな?) 
#   
#  [環境] 
#  [3.1] OS:windows  
#  [3.2] コンパイラ名とバージョン:Microsoft Visual studio 2010  
#  [3.3] 言語:C++  
#  [4] 期限: 6月19日 21:00まで  
#   

'課題2 a[2][2] = {{1,2},{3,4}},  b[2][1]={{1},{3}} のとき行列aとbを掛け算した結果a*bを出力する' :-
        行列の掛け算([[1,2],[3,4]],[[1],[3]],_行列aとbを掛け算した結果).

行列の掛け算(_a,_b,_行列aとbを掛け算した結果) :-
        転置(_b,_転置したb),
        行列の掛け算_1(_a,_転置したb,_行列aとbを掛け算した結果),
        '行列a*bを出力する'(_行列aとbを掛け算した結果).

行列の掛け算_1([],_,[]) :- !.
行列の掛け算_1([A|R1],L,[S1|R3]) :-
        行列の掛け算_2(A,L,S1),
        行列の掛け算_1(R1,L,R3) .

行列の掛け算_2(_,[],[]) :- !.
行列の掛け算_2(A,[B|R2],[C|R3]) :-
        行列の掛け算_3(A,B,C),
        行列の掛け算_2(A,R2,R3).

行列の掛け算_3([],[],0).
行列の掛け算_3([A|R1],[B|R2],S) :-
        S1 is A * B,
        行列の掛け算_3(R1,R2,S2),
        分数を含む加算(S1,S2,S) .

行列の掛け算_3([],[],0) :- !.
行列の掛け算_3([A1 / A2|R1],[B1 / B2|R2],S) :-
        S01 is A1 * B1,
        S02 is A2 * B2,
        約分(S01 / S02,S1),
        行列の掛け算_3(R1,R2,S2),
        分数を含む加算(S1,S2,S),!.
行列の掛け算_3([A1 / A2|R1],[B|R2],S) :-
        S0 is A1 * B,
        約分(S0 / A2,S1),
        行列の掛け算_3(R1,R2,S2),
        分数を含む加算(S1,S2,S),!.
行列の掛け算_3([A|R1],[B1 / B2|R2],S) :-
        S0 is A * B1,
        約分(S0 / B2,S1),
        行列の掛け算_3(R1,R2,S2),
        分数を含む加算(S1,S2,S),!.
行列の掛け算_3([A|R1],[B|R2],S) :-
        S1 is A * B,
        行列の掛け算_3(R1,R2,S2),
        分数を含む加算(S1,S2,S) .

分数を含む加算(A1 / A2,B1 / B2,C) :-
        S1 is A1 * B2 + A2 * B1,
        S2 is A2 * B2,
        約分(S1 / S2,C),!.
分数を含む加算(A1 / A2,B,C) :-
        S1 is A1 + A2 * B,
        約分(S1 / A2,C),!.
分数を含む加算(A,B1 / B2,C) :-
        S1 is B1 + B2 * A,
        約分(S1 / B2,C),!.
分数を含む加算(A,B,C) :-
        C is A + B .

約分(B / A,X) :-
        最大公約数(B,A,C),
        _分子 is B // C,
        _分母 is A // C,
        約分の二(_分子,_分母,X),!.

約分の二(_分子,1,_分子) :- !.
約分の二(_分子,1.0,_分子) :- !.
約分の二(_分子,_分母,_分子 / _分母).

最大公約数(M,N,X) :-
        最大公約数をユークリッドの互除法で求める(M,N,X),!.

最大公約数をユークリッドの互除法で求める(M,N,N) :-
        0 is M mod N,!.
最大公約数をユークリッドの互除法で求める(M,N,X) :-
        Mod is M mod N,
        最大公約数をユークリッドの互除法で求める(N,Mod,X).

'行列a*bを出力する'(_行列aとbを掛け算した結果) :-
        write('['),
        append(_,[_行|R],_行列aとbを掛け算した結果),
        writef(' %t\n',[_行]),
        R = [_最終行],
        writef(' %t]\n',[_最終行]).