Section LtmxIdentities.
Variables (m1 m2 n : nat) (A : 'M_(m1, n)) (B : 'M_(m2, n)).
Hint Resolve rank_leq_row rank_leq_col row_ebase_unit col_ebase_unit : core.
Arguments mulmx_max_rank [r m n].
Arguments submxP {m1 m2 n A B}.
Arguments row_subP {m1 m2 n A B}.
Arguments rV_subP {m1 m2 n A B}.
Arguments row_fullP {m n A}.
(* A variant of row_free_inj that exposes mulmxr, an alias for mulmx^~ *)
(* but which is canonically additive *)
Definition row_free_injr m n p A : row_free A -> injective (mulmxr A) :=
@row_free_inj m n p A.
Arguments eqmxP {m1 m2 n A B}.
Arguments genmxP {m1 m2 n A B}.
Hint Resolve row_base_free col_base_full : core.
Let eqmx_sum_nop m n (A : 'M_(m, n)) : (addsmx_nop A :=: A)%MS.
End AddsmxSub.
Canonical addsmx_monoid n :=
Monoid.Law (@addsmxA n n n n) (@adds0mx_id n n) (@addsmx0_id n n).
Canonical addsmx_comoid n := Monoid.ComLaw (@addsmxC n n n).
Arguments sub_addsmxP {m1 m2 m3 n A B C}.
Variable I : finType.
Implicit Type P : pred I.
Arguments sumsmx_sup i0 [P m n A B_].
Let capmx_witnessP m n (A : 'M_(m, n)) : equivmx A (qidmx A) (capmx_witness A).
Let capmx_normP m n (A : 'M_(m, n)) : equivmx_spec A (qidmx A) (capmx_norm A).
Let capmx_nopP m n (A : 'M_(m, n)) : equivmx_spec A (qidmx A) (capmx_nop A).
Let sub_qidmx m1 m2 n (A : 'M_(m1, n)) (B : 'M_(m2, n)) :
qidmx B -> (A <= B)%MS.
Let qidmx_cap m1 m2 n (A : 'M_(m1, n)) (B : 'M_(m2, n)) :
qidmx (A :&: B)%MS = qidmx A && qidmx B.
Let capmx_eq_norm m1 m2 n (A : 'M_(m1, n)) (B : 'M_(m2, n)) :
qidmx A = qidmx B -> (A :&: B)%MS = capmx_norm (A :&: B)%MS.
Canonical capmx_monoid n :=
Monoid.Law (@capmxA n n n n) (@cap1mx n) (@capmx1 n).
Canonical capmx_comoid n := Monoid.ComLaw (@capmxC n n n).

Lemma mxrank_mul_ker m n p (A : 'M_(m, n)) (B : 'M_(n, p)) :
(\rank (A *m B) + \rank (A :&: kermx B))%N = \rank A.