(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
(** Sets as characteristic functions *)
(* G. Huet 1-9-95 *)
(* Updated Papageno 12/98 *)
Set Implicit Arguments.
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.
#[local]
Hint Unfold In : core.
(** uniset inclusion *)
Definition incl (s1 s2:uniset) := forall a:A, Bool.le (charac s1 a) (charac s2 a).
#[local]
Hint Unfold incl : core.
(** uniset equality *)
Definition seq (s1 s2:uniset) := forall a:A, charac s1 a = charac s2 a.
#[local]
Hint Unfold seq : core.

(* Specifications: *)
Lemma le_refl : forall b, Bool.le b b.
#[local]
Hint Resolve le_refl : core.
Lemma incl_left : forall s1 s2:uniset, seq s1 s2 -> incl s1 s2.
Lemma incl_right : forall s1 s2:uniset, seq s1 s2 -> incl s2 s1.
Lemma seq_refl : forall x:uniset, seq x x.
#[local]
Hint Resolve seq_refl : core.
Lemma seq_trans : forall x y z:uniset, seq x y -> seq y z -> seq x z.
Lemma seq_sym : forall x y:uniset, seq x y -> seq y x.
Definition union (m1 m2:uniset) :=
Charac (fun a:A => orb (charac m1 a) (charac m2 a)).