このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1335517816/654
#  [1] 授業単元: プログラミング 
#  [2] 問題文(含コード&リンク): 問題文はリンク先にあります 
#  http://ime.nu/codepad.org/3vEhNLeD 
#  /* 問題文
#  (1)行列の乗算を行う関数
#  (2)行列の(i,j)要素に値をセットする関数
#  (3)行列の(i,j)要素の値を得る関数
#  (4)行列の第p行と第q行を入れ替える関数 を作りなさい。*/

行列の乗算(L1,L2,X) :-
        転置(L2,L4),
        行列を転置された行列に掛け合わせる(L1,L4,X).

転置([[]|_],[]) :- !.
転置(L,[L1|R2]) :-
        転置(L,L2,L1),
        転置(L2,R2).

転置([],[],[]) :- !.
転置([[A|R1]|R2],[R1|R3],[A|R4]) :-
        転置(R2,R3,R4).

行列を転置された行列に掛け合わせる([],_,[]) :- !.
行列を転置行された列に掛け合わせる([_行|R1],L,[S1|R3]) :-
        行列の行を転置された行列に掛け合わせる(_行,L,S1),
        行列を転置された行列に掛け合わせる(R1,L,R3).

行列を転置された行列に掛け合わせる(_,[],[]) :- !.
行列を転置された行列に掛け合わせる(A,[B|R2],[C|R3]) :-
        行列要素の積(A,B,C),
        行列を転置された行列に掛け合わせる(A,R2,R3).

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

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

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

分数を含む加算(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.