Section MatrixDef.
Variable R : Type.
Variables m n : nat.
(* Basic linear algebra (matrices).                                       *)
(* We use dependent types (ordinals) for the indices so that ranges are   *)
(* mostly inferred automatically                                          *)
Variant matrix : predArgType := Matrix of {ffun 'I_m * 'I_n -> R}.
Definition mx_val A := let: Matrix g := A in g.
Canonical matrix_subType := Eval hnf in [newType for mx_val].
Fact matrix_key : unit. Proof. by []. Qed.
Definition matrix_of_fun_def F := Matrix [ffun ij => F ij.1 ij.2].
Definition matrix_of_fun k := locked_with k matrix_of_fun_def.
Canonical matrix_unlockable k := [unlockable fun matrix_of_fun k].
Definition fun_of_matrix A (i : 'I_m) (j : 'I_n) := mx_val A (i, j).
Coercion fun_of_matrix : matrix >-> Funclass.
Definition row_mxAx := row_mxA. (* bypass Prenex Implicits. *)

Lemma block_mxEh :
block_mx Aul Aur Adl Adr = row_mx (col_mx Aul Adl) (col_mx Aur Adr).