Section defs.
Variable A : Set.
Variable eqA : A -> A -> Prop.
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
Inductive uniset : Set :=
Charac : (A -> bool) -> uniset.
Definition charac (s:uniset) (a:A) : bool := let (f) := s in f a.
Definition Emptyset := Charac (fun a:A => false).
Definition Fullset := Charac (fun a:A => true).
Definition Singleton (a:A) :=
Charac
(fun a':A =>
match eqA_dec a a' with
| left h => true
| right h => false
end).
Definition In (s:uniset) (a:A) : Prop := charac s a = true.
Hint Unfold In : core.
(** uniset inclusion *)
Definition incl (s1 s2:uniset) := forall a:A, leb (charac s1 a) (charac s2 a).
Hint Unfold incl : core.
(** uniset equality *)
Definition seq (s1 s2:uniset) := forall a:A, charac s1 a = charac s2 a.
Hint Unfold seq : core.
Hint Resolve leb_refl : core.
Hint Resolve seq_refl : core.
(** uniset union *)
Definition union (m1 m2:uniset) :=
Charac (fun a:A => orb (charac m1 a) (charac m2 a)).
Hint Resolve union_empty_left : core.
Hint Resolve union_empty_right : core.
Hint Resolve union_comm : core.
Hint Resolve union_ass : core.
Hint Resolve seq_left : core.
Hint Resolve seq_right : core.
(** All the proofs that follow duplicate [Multiset_of_A] *)
(** Here we should make uniset an abstract datatype, by hiding [Charac], [union], [charac]; all further properties are proved abstractly *)

Lemma union_rotate :
forall x y z:uniset, seq (union x (union y z)) (union z (union x y)).