(************************************************************************)
(*         *      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)         *)
(************************************************************************)
(** * Finite sets library *)
(** This module implements bridges (as functors) from dependent to/from non-dependent set signature. *)
Require Export FSetInterface.
Set Implicit Arguments.
Unset Strict Implicit.
Set Firstorder Depth 2.
(** * From non-dependent signature [S] to dependent signature [Sdep]. *)
Module DepOfNodep (Import M: S) <: Sdep with Module E := M.E.
Local Ltac Tauto.intuition_solver ::= auto with bool set.
Definition empty : {s : t | Empty s}.
Definition is_empty : forall s : t, {Empty s} + {~ Empty s}.
Definition mem : forall (x : elt) (s : t), {In x s} + {~ In x s}.
Definition Add (x : elt) (s s' : t) :=
forall y : elt, In y s' <-> E.eq x y \/ In y s.
Definition add : forall (x : elt) (s : t), {s' : t | Add x s s'}.
Definition singleton :
forall x : elt, {s : t | forall y : elt, In y s <-> E.eq x y}.
Definition remove :
forall (x : elt) (s : t),
{s' : t | forall y : elt, In y s' <-> ~ E.eq x y /\ In y s}.
Definition union :
forall s s' : t, {s'' : t | forall x : elt, In x s'' <-> In x s \/ In x s'}.
Definition inter :
forall s s' : t, {s'' : t | forall x : elt, In x s'' <-> In x s /\ In x s'}.
Definition diff :
forall s s' : t, {s'' : t | forall x : elt, In x s'' <-> In x s /\ ~ In x s'}.
Definition equal : forall s s' : t, {Equal s s'} + {~ Equal s s'}.
Definition subset : forall s s' : t, {Subset s s'} + {~Subset s s'}.
Definition elements :
forall s : t,
{l : list elt | sort E.lt l /\ (forall x : elt, In x s <-> InA E.eq x l)}.
Definition cardinal :
forall s : t,
{r : nat | let (l,_) := elements s in r = length l }.
Definition fdec (P : elt -> Prop) (Pdec : forall x : elt, {P x} + {~ P x})
(x : elt) := if Pdec x then true else false.

Lemma compat_P_aux :
forall (P : elt -> Prop) (Pdec : forall x : elt, {P x} + {~ P x}),
compat_P E.eq P -> compat_bool E.eq (fdec Pdec).