Definition elt := M.elt.Definition elt_eq := M.elt_eq.(* A set of equivalence classes over elt is represented by a map m.
   M.get a m = Some a' means that a is in the same class as a'.
   M.get a m = None means that a is the canonical representative
     for its equivalence class. *)

(* The ordering over elt induced by such a map.
   repr_order m a a' iff M.get a' m = Some a.
   This ordering must be well founded. *)

Definition order (m: M.t elt) (a a': elt) : Prop :=
  M.get a' m = Some a.Record unionfind : Type := mk { m: M.t elt; mwf: well_founded (order m) }.Record unionfind : Type := mk { m: M.t elt; mwf: well_founded (order m) }.Record unionfind : Type := mk { m: M.t elt; mwf: well_founded (order m) }.Record unionfind : Type := mk { m: M.t elt; mwf: well_founded (order m) }.Definition t := unionfind.Definition getlink (m: M.t elt) (a: elt) : {a' | M.get a m = Some a'} + {M.get a m = None}.Definition F_repr (a: elt) (rec: forall b, order uf.(m) b a -> elt) : elt :=
  match getlink uf.(m) a with
  | inleft (exist a' P) => rec a' P
  | inright _ => a
  end.Definition repr (a: elt) : elt := Fix uf.(mwf) (fun _ => elt) F_repr a.

(* Specifications: *)
Lemma repr_unroll: forall a, repr a = match M.get a uf.(m) with Some a' => repr a' | None => a end.
Lemma repr_none: forall a, M.get a uf.(m) = None -> repr a = a.
Lemma repr_some: forall a a', M.get a uf.(m) = Some a' -> repr a = repr a'.
Lemma repr_res_none: forall (a: elt), M.get (repr a) uf.(m) = None.
Lemma repr_canonical: forall (a: elt), repr (repr a) = repr a.
Lemma repr_some_diff: forall a a', M.get a uf.(m) = Some a' -> a <> repr a'.
Lemma repr_unroll: forall a, repr a = match M.get a uf.(m) with Some a' => repr a' | None => a end.
Lemma repr_none: forall a, M.get a uf.(m) = None -> repr a = a.
Lemma repr_some: forall a a', M.get a uf.(m) = Some a' -> repr a = repr a'.
Lemma repr_res_none: forall (a: elt), M.get (repr a) uf.(m) = None.
Lemma repr_canonical: forall (a: elt), repr (repr a) = repr a.
Lemma repr_some_diff: forall a a', M.get a uf.(m) = Some a' -> a <> repr a'.