Variable n' : nat.
Local Notation n := n'.+1.
Canonical matrix_algType :=
Eval hnf in AlgType R 'M[R]_n (fun k => scalemxAr k).
End MatrixAlgType.

(* Specifications: *)
Lemma diag_mxC n (d e : 'rV[R]_n) :
diag_mx d *m diag_mx e = diag_mx e *m diag_mx d.
Lemma diag_mx_comm n' (d e : 'rV[R]_n'.+1) : GRing.comm (diag_mx d) (diag_mx e).
Lemma scalar_mx_comm n' a (A : 'M[R]_n'.+1) : GRing.comm A a%:M.
(* The theory of determinants *)
Lemma determinant_multilinear n (A B C : 'M[R]_n) i0 b c :
row i0 A = b *: row i0 B + c *: row i0 C ->
row' i0 B = row' i0 A ->
row' i0 C = row' i0 A ->
\det A = b * \det B + c * \det C.
Lemma determinant_alternate n (A : 'M[R]_n) i1 i2 :
i1 != i2 -> A i1 =1 A i2 -> \det A = 0.
Lemma det_tr n (A : 'M[R]_n) : \det A^T = \det A.
Lemma det_perm n (s : 'S_n) : \det (perm_mx s) = (-1) ^+ s :> R.
Lemma det1 n : \det (1%:M : 'M[R]_n) = 1.
Lemma det0 n' : \det (0 : 'M[R]_n'.+1) = 0.
Lemma detM n' (A B : 'M[R]_n'.+1) : \det (A * B) = \det A * \det B.
(* Laplace expansion lemma *)
Lemma expand_cofactor n (A : 'M[R]_n) i j :
cofactor A i j =
\sum_(s : 'S_n | s i == j) (-1) ^+ s * \prod_(k | i != k) A k (s k).
Lemma expand_det_row n (A : 'M[R]_n) i0 :
\det A = \sum_j A i0 j * cofactor A i0 j.
Lemma cofactor_tr n (A : 'M[R]_n) i j : cofactor A^T i j = cofactor A j i.
Lemma cofactorZ n a (A : 'M[R]_n) i j :
cofactor (a *: A) i j = a ^+ n.-1 * cofactor A i j.
Lemma trmx_adj n (A : 'M[R]_n) : (\adj A)^T = \adj A^T.
(* Cramer rule : adjugate on the right *)
Lemma mul_adj_mx n (A : 'M[R]_n) : \adj A *m A = (\det A)%:M.
Lemma adj1 n : \adj (1%:M) = 1%:M :> 'M[R]_n.
(* Only tall matrices have inverses. *)
Lemma mulmx1_min m n (A : 'M[R]_(m, n)) B : A *m B = 1%:M -> m <= n.
Lemma det_ublock n1 n2 Aul (Aur : 'M[R]_(n1, n2)) Adr :
\det (block_mx Aul Aur 0 Adr) = \det Aul * \det Adr.
Lemma det_lblock n1 n2 Aul (Adl : 'M[R]_(n2, n1)) Adr :
\det (block_mx Aul 0 Adl Adr) = \det Aul * \det Adr.
Lemma invmx_scalar a : invmx (a%:M) = a^-1%:M.
Lemma mulVmx : {in unitmx, left_inverse 1%:M invmx mulmx}.
Lemma mulmxV : {in unitmx, right_inverse 1%:M invmx mulmx}.
Lemma mulKmx m : {in unitmx, @left_loop _ 'M_(n, m) invmx mulmx}.
Lemma unitmx_inv A : (invmx A \in unitmx) = (A \in unitmx).
Lemma mulmx1_unit A B : A *m B = 1%:M -> A \in unitmx /\ B \in unitmx.
Lemma is_perm_mxV (A : 'M_n) : is_perm_mx A^-1 = is_perm_mx A.
End MatrixInv.