Section MatrixRing.
Variable n' : nat.
Local Notation n := n'.+1.
(* Determinants and adjugates are defined here, but most of their properties *)
(* only hold for matrices over a commutative ring, so their theory is        *)
(* deferred to that section.                                                 *)
(* The determinant, in one line with the Leibniz Formula *)
Definition determinant n (A : 'M_n) : R :=
\sum_(s : 'S_n) (-1) ^+ s * \prod_i A i (s i).
(* The cofactor of a matrix on the indexes i and j *)
Definition cofactor n A (i j : 'I_n) : R :=
(-1) ^+ (i + j) * determinant (row' i (col' j A)).
(* The adjugate matrix : defined as the transpose of the matrix of cofactors *)
Fact adjugate_key : unit. Proof. by []. Qed.
Definition adjugate n (A : 'M_n) := \matrix[adjugate_key]_(i, j) cofactor A j i.
End MatrixAlgebra.
Arguments delta_mx {R m n}.
Arguments scalar_mx {R n}.
Arguments perm_mx {R n}.
Arguments tperm_mx {R n}.
Arguments pid_mx {R m n}.
Arguments copid_mx {R n}.
Arguments lin_mulmxr {R m n p}.
Prenex Implicits diag_mx is_scalar_mx.
Prenex Implicits mulmx mxtrace determinant cofactor adjugate.
Arguments is_scalar_mxP {R n A}.
Arguments mul_delta_mx {R m n p}.
Hint Extern 0 (is_true (is_diag_mx (scalar_mx _))) =>
apply: scalar_mx_is_diag : core.
Hint Extern 0 (is_true (is_trig_mx (scalar_mx _))) =>
apply: scalar_mx_is_trig : core.
Hint Extern 0 (is_true (is_diag_mx (diag_mx _))) =>
apply: diag_mx_is_diag : core.
Hint Extern 0 (is_true (is_trig_mx (diag_mx _))) =>
apply: diag_mx_is_trig : core.
Notation "a %:M" := (scalar_mx a) : ring_scope.
Notation "A *m B" := (mulmx A B) : ring_scope.
Arguments mulmxr {_ _ _ _} B A /.
Notation "\tr A" := (mxtrace A) : ring_scope.
Notation "'\det' A" := (determinant A) : ring_scope.
Notation "'\adj' A" := (adjugate A) : ring_scope.

(* Non-commutative transpose requires multiplication in the converse ring.   *)
Lemma trmx_mul_rev (R : ringType) m n p (A : 'M[R]_(m, n)) (B : 'M[R]_(n, p)) :
(A *m B)^T = (B : 'M[R^c]_(n, p))^T *m (A : 'M[R^c]_(m, n))^T.