【出典】https://twitter.com/TakaoOzaki/status/306175708726706177
【要約】述語 単位行列/2 を“うまく”定義する。
単位行列 E_n := [ δ_i,j ]_n×n からの連想として「添字」を用いる実装をすると、双方向性を保つのがめんどくさい
(組み込み述語 var による条件分岐がどうしても必要になる気がする)。
【出典】https://twitter.com/TakaoOzaki/status/306175708726706177
【要約】述語 単位行列/2 を“うまく”定義する。
単位行列 E_n := [ δ_i,j ]_n×n からの連想として「添字」を用いる実装をすると、双方向性を保つのがめんどくさい
(組み込み述語 var による条件分岐がどうしても必要になる気がする)。
mylength([], 0).mylength([_|T], N) :- mylength(T, N1), N is N1 + 1.零リスト([]).零リスト([0|T]) :- 零リスト(T).単位行列(N, LL) :- mylength(LL, N), 単位行列_(N, LL).単位行列_(0, []).単位行列_(N, [[1|RowT]|T]) :-% number(N), N > 0,N1 is N - 1, mylength(RowT, N1), !, % important!行列の左に列ベクトルを加える(T1, ClmT, T),零リスト(RowT), 零リスト(ClmT),単位行列_(N1, T1).行列の左に列ベクトルを加える([], [], []).行列の左に列ベクトルを加える([T|LL1], [H|V], [[H|T]|LL]) :-行列の左に列ベクトルを加える(LL1, V, LL).?- 単位行列(2, [[1, 0], [0, 1]])./*yes*/?- 単位行列(N, [[1, 0], [0, 1]])./*N = 2 ;no*/% うまく定義しないと no が返らず無限ループに陥ることも。?- 単位行列(2, LL)./*LL = [[1, 0], [0, 1]] ;... (無限ループに陥る)*/% no を返してほしいところだが、次の結果を得るためにはこの挙動にならざるをえない??- 単位行列(N, LL)./*N = 0, LL = [] ;N = 1, LL = [[1, 0], [0, 1]] ;N = 2, LL = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] ;N = 3, LL = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] ;... (各Nについて無限に成功する)*/% うまく定義しないと N = 0, 1 だけで終わってしまうことも。