(* Partial identity matrix (used in rank decomposition). *)
Fact pid_mx_key : unit. Proof. by []. Qed.
Definition pid_mx {m n} r : 'M[R]_(m, n) :=
\matrix[pid_mx_key]_(i, j) ((i == j :> nat) && (i < r))%:R.

(* Specifications: *)
Lemma pid_mx_0 m n : pid_mx 0 = 0 :> 'M_(m, n).
Lemma pid_mx_col m r : pid_mx r = col_mx 1%:M 0 :> 'M_(r + m, r).
Lemma pid_mx_block m n r : pid_mx r = block_mx 1%:M 0 0 0 :> 'M_(r + m, r + n).
Lemma tr_pid_mx m n r : (pid_mx r)^T = pid_mx r :> 'M_(n, m).
Lemma pid_mx_id m n p r :
r <= n -> (pid_mx r : 'M_(m, n)) *m (pid_mx r : 'M_(n, p)) = pid_mx r.
(* Block products; we cover all 1 x 2, 2 x 1, and 2 x 2 block products. *)
Lemma mul_mx_row m n p1 p2 (A : 'M_(m, n)) (Bl : 'M_(n, p1)) (Br : 'M_(n, p2)) :
A *m row_mx Bl Br = row_mx (A *m Bl) (A *m Br).
Lemma mul_col_mx m1 m2 n p (Au : 'M_(m1, n)) (Ad : 'M_(m2, n)) (B : 'M_(n, p)) :
col_mx Au Ad *m B = col_mx (Au *m B) (Ad *m B).
Lemma mul_row_col m n1 n2 p (Al : 'M_(m, n1)) (Ar : 'M_(m, n2))
(Bu : 'M_(n1, p)) (Bd : 'M_(n2, p)) :
row_mx Al Ar *m col_mx Bu Bd = Al *m Bu + Ar *m Bd.
Lemma mul_col_row m1 m2 n p1 p2 (Au : 'M_(m1, n)) (Ad : 'M_(m2, n))
(Bl : 'M_(n, p1)) (Br : 'M_(n, p2)) :
col_mx Au Ad *m row_mx Bl Br
= block_mx (Au *m Bl) (Au *m Br) (Ad *m Bl) (Ad *m Br).