非決定性の述語 単位行列/2 (「添字」を用いるバージョン)

【目標】述語 単位行列/2 を“うまく”定義する。
【出典】http://codetter.com/?p=902
「添字」を考えて、単位行列 E_n := [ δ_i,j ]_n×n として定義する。
数値を用いると is によって双方向性を失ってしまうので、ペアノ自然数 s(N) を用いる。
ペアノ自然数と数値を相互に単一化させる述語 natural/2 に、めんどくさい条件分岐を押し付けることで、定義を簡潔にする試み。

【目標】述語 単位行列/2 を“うまく”定義する。
【出典】http://codetter.com/?p=902
「添字」を考えて、単位行列 E_n := [ δ_i,j ]_n×n として定義する。
数値を用いると is によって双方向性を失ってしまうので、ペアノ自然数 s(N) を用いる。
ペアノ自然数と数値を相互に単一化させる述語 natural/2 に、めんどくさい条件分岐を押し付けることで、定義を簡潔にする試み。

  • タグ:
  • タグはありません
natural(0).
natural(s(N)) :- natural(N).
natural(0, 0).
natural(s(N), X) :- number(X), !, X > 0, X1 is X - 1, natural(N, X1). % N X
natural(s(N), X) :- var(X), !, integer_itetate(X, 1), natural(s(N), X). %
natural(s(N), X) :- natural_acc(N, X, 1), !. % X N
natural_acc(0, X, X).
natural_acc(s(N), X, Acc) :- Acc1 is Acc + 1, natural_acc(N, X, Acc1).
integer_itetate(X, X).
integer_itetate(X, L) :- L1 is L + 1, integer_itetate(X, L1).
mylength_n([], 0).
mylength_n([Head|Tail], s(N)) :- mylength_n(Tail, N).
at_n([Val|_], 0, Val).
at_n([_|List], s(N), Val) :- at_n(List, N, Val).
insertAt_n(List, 0, Val, [Val|List]).
insertAt_n([X|List], s(N), Val, [X|Tail]) :- insertAt_n(List, N, Val, Tail).
([]).
([0|T]) :- (T).
_n(0, []).
_n(s(N), LL) :- _n(s(N), LL, 0). %
_n(N, [], N).
_n(N, [Row|RowT], M) :-
mylength_n(Row, N), insertAt_n(RowRems, M, 1, Row), (RowRems),
_n(N, RowT, s(M)).
(X, LL) :- natural(N, X), _n(N, LL). %
?- (2, [[1, 0], [0, 1]]). %=> yes
?- (N, [[1, 0], [0, 1]]). %=> N = 2 ; ... ()
?- (2, LL). %=> LL = [[1,0],[0,1]] ; no
?- (N, LL). %=> N = 0, 1, 2, ...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX