Require Import FSetInterface.
Set Implicit Arguments.
Unset Strict Implicit.
Module Type S.
Declare Module E : OrderedType.
Definition elt := E.t.
Parameter t : Set.
Parameter In : elt -> t -> Prop.
Definition Equal s s' := forall a : elt, In a s <-> In a s'.
Definition Subset s s' := forall a : elt, In a s -> In a s'.
Definition Empty s := forall a : elt, ~ In a s.
Definition For_all (P : elt -> Prop) s := forall x, In x s -> P x.
Definition Exists (P : elt -> Prop) s := exists x, In x s /\ P x.
Notation "s [=] t" := (Equal s t) (at level 70, no associativity).
Notation "s [<=] t" := (Subset s t) (at level 70, no associativity).
Parameter empty : t.
Parameter is_empty : t -> bool.
Parameter mem : elt -> t -> bool.
Parameter add : elt -> t -> t.
Parameter singleton : elt -> t.
Parameter remove : elt -> t -> t.
Parameter union : t -> t -> t.
Parameter inter : t -> t -> t.
Parameter diff : t -> t -> t.
Definition eq : t -> t -> Prop := Equal.
Parameter lt : t -> t -> Prop.
Parameter compare : forall s s' : t, Compare lt eq s s'.
Parameter equal : t -> t -> bool.
Parameter subset : t -> t -> bool.
Parameter fold : forall A : Set, (elt -> A -> A) -> t -> A -> A.
Parameter for_all : (elt -> bool) -> t -> bool.
Parameter exists_ : (elt -> bool) -> t -> bool.
Parameter filter : (elt -> bool) -> t -> t.
Parameter partition : (elt -> bool) -> t -> t * t.
Parameter cardinal : t -> nat.
Parameter elements : t -> list elt.
Parameter min_elt : t -> option elt.
Parameter max_elt : t -> option elt.
Parameter choose : t -> option elt.
Section Spec.
Variable s s' s'' : t.
Variable x y : elt.
Parameter In_1 : E.eq x y -> In x s -> In y s.
Parameter eq_refl : eq s s.
Parameter eq_sym : eq s s' -> eq s' s.
Parameter eq_trans : eq s s' -> eq s' s'' -> eq s s''.
Parameter lt_trans : lt s s' -> lt s' s'' -> lt s s''.
Parameter lt_not_eq : lt s s' -> ~ eq s s'.
Parameter mem_1 : In x s -> mem x s = true.
Parameter mem_2 : mem x s = true -> In x s.
Parameter equal_1 : s[=]s' -> equal s s' = true.
Parameter equal_2 : equal s s' = true ->s[=]s'.
Parameter subset_1 : s[<=]s' -> subset s s' = true.
Parameter subset_2 : subset s s' = true -> s[<=]s'.
Parameter empty_1 : Empty empty.
Parameter is_empty_1 : Empty s -> is_empty s = true.
Parameter is_empty_2 : is_empty s = true -> Empty s.
Parameter add_1 : E.eq x y -> In y (add x s).
Parameter add_2 : In y s -> In y (add x s).
Parameter add_3 : ~ E.eq x y -> In y (add x s) -> In y s.
Parameter remove_1 : E.eq x y -> ~ In y (remove x s).
Parameter remove_2 : ~ E.eq x y -> In y s -> In y (remove x s).
Parameter remove_3 : In y (remove x s) -> In y s.
Parameter singleton_1 : In y (singleton x) -> E.eq x y.
Parameter singleton_2 : E.eq x y -> In y (singleton x).
Parameter union_1 : In x (union s s') -> In x s \/ In x s'.
Parameter union_2 : In x s -> In x (union s s').
Parameter union_3 : In x s' -> In x (union s s').
Parameter inter_1 : In x (inter s s') -> In x s.
Parameter inter_2 : In x (inter s s') -> In x s'.
Parameter inter_3 : In x s -> In x s' -> In x (inter s s').
Parameter diff_1 : In x (diff s s') -> In x s.
Parameter diff_2 : In x (diff s s') -> ~ In x s'.
Parameter diff_3 : In x s -> ~ In x s' -> In x (diff s s').
Parameter fold_1 : forall (A : Set) (i : A) (f : elt -> A -> A),
fold f s i = fold_left (fun a e => f e a) (elements s) i.
Parameter cardinal_1 : cardinal s = length (elements s).
Section Filter.
Variable f : elt -> bool.
Parameter filter_1 : compat_bool E.eq f -> In x (filter f s) -> In x s.
Parameter filter_2 : compat_bool E.eq f -> In x (filter f s) -> f x = true.
Parameter filter_3 :
compat_bool E.eq f -> In x s -> f x = true -> In x (filter f s).
Parameter for_all_1 :
compat_bool E.eq f ->
For_all (fun x => f x = true) s -> for_all f s = true.
Parameter for_all_2 :
compat_bool E.eq f ->
for_all f s = true -> For_all (fun x => f x = true) s.
Parameter exists_1 :
compat_bool E.eq f ->
Exists (fun x => f x = true) s -> exists_ f s = true.
Parameter exists_2 :
compat_bool E.eq f ->
exists_ f s = true -> Exists (fun x => f x = true) s.
Parameter partition_1 : compat_bool E.eq f ->
fst (partition f s) [=] filter f s.
Parameter partition_2 : compat_bool E.eq f ->
snd (partition f s) [=] filter (fun x => negb (f x)) s.
End Filter.
Parameter elements_1 : In x s -> InA E.eq x (elements s).
Parameter elements_2 : InA E.eq x (elements s) -> In x s.
Parameter elements_3 : sort E.lt (elements s).
Parameter min_elt_1 : min_elt s = Some x -> In x s.
Parameter min_elt_2 : min_elt s = Some x -> In y s -> ~ E.lt y x.
Parameter min_elt_3 : min_elt s = None -> Empty s.
Parameter max_elt_1 : max_elt s = Some x -> In x s.
Parameter max_elt_2 : max_elt s = Some x -> In y s -> ~ E.lt x y.
Parameter max_elt_3 : max_elt s = None -> Empty s.
Parameter choose_1 : choose s = Some x -> In x s.
Parameter choose_2 : choose s = None -> Empty s.
End Spec.
Hint Immediate In_1.
Hint Resolve mem_1 mem_2 equal_1 equal_2 subset_1 subset_2 empty_1
is_empty_1 is_empty_2 choose_1 choose_2 add_1 add_2 add_3 remove_1
remove_2 remove_3 singleton_1 singleton_2 union_1 union_2 union_3 inter_1
inter_2 inter_3 diff_1 diff_2 diff_3 filter_1 filter_2 filter_3 for_all_1
for_all_2 exists_1 exists_2 partition_1 partition_2 elements_1 elements_2
elements_3 min_elt_1 min_elt_2 min_elt_3 max_elt_1 max_elt_2 max_elt_3
: sets.
End S.