Bind Scope ring_scope with matrix.
Notation "''M[' R ]_ ( m , n )" := (matrix R m n) (only parsing): type_scope.
Notation "''rV[' R ]_ n" := 'M[R]_(1, n) (only parsing) : type_scope.
Notation "''cV[' R ]_ n" := 'M[R]_(n, 1) (only parsing) : type_scope.
Notation "''M[' R ]_ n" := 'M[R]_(n, n) (only parsing) : type_scope.
Notation "''M[' R ]_ ( n )" := 'M[R]_n (only parsing) : type_scope.
Notation "''M_' ( m , n )" := 'M[_]_(m, n) : type_scope.
Notation "''rV_' n" := 'M_(1, n) : type_scope.
Notation "''cV_' n" := 'M_(n, 1) : type_scope.
Notation "''M_' n" := 'M_(n, n) : type_scope.
Notation "''M_' ( n )" := 'M_n (only parsing) : type_scope.
Notation "\matrix[ k ]_ ( i , j ) E" := (matrix_of_fun k (fun i j => E))
(at level 36, E at level 36, i, j at level 50): ring_scope.
Notation "\matrix_ ( i < m , j < n ) E" :=
(@matrix_of_fun _ m n matrix_key (fun i j => E)) (only parsing) : ring_scope.
Notation "\matrix_ ( i , j < n ) E" :=
(\matrix_(i < n, j < n) E) (only parsing) : ring_scope.
Notation "\matrix_ ( i , j ) E" := (\matrix_(i < _, j < _) E) : ring_scope.
Notation "\matrix_ ( i < m ) E" :=
(\matrix_(i < m, j < _) @fun_of_matrix _ 1 _ E 0 j)
(only parsing) : ring_scope.
Notation "\matrix_ i E" := (\matrix_(i < _) E) : ring_scope.
Notation "\col_ ( i < n ) E" := (@matrix_of_fun _ n 1 matrix_key (fun i _ => E))
(only parsing) : ring_scope.
Notation "\col_ i E" := (\col_(i < _) E) : ring_scope.
Notation "\row_ ( j < n ) E" := (@matrix_of_fun _ 1 n matrix_key (fun _ j => E))
(only parsing) : ring_scope.
Notation "\row_ j E" := (\row_(j < _) E) : ring_scope.
Definition matrix_eqMixin (R : eqType) m n :=
Eval hnf in [eqMixin of 'M[R]_(m, n) by <:].
Canonical matrix_eqType (R : eqType) m n:=
Eval hnf in EqType 'M[R]_(m, n) (matrix_eqMixin R m n).
Definition matrix_choiceMixin (R : choiceType) m n :=
[choiceMixin of 'M[R]_(m, n) by <:].
Canonical matrix_choiceType (R : choiceType) m n :=
Eval hnf in ChoiceType 'M[R]_(m, n) (matrix_choiceMixin R m n).
Definition matrix_countMixin (R : countType) m n :=
[countMixin of 'M[R]_(m, n) by <:].
Canonical matrix_countType (R : countType) m n :=
Eval hnf in CountType 'M[R]_(m, n) (matrix_countMixin R m n).
Canonical matrix_subCountType (R : countType) m n :=
Eval hnf in [subCountType of 'M[R]_(m, n)].
Definition matrix_finMixin (R : finType) m n :=
[finMixin of 'M[R]_(m, n) by <:].
Canonical matrix_finType (R : finType) m n :=
Eval hnf in FinType 'M[R]_(m, n) (matrix_finMixin R m n).
Canonical matrix_subFinType (R : finType) m n :=
Eval hnf in [subFinType of 'M[R]_(m, n)].

(* This lemma has Prenex Implicits to help RL rewrititng with castmx_sym. *)
Lemma col_mxA m1 m2 m3 n (A1 : 'M_(m1, n)) (A2 : 'M_(m2, n)) (A3 : 'M_(m3, n)) :
let cast := (esym (addnA m1 m2 m3), erefl n) in
col_mx A1 (col_mx A2 A3) = castmx cast (col_mx (col_mx A1 A2) A3).