(* Union *)

Remark union_not_same_class:
  forall uf a b, repr uf a <> repr uf b -> repr uf (repr uf b) <> repr uf a.Definition union (uf: t) (a b: elt) : t :=
  let a' := repr uf a in
  let b' := repr uf b in
  match M.elt_eq a' b' with
  | left EQ => uf
  | right NEQ => identify uf a' b' (repr_res_none uf a) (union_not_same_class uf a b NEQ)
  end.

(* Specifications: *)
Lemma repr_union_1: forall uf a b x, repr uf x <> repr uf a -> repr (union uf a b) x = repr uf x.
Lemma repr_union_2: forall uf a b x, repr uf x = repr uf a -> repr (union uf a b) x = repr uf b.
Lemma repr_union_3: forall uf a b, repr (union uf a b) b = repr uf b.
Lemma sameclass_union_1: forall uf a b, sameclass (union uf a b) a b.
Lemma sameclass_union_2: forall uf a b x y, sameclass uf x y -> sameclass (union uf a b) x y.
Lemma sameclass_union_3: forall uf a b x y, sameclass (union uf a b) x y -> sameclass uf x y \/ sameclass uf x a /\ sameclass uf y b \/ sameclass uf x b /\ sameclass uf y a.
Lemma repr_union_1: forall uf a b x, repr uf x <> repr uf a -> repr (union uf a b) x = repr uf x.
Lemma repr_union_2: forall uf a b x, repr uf x = repr uf a -> repr (union uf a b) x = repr uf b.
Lemma repr_union_3: forall uf a b, repr (union uf a b) b = repr uf b.
Lemma sameclass_union_1: forall uf a b, sameclass (union uf a b) a b.
Lemma sameclass_union_2: forall uf a b x y, sameclass uf x y -> sameclass (union uf a b) x y.
Lemma sameclass_union_3: forall uf a b x y, sameclass (union uf a b) x y -> sameclass uf x y \/ sameclass uf x a /\ sameclass uf y b \/ sameclass uf x b /\ sameclass uf y a.