Пролог матричных операций

#matrix #prolog

#матрица #пролог

Вопрос:

Привет, мне нужна помощь с некоторыми функциями prolog, пожалуйста:

Определение предикатов:

строка (X, N, C): C — строка N матрицы X.

столбец (X, N, C): C — это столбец N матрицы X.

first_column(X,C,R): матрица X образована первым столбцом C и остальной частью матрицы R.

симметричный(X): X — это квадратная матрица, симметричная диагонали.

Матрица представляет собой список списков: [[a, b, c],[d, e, f], [g, h, i]] >>>

           a b c
          d e f
          g h i
  

Ответ №1:

Рассмотрим:

 row(M, N, Row) :-
    nth1(N, M, Row).

column(M, N, Col) :-
    transpose(M, MT),
    row(MT, N, Col).

symmetrical(M) :-
    transpose(M, M).

transpose([[]|_], []) :- !.
transpose([[I|Is]|Rs], [Col|MT]) :-
    first_column([[I|Is]|Rs], Col, [Is|NRs]),
    transpose([Is|NRs], MT).

first_column([], [], []).
first_column([[]|_], [], []).
first_column([[I|Is]|Rs], [I|Col], [Is|Rest]) :-
    first_column(Rs, Col, Rest).
  

Тестирование с:

 matrix([[a,b,c],[d,e,f],[g,h,i]]).
  

Для строк:

  ?- matrix(M), row(M, N, Row).
M = [[a, b, c], [d, e, f], [g, h, i]],
N = 1,
Row = [a, b, c] ;
M = [[a, b, c], [d, e, f], [g, h, i]],
N = 2,
Row = [d, e, f] ;
M = [[a, b, c], [d, e, f], [g, h, i]],
N = 3,
Row = [g, h, i] ;
false.
  

Столбцы:

 ?- matrix(M), column(M, N, Col).
M = [[a, b, c], [d, e, f], [g, h, i]],
N = 1,
Col = [a, d, g] ;
M = [[a, b, c], [d, e, f], [g, h, i]],
N = 2,
Col = [b, e, h] ;
M = [[a, b, c], [d, e, f], [g, h, i]],
N = 3,
Col = [c, f, i] ;
false.
  

Первый столбец:

 ?- matrix(M), first_column(M, C, R).
M = [[a, b, c], [d, e, f], [g, h, i]],
C = [a, d, g],
R = [[b, c], [e, f], [h, i]].
  

Наконец, симметрия матрицы определяется любой матрицей, которая является транспозицией самой себя.

  ?- matrix(M), symmetrical(M).
false.

?- symmetrical([[a,b,c],[b,d,e],[c,e,f]]).
true.
  

Ответ №2:

В SWI-Prolog вы могли бы определить предикаты строк и столбцов следующим образом:

 row(N, Matrix, Row) :-
    nth1(N, Matrix, Row).

col(N, Matrix, Col) :-
    maplist(nth1(N), Matrix, Col).
  

Обратите внимание, что, используя эти определения, вы также можете генерировать строки / столбцы, если задано только Matrix , например

 ?- col(N, [[a, b], [c, d]], Col).
N = 1,
Col = [a, c] ;
N = 2,
Col = [b, d] ;
false.
  

Симметричные матрицы могут быть сгенерированы следующим образом:

 % Generates matrix elements
element(RowN-ColN, Matrix, El) :-
    row(RowN, Matrix, Row),
    nth1(ColN, Row, El).

% Generates matrix symmetric elements, i.e. where Aij = Aji.
symmetric_element(Matrix, RowN-ColN) :-
    element(RowN-ColN, Matrix, El),
    element(ColN-RowN, Matrix, El).

% Generates row-colum indices for the upper triangle.
get_index_pair(N, RowN-ColN) :-
    between(1, N, RowN),
    succ(RowN, RowN1),
    between(RowN1, N, ColN).

% Generates matrixes where every element is symmetric.
symmetric(Matrix) :-
    length(Matrix, N),
    findall(IndexPair, get_index_pair(N, IndexPair), IndexPairs),
    maplist(symmetric_element(Matrix), IndexPairs).
  

Использование:

 ?- Matrix = [[a, b, c], Row2, Row3], symmetric(Matrix), numbervars(Matrix, 0, _).
Matrix = [[a, b, c], [b, A, B|C], [c, B|D]],
Row2 = [b, A, B|C],
Row3 = [c, B|D].
  

Ответ №3:

 
row(N,Matrix,Row) :-
        nth1(N,Matrix,Row).

col(N,Matrix,Col) :-
        findall(E,(append(_,[Row|_],Matrix),nth1(N,Row,E)),Col).
  

Комментарии:

1. Такое поведение не совсем разумно: ?- col(_, [[a, b], [c, d]], Col). Col = [a, b, c, d].