Definition F_pathlen (a: elt) (rec: forall b, order uf.(m) b a -> nat) : nat :=
  match getlink uf.(m) a with
  | inleft (exist a' P) => S (rec a' P)
  | inright _ => O
  end.Definition pathlen (a: elt) : nat := Fix uf.(mwf) (fun _ => nat) F_pathlen a.

(* Specifications: *)
Lemma pathlen_unroll: forall a, pathlen a = match M.get a uf.(m) with Some a' => S(pathlen a') | None => O end.
Lemma pathlen_none: forall a, M.get a uf.(m) = None -> pathlen a = 0.
Lemma pathlen_some: forall a a', M.get a uf.(m) = Some a' -> pathlen a = S (pathlen a').
Lemma pathlen_zero: forall a, repr uf a = a <-> pathlen a = O.
Lemma pathlen_merge: forall uf a b x, pathlen (merge uf a b) x = if M.elt_eq (repr uf a) (repr uf b) then pathlen uf x else if M.elt_eq (repr uf x) (repr uf a) then pathlen uf x + pathlen uf b + 1 else pathlen uf x.
Lemma pathlen_gt_merge: forall uf a b x y, repr uf x = repr uf y -> pathlen uf x > pathlen uf y -> pathlen (merge uf a b) x > pathlen (merge uf a b) y.
Lemma compress_order: forall x y, order (M.set a b uf.(m)) y x -> order uf.(m) y x \/ (x = a /\ y = b).
Lemma pathlen_unroll: forall a, pathlen a = match M.get a uf.(m) with Some a' => S(pathlen a') | None => O end.
Lemma pathlen_none: forall a, M.get a uf.(m) = None -> pathlen a = 0.
Lemma pathlen_some: forall a a', M.get a uf.(m) = Some a' -> pathlen a = S (pathlen a').
Lemma pathlen_zero: forall a, repr uf a = a <-> pathlen a = O.
Lemma pathlen_merge: forall uf a b x, pathlen (merge uf a b) x = if M.elt_eq (repr uf a) (repr uf b) then pathlen uf x else if M.elt_eq (repr uf x) (repr uf a) then pathlen uf x + pathlen uf b + 1 else pathlen uf x.
Lemma pathlen_gt_merge: forall uf a b x y, repr uf x = repr uf y -> pathlen uf x > pathlen uf y -> pathlen (merge uf a b) x > pathlen (merge uf a b) y.
Lemma compress_order: forall x y, order (M.set a b uf.(m)) y x -> order uf.(m) y x \/ (x = a /\ y = b).