End COMPRESS.
(* Find with path compression *)
Section FIND.
Variable uf: t.
Program Fixpoint find_x (a: elt) {wf (order uf.(m)) a} :
{ r: elt * t | fst r = repr uf a /\ forall x, repr (snd r) x = repr uf x } :=
match M.get a uf.(m) with
| Some a' =>
match find_x a' with
| pair b uf' => (b, compress uf' a b _ _)
end
| None => (a, uf)
end.
Next Obligation.
red. auto.
Qed.
Next Obligation.
(* a <> b*)
destruct (find_x a')
as [[b' uf''] [A B]]. simpl in *. inv Heq_anonymous.
apply repr_some_diff. auto.
Qed.
Next Obligation.
destruct (find_x a') as [[b' uf''] [A B]]. simpl in *. inv Heq_anonymous.
rewrite B. apply repr_some. auto.
Qed.
Next Obligation.
split.
destruct (find_x a')
as [[b' uf''] [A B]]. simpl in *. inv Heq_anonymous.
symmetry. apply repr_some. auto.
intros. rewrite repr_compress.
destruct (find_x a')
as [[b' uf''] [A B]]. simpl in *. inv Heq_anonymous. auto.
Qed.
Next Obligation.
split; auto. symmetry. apply repr_none. auto.
Qed.
Next Obligation.
apply mwf.
Defined.
Definition find (a: elt) : elt * t := proj1_sig (find_x a).

Lemma find_unchanged:
forall a x, repr (snd (find a)) x = repr uf x.