Fixpoint to_fin_mult {m n} : Fin m * Fin n -> Fin (m * n) :=
  match m with
  | 0 => fun p =>
    match fst p with
    end
  | S k => fun p =>
    match fst p with
    | inl tt => to_fin_sum (inl (snd p))
    | inr j => to_fin_sum (inr (to_fin_mult (j, snd p)))
    end
  end.Fixpoint from_fin_mult {m n} : Fin (m * n) -> Fin m * Fin n :=
  match m with
  | 0 => fun i =>
    match i with
    end
  | S k => fun i =>
    match from_fin_sum i with
    | inl j => (inl tt, j)
    | inr j =>
      match from_fin_mult j with
      | (k1, k2) => (inr k1, k2)
      end
    end
  end.

(* Specifications: *)
Lemma to_from_fin_mult {m n} : forall i : Fin (m * n), to_fin_mult (from_fin_mult i) = i.
Lemma from_to_fin_mult {m n} : forall p : Fin m * Fin n, from_fin_mult (to_fin_mult p) = p.
Lemma to_from_fin_mult {m n} : forall i : Fin (m * n), to_fin_mult (from_fin_mult i) = i.
Lemma from_to_fin_mult {m n} : forall p : Fin m * Fin n, from_fin_mult (to_fin_mult p) = p.