このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1291471791/778
#  1] 授業単元:Cプロ実習  
#  [2] 問題文(含コード&リンク): 
#  2つの4×4行列を2次元配列に格納し、それらの積を求めるプログラムを作成せよ。 
#  以下の関数を必ず利用すること。 
#  関数の引数の型では1次元目が空白になっているが、 
#   main関数では4×4の通常の2次元配列を用いればよい。 
#   

'2つの4×4行列を2次元配列に格納し、それらの積を求める' :-
        行列一の入力(LL1),
        行列二の入力(LL2),
        行列の積(LL1,LL2,LL3),
        結果の表示(LL1,LL2,LL3).

行列一の入力(LL1) :-
        length(LL1,4),
        findall(L1,
                    append(L0,[L1|_],LL1),
                    length([_|L0],Nth),
                    write_formatted('第二行列の%t行目をカンマ区切りで4列入力してください\n',[Nth]),
                    カンマ区切りによる四項入力(L1)),
                LL1).

行列二の入力(LL2) :-
        length(LL2,4),
        findall(L2,
                    append(L0,[L2|_],LL2),
                    length([_|L0],Nth),
                    write_formatted('第二行列の%t行目をカンマ区切りで4列入力してください\n',[Nth]),
                    カンマ区切りによる四項入力(L2)),
                LL2).

カンマ区切りによる四項入力(L) :-
        get_line(Line),
        カンマ区切りによる四項入力診断(Line,L),!.
カンマ区切りによる四項入力(L) :- カンマ区切りによる四項入力(L).

カンマ区切りによる四項入力診断(Line,L) :-
        split(Line,[','],L),
        length(L,4),
        すべて数値(L),!.
カンマ区切りによる四項入力診断(Line,L) :-
        write('入力された%tからは四項を取り出すことができません。再入力をお願いします。\n'),
        fail.

すべて数値([]) :- !.
すべて数値([V|R]) :- number(V),すべて数値(R).

行列の積(L1,L2,X) :-
        行列の転置(L2,L4),
        行列の積_1(L1,L4,X).

行列の積_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),
        S is S1 + S2.

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

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

結果の表示(LL1,LL2,LL3) :-
        行列の表示(LL1),
        write('        ×\n'),
        行列の表示(LL2),
        write('        =\n'),
        行列の表示(LL3).

行列の表示(LL) :-
        write('['),
        行列の表示の一(LL).

行列の表示の一([]) :- write(']\n'),!. 
行列の表示の一([L]) :- write_formatted(' %t]\n',[L]),!. 
行列の表示の一([L|R]) :-
        write_formatted(' %t\n',[L]),
        行列の表示の一(R),!