Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \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 functor derives additional facts from MSetInterface.S. These facts are mainly the specifications of MSetInterface.S written using different styles: equivalence and boolean equalities. Moreover, we prove that E.Eq and Equal are setoid equalities.
Require Import DecidableTypeEx.
Require Export MSetInterface.
Set Implicit Arguments.
Unset Strict Implicit.
First, a functor for Weak Sets in functorial version.
Module WFactsOn (Import E : DecidableType)(Import M : WSetsOn E).

Notation eq_dec := E.eq_dec.
Definition eqb x y := if eq_dec x y then true else false.

Specifications written using implications :

this used to be the default interface.
Section ImplSpec.
Variable s s' : t.
Variable x y : elt.

s, s':t
x, y:elt

E.eq x y -> In x s -> In y s
s, s':t
x, y:elt

E.eq x y -> In x s -> In y s
intros E; rewrite E; auto. Qed.
s, s':t
x, y:elt

In x s -> mem x s = true
s, s':t
x, y:elt

In x s -> mem x s = true
intros; apply <- mem_spec; auto. Qed.
s, s':t
x, y:elt

mem x s = true -> In x s
s, s':t
x, y:elt

mem x s = true -> In x s
intros; apply -> mem_spec; auto. Qed.
s, s':t
x, y:elt

s [=] s' -> equal s s' = true
s, s':t
x, y:elt

s [=] s' -> equal s s' = true
intros; apply <- equal_spec; auto. Qed.
s, s':t
x, y:elt

equal s s' = true -> s [=] s'
s, s':t
x, y:elt

equal s s' = true -> s [=] s'
intros; apply -> equal_spec; auto. Qed.
s, s':t
x, y:elt

s [<=] s' -> subset s s' = true
s, s':t
x, y:elt

s [<=] s' -> subset s s' = true
intros; apply <- subset_spec; auto. Qed.
s, s':t
x, y:elt

subset s s' = true -> s [<=] s'
s, s':t
x, y:elt

subset s s' = true -> s [<=] s'
intros; apply -> subset_spec; auto. Qed.
s, s':t
x, y:elt

Empty s -> is_empty s = true
s, s':t
x, y:elt

Empty s -> is_empty s = true
intros; apply <- is_empty_spec; auto. Qed.
s, s':t
x, y:elt

is_empty s = true -> Empty s
s, s':t
x, y:elt

is_empty s = true -> Empty s
intros; apply -> is_empty_spec; auto. Qed.
s, s':t
x, y:elt

E.eq x y -> In y (add x s)
s, s':t
x, y:elt

E.eq x y -> In y (add x s)
s, s':t
x, y:elt
H:E.eq x y

E.eq y x \/ In y s
auto with relations. Qed.
s, s':t
x, y:elt

In y s -> In y (add x s)
s, s':t
x, y:elt

In y s -> In y (add x s)
intros; apply <- add_spec; auto. Qed.
s, s':t
x, y:elt

~ E.eq x y -> In y (add x s) -> In y s
s, s':t
x, y:elt

~ E.eq x y -> In y (add x s) -> In y s
s, s':t
x, y:elt

~ E.eq x y -> E.eq y x \/ In y s -> In y s
s, s':t
x, y:elt
H:~ E.eq x y
H':E.eq y x

In y s
elim H; auto with relations. Qed.
s, s':t
x, y:elt

E.eq x y -> ~ In y (remove x s)
s, s':t
x, y:elt

E.eq x y -> ~ In y (remove x s)
intros; rewrite remove_spec; intuition. Qed.
s, s':t
x, y:elt

~ E.eq x y -> In y s -> In y (remove x s)
s, s':t
x, y:elt

~ E.eq x y -> In y s -> In y (remove x s)
intros; apply <- remove_spec; auto with relations. Qed.
s, s':t
x, y:elt

In y (remove x s) -> In y s
s, s':t
x, y:elt

In y (remove x s) -> In y s
rewrite remove_spec; intuition. Qed.
s, s':t
x, y:elt

In y (singleton x) -> E.eq x y
s, s':t
x, y:elt

In y (singleton x) -> E.eq x y
rewrite singleton_spec; auto with relations. Qed.
s, s':t
x, y:elt

E.eq x y -> In y (singleton x)
s, s':t
x, y:elt

E.eq x y -> In y (singleton x)
rewrite singleton_spec; auto with relations. Qed.
s, s':t
x, y:elt

In x (union s s') -> In x s \/ In x s'
s, s':t
x, y:elt

In x (union s s') -> In x s \/ In x s'
rewrite union_spec; auto. Qed.
s, s':t
x, y:elt

In x s -> In x (union s s')
s, s':t
x, y:elt

In x s -> In x (union s s')
rewrite union_spec; auto. Qed.
s, s':t
x, y:elt

In x s' -> In x (union s s')
s, s':t
x, y:elt

In x s' -> In x (union s s')
rewrite union_spec; auto. Qed.
s, s':t
x, y:elt

In x (inter s s') -> In x s
s, s':t
x, y:elt

In x (inter s s') -> In x s
rewrite inter_spec; intuition. Qed.
s, s':t
x, y:elt

In x (inter s s') -> In x s'
s, s':t
x, y:elt

In x (inter s s') -> In x s'
rewrite inter_spec; intuition. Qed.
s, s':t
x, y:elt

In x s -> In x s' -> In x (inter s s')
s, s':t
x, y:elt

In x s -> In x s' -> In x (inter s s')
rewrite inter_spec; intuition. Qed.
s, s':t
x, y:elt

In x (diff s s') -> In x s
s, s':t
x, y:elt

In x (diff s s') -> In x s
rewrite diff_spec; intuition. Qed.
s, s':t
x, y:elt

In x (diff s s') -> ~ In x s'
s, s':t
x, y:elt

In x (diff s s') -> ~ In x s'
rewrite diff_spec; intuition. Qed.
s, s':t
x, y:elt

In x s -> ~ In x s' -> In x (diff s s')
s, s':t
x, y:elt

In x s -> ~ In x s' -> In x (diff s s')
rewrite diff_spec; auto. Qed. Variable f : elt -> bool. Notation compatb := (Proper (E.eq==>Logic.eq)) (only parsing).
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> In x (filter f s) -> In x s
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> In x (filter f s) -> In x s
intros P; rewrite filter_spec; intuition. Qed.
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> In x (filter f s) -> f x = true
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> In x (filter f s) -> f x = true
intros P; rewrite filter_spec; intuition. Qed.
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> In x s -> f x = true -> In x (filter f s)
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> In x s -> f x = true -> In x (filter f s)
intros P; rewrite filter_spec; intuition. Qed.
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s -> for_all f s = true
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s -> for_all f s = true
intros; apply <- for_all_spec; auto. Qed.
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> for_all f s = true -> For_all (fun x0 : elt => f x0 = true) s
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> for_all f s = true -> For_all (fun x0 : elt => f x0 = true) s
intros; apply -> for_all_spec; auto. Qed.
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s -> exists_ f s = true
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s -> exists_ f s = true
intros; apply <- exists_spec; auto. Qed.
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> exists_ f s = true -> Exists (fun x0 : elt => f x0 = true) s
s, s':t
x, y:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> exists_ f s = true -> Exists (fun x0 : elt => f x0 = true) s
intros; apply -> exists_spec; auto. Qed.
s, s':t
x, y:elt
f:elt -> bool

In x s -> InA E.eq x (elements s)
s, s':t
x, y:elt
f:elt -> bool

In x s -> InA E.eq x (elements s)
intros; apply <- elements_spec1; auto. Qed.
s, s':t
x, y:elt
f:elt -> bool

InA E.eq x (elements s) -> In x s
s, s':t
x, y:elt
f:elt -> bool

InA E.eq x (elements s) -> In x s
intros; apply -> elements_spec1; auto. Qed. End ImplSpec. Notation empty_1 := empty_spec (only parsing). Notation fold_1 := fold_spec (only parsing). Notation cardinal_1 := cardinal_spec (only parsing). Notation partition_1 := partition_spec1 (only parsing). Notation partition_2 := partition_spec2 (only parsing). Notation choose_1 := choose_spec1 (only parsing). Notation choose_2 := choose_spec2 (only parsing). Notation elements_3w := elements_spec2w (only parsing). Hint Resolve mem_1 equal_1 subset_1 empty_1 is_empty_1 choose_1 choose_2 add_1 add_2 remove_1 remove_2 singleton_2 union_1 union_2 union_3 inter_3 diff_3 fold_1 filter_3 for_all_1 exists_1 partition_1 partition_2 elements_1 elements_3w : set. Hint Immediate In_1 mem_2 equal_2 subset_2 is_empty_2 add_3 remove_3 singleton_1 inter_1 inter_2 diff_1 diff_2 filter_1 filter_2 for_all_2 exists_2 elements_2 : set.

Specifications written using equivalences :

this is now provided by the default interface.
Section IffSpec.
Variable s s' s'' : t.
Variable x y z : elt.

s, s', s'':t
x, y, z:elt

E.eq x y -> In x s <-> In y s
s, s', s'':t
x, y, z:elt

E.eq x y -> In x s <-> In y s
intros E; rewrite E; intuition. Qed.
s, s', s'':t
x, y, z:elt

In x s <-> mem x s = true
s, s', s'':t
x, y, z:elt

In x s <-> mem x s = true
apply iff_sym, mem_spec. Qed.
s, s', s'':t
x, y, z:elt

~ In x s <-> mem x s = false
s, s', s'':t
x, y, z:elt

~ In x s <-> mem x s = false
rewrite <-mem_spec; destruct (mem x s); intuition. Qed.
s, s', s'':t
x, y, z:elt

s [=] s' <-> equal s s' = true
s, s', s'':t
x, y, z:elt

s [=] s' <-> equal s s' = true
apply iff_sym, equal_spec. Qed.
s, s', s'':t
x, y, z:elt

s [<=] s' <-> subset s s' = true
s, s', s'':t
x, y, z:elt

s [<=] s' <-> subset s s' = true
apply iff_sym, subset_spec. Qed.
s, s', s'':t
x, y, z:elt

In x empty <-> False
s, s', s'':t
x, y, z:elt

In x empty <-> False
intuition; apply (empty_spec H). Qed.
s, s', s'':t
x, y, z:elt

Empty s <-> is_empty s = true
s, s', s'':t
x, y, z:elt

Empty s <-> is_empty s = true
apply iff_sym, is_empty_spec. Qed.
s, s', s'':t
x, y, z:elt

In y (singleton x) <-> E.eq x y
s, s', s'':t
x, y, z:elt

In y (singleton x) <-> E.eq x y
rewrite singleton_spec; intuition. Qed.
s, s', s'':t
x, y, z:elt

In y (add x s) <-> E.eq x y \/ In y s
s, s', s'':t
x, y, z:elt

In y (add x s) <-> E.eq x y \/ In y s
rewrite add_spec; intuition. Qed.
s, s', s'':t
x, y, z:elt

~ E.eq x y -> In y (add x s) <-> In y s
s, s', s'':t
x, y, z:elt

~ E.eq x y -> In y (add x s) <-> In y s
s, s', s'':t
x, y, z:elt
H:E.eq x y -> False
H1:E.eq y x

In y s
elim H; auto with relations. Qed.
s, s', s'':t
x, y, z:elt

In y (remove x s) <-> In y s /\ ~ E.eq x y
s, s', s'':t
x, y, z:elt

In y (remove x s) <-> In y s /\ ~ E.eq x y
rewrite remove_spec; intuition. Qed.
s, s', s'':t
x, y, z:elt

~ E.eq x y -> In y (remove x s) <-> In y s
s, s', s'':t
x, y, z:elt

~ E.eq x y -> In y (remove x s) <-> In y s
rewrite remove_spec; intuition. Qed. Variable f : elt -> bool.
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = true
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = true
intros; apply iff_sym, for_all_spec; auto. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = true
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = true
intros; apply iff_sym, exists_spec; auto. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

In x s <-> InA E.eq x (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool

In x s <-> InA E.eq x (elements s)
apply iff_sym, elements_spec1. Qed. End IffSpec. Notation union_iff := union_spec (only parsing). Notation inter_iff := inter_spec (only parsing). Notation diff_iff := diff_spec (only parsing). Notation filter_iff := filter_spec (only parsing).
Useful tactic for simplifying expressions like In y (add x (union s s'))
Ltac set_iff :=
 repeat (progress (
  rewrite add_iff || rewrite remove_iff || rewrite singleton_iff
  || rewrite union_iff || rewrite inter_iff || rewrite diff_iff
  || rewrite empty_iff)).

Specifications written using boolean predicates

Section BoolSpec.
Variable s s' s'' : t.
Variable x y z : elt.

s, s', s'':t
x, y, z:elt

E.eq x y -> mem x s = mem y s
s, s', s'':t
x, y, z:elt

E.eq x y -> mem x s = mem y s
s, s', s'':t
x, y, z:elt
H:E.eq x y

mem x s = mem y s
s, s', s'':t
x, y, z:elt
H:E.eq x y

In x s <-> mem x s = true -> In y s <-> mem y s = true -> In x s <-> In y s -> mem x s = mem y s
destruct (mem x s); destruct (mem y s); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem y empty = false
s, s', s'':t
x, y, z:elt

mem y empty = false
s, s', s'':t
x, y, z:elt

In y empty <-> False -> In y empty <-> mem y empty = true -> mem y empty = false
destruct (mem y empty); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem y (add x s) = eqb x y || mem y s
s, s', s'':t
x, y, z:elt

mem y (add x s) = eqb x y || mem y s
s, s', s'':t
x, y, z:elt

In y (add x s) <-> mem y (add x s) = true -> In y s <-> mem y s = true -> In y (add x s) <-> E.eq x y \/ In y s -> mem y (add x s) = (if eq_dec x y then true else false) || mem y s
destruct (eq_dec x y); destruct (mem y s); destruct (mem y (add x s)); intuition. Qed.
s, s', s'':t
x, y, z:elt

~ E.eq x y -> mem y (add x s) = mem y s
s, s', s'':t
x, y, z:elt

~ E.eq x y -> mem y (add x s) = mem y s
s, s', s'':t
x, y, z:elt
H:~ E.eq x y

In y (add x s) <-> mem y (add x s) = true -> In y s <-> mem y s = true -> In y (add x s) <-> In y s -> mem y (add x s) = mem y s
destruct (mem y s); destruct (mem y (add x s)); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem y (remove x s) = mem y s && negb (eqb x y)
s, s', s'':t
x, y, z:elt

mem y (remove x s) = mem y s && negb (eqb x y)
s, s', s'':t
x, y, z:elt

In y (remove x s) <-> mem y (remove x s) = true -> In y s <-> mem y s = true -> In y (remove x s) <-> In y s /\ ~ E.eq x y -> mem y (remove x s) = mem y s && negb (if eq_dec x y then true else false)
destruct (eq_dec x y); destruct (mem y s); destruct (mem y (remove x s)); simpl; intuition. Qed.
s, s', s'':t
x, y, z:elt

~ E.eq x y -> mem y (remove x s) = mem y s
s, s', s'':t
x, y, z:elt

~ E.eq x y -> mem y (remove x s) = mem y s
s, s', s'':t
x, y, z:elt
H:~ E.eq x y

In y (remove x s) <-> mem y (remove x s) = true -> In y s <-> mem y s = true -> In y (remove x s) <-> In y s -> mem y (remove x s) = mem y s
destruct (mem y s); destruct (mem y (remove x s)); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem y (singleton x) = eqb x y
s, s', s'':t
x, y, z:elt

mem y (singleton x) = eqb x y
s, s', s'':t
x, y, z:elt

In y (singleton x) <-> mem y (singleton x) = true -> In y (singleton x) <-> E.eq x y -> mem y (singleton x) = (if eq_dec x y then true else false)
destruct (eq_dec x y); destruct (mem y (singleton x)); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem x (union s s') = mem x s || mem x s'
s, s', s'':t
x, y, z:elt

mem x (union s s') = mem x s || mem x s'
s, s', s'':t
x, y, z:elt

In x (union s s') <-> mem x (union s s') = true -> In x s <-> mem x s = true -> In x s' <-> mem x s' = true -> In x (union s s') <-> In x s \/ In x s' -> mem x (union s s') = mem x s || mem x s'
destruct (mem x s); destruct (mem x s'); destruct (mem x (union s s')); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem x (inter s s') = mem x s && mem x s'
s, s', s'':t
x, y, z:elt

mem x (inter s s') = mem x s && mem x s'
s, s', s'':t
x, y, z:elt

In x (inter s s') <-> mem x (inter s s') = true -> In x s <-> mem x s = true -> In x s' <-> mem x s' = true -> In x (inter s s') <-> In x s /\ In x s' -> mem x (inter s s') = mem x s && mem x s'
destruct (mem x s); destruct (mem x s'); destruct (mem x (inter s s')); intuition. Qed.
s, s', s'':t
x, y, z:elt

mem x (diff s s') = mem x s && negb (mem x s')
s, s', s'':t
x, y, z:elt

mem x (diff s s') = mem x s && negb (mem x s')
s, s', s'':t
x, y, z:elt

In x (diff s s') <-> mem x (diff s s') = true -> In x s <-> mem x s = true -> In x s' <-> mem x s' = true -> In x (diff s s') <-> In x s /\ ~ In x s' -> mem x (diff s s') = mem x s && negb (mem x s')
destruct (mem x s); destruct (mem x s'); destruct (mem x (diff s s')); simpl; intuition. Qed.
s, s', s'':t
x, y, z:elt

mem x s = existsb (eqb x) (elements s)
s, s', s'':t
x, y, z:elt

mem x s = existsb (eqb x) (elements s)
s, s', s'':t
x, y, z:elt

In x s <-> mem x s = true -> In x s <-> InA E.eq x (elements s) -> existsb (eqb x) (elements s) = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true) -> mem x s = existsb (eqb x) (elements s)
s, s', s'':t
x, y, z:elt

In x s <-> mem x s = true -> In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)) -> existsb (eqb x) (elements s) = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true) -> mem x s = existsb (eqb x) (elements s)
s, s', s'':t
x, y, z:elt
H:In x s <-> true = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:false = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

true = false
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> true = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:false = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> true = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:false = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> true = true
H0:In x s -> exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)
H1:false = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> true = true
H1:false = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
a:E.t
Ha1:E.eq x a
Ha2:List.In a (elements s)

exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
false = true
s, s', s'':t
x, y, z:elt
a:E.t
Ha1:E.eq x a
Ha2:List.In a (elements s)
H:false = true -> exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true
H3:(exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true) -> false = true
H1:In x s
H2:true = true

eqb x a = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)
false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

false = true
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

In x s
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)

exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
H1:true = true -> exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true

exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)
s, s', s'':t
x, y, z:elt
H:In x s <-> false = true
H0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))
a:E.t
Ha1:List.In a (elements s)
Ha2:eqb x a = true

exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)
s, s', s'':t
x, y, z:elt
a:E.t
Ha1:List.In a (elements s)
Ha2:eqb x a = true
H1:In x s -> false = true
H2:false = true -> In x s
H:In x s -> exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)
H3:(exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)) -> In x s

E.eq x a
unfold eqb in *; destruct (eq_dec x a); auto; discriminate. Qed. Variable f : elt->bool.
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> mem x (filter f s) = mem x s && f x
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> mem x (filter f s) = mem x s && f x
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

mem x (filter f s) = mem x s && f x
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

In x (filter f s) <-> mem x (filter f s) = true -> In x s <-> mem x s = true -> In x (filter f s) <-> In x s /\ f x = true -> mem x (filter f s) = mem x s && f x
destruct (mem x s); destruct (mem x (filter f s)); destruct (f x); simpl; intuition. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> for_all f s = forallb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> for_all f s = forallb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

for_all f s = forallb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

forallb f (elements s) = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true) -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = true -> (forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)) -> for_all f s = forallb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

forallb f (elements s) = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true) -> (forall x0 : elt, In x0 s -> f x0 = true) <-> for_all f s = true -> (forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)) -> for_all f s = forallb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> false = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

false = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:In x0 s

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = true
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:In x0 s

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = true
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:InA E.eq x0 (elements s)

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = true
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:exists y0 : E.t, E.eq x0 y0 /\ List.In y0 (elements s)

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = true
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
a:E.t
Ha1:E.eq x0 a
Ha2:List.In a (elements s)

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = true
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
a:E.t
Ha1:E.eq x0 a
Ha2:List.In a (elements s)

f a = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)
H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

false = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)
H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> true = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:List.In x0 (elements s)

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)
H1:true = true -> forall x1 : elt, In x1 s -> f x1 = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:List.In x0 (elements s)

f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)
H1:true = true -> forall x1 : elt, In x1 s -> f x1 = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:List.In x0 (elements s)

In x0 s
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)
H1:true = true -> forall x1 : elt, In x1 s -> f x1 = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:List.In x0 (elements s)

InA E.eq x0 (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)
H1:true = true -> forall x1 : elt, In x1 s -> f x1 = true
H2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)
x0:elt
H3:List.In x0 (elements s)

exists y0 : E.t, E.eq x0 y0 /\ List.In y0 (elements s)
exists x0; split; auto with relations. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> exists_ f s = existsb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool

Proper (E.eq ==> Logic.eq) f -> exists_ f s = existsb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

exists_ f s = existsb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

existsb f (elements s) = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true) -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = true -> (forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)) -> exists_ f s = existsb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f

existsb f (elements s) = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true) -> (exists x0 : elt, In x0 s /\ f x0 = true) <-> exists_ f s = true -> (forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)) -> exists_ f s = existsb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

false = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

exists x0 : elt, In x0 s /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:true = true -> exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

exists x0 : elt, In x0 s /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
Ha1:List.In a (elements s)
Ha2:f a = true

exists x0 : elt, In x0 s /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
Ha1:List.In a (elements s)
Ha2:f a = true

In a s
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

true = false
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

false = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H1:true = true -> exists x0 : elt, In x0 s /\ f x0 = true
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)

exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
Ha1:In a s
Ha2:f a = true

exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
Ha1:InA E.eq a (elements s)
Ha2:f a = true

exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
Ha1:exists y0 : E.t, E.eq a y0 /\ List.In y0 (elements s)
Ha2:f a = true

exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
b:E.t
Hb1:E.eq a b
Hb2:List.In b (elements s)
Ha2:f a = true

exists x0 : elt, List.In x0 (elements s) /\ f x0 = true
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:Proper (E.eq ==> Logic.eq) f
H0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)
H2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)
a:elt
b:E.t
Hb1:E.eq a b
Hb2:List.In b (elements s)
Ha2:f a = true

List.In b (elements s) /\ f b = true
rewrite <- (H _ _ Hb1); auto. Qed. End BoolSpec.

Declarations of morphisms with respects to E.eq and Equal


Proper (E.eq ==> Equal ==> iff) In

Proper (E.eq ==> Equal ==> iff) In
x, y:E.t
H:E.eq x y
s, s':t
H0:forall a : elt, In a s <-> In a s'

In x s <-> In y s'
rewrite (In_eq_iff s H); auto. Qed.

Proper (Equal ==> iff) Empty

Proper (Equal ==> iff) Empty
s, s':t
E:s [=] s'

((forall a : elt, ~ In a s) -> forall a : elt, ~ In a s') /\ ((forall a : elt, ~ In a s') -> forall a : elt, ~ In a s)
setoid_rewrite E; auto. Qed.

Proper (Equal ==> Logic.eq) is_empty

Proper (Equal ==> Logic.eq) is_empty
s, s':t
H:s [=] s'

is_empty s = is_empty s'
s, s':t
H:s [=] s'

Empty s <-> is_empty s = true -> is_empty s = is_empty s'
s, s':t
H:s [=] s'

Empty s' <-> is_empty s = true -> is_empty s = is_empty s'
s, s':t
H:s [=] s'

is_empty s' = true <-> is_empty s = true -> is_empty s = is_empty s'
destruct (is_empty s); destruct (is_empty s'); intuition. Qed.

Proper (E.eq ==> Equal ==> Logic.eq) mem

Proper (E.eq ==> Equal ==> Logic.eq) mem
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [=] s'

mem x s = mem x' s'
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [=] s'

In x s <-> mem x s = true -> mem x s = mem x' s'
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [=] s'

mem x' s' = true <-> mem x s = true -> mem x s = mem x' s'
destruct (mem x s), (mem x' s'); intuition. Qed.

Proper (E.eq ==> Equal) singleton

Proper (E.eq ==> Equal) singleton
x, y:E.t
H:E.eq x y
a:elt

In a (singleton x) <-> In a (singleton y)
rewrite !singleton_iff, H; intuition. Qed.

Proper (E.eq ==> Equal ==> Equal) add

Proper (E.eq ==> Equal ==> Equal) add
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [=] s'
a:elt

In a (add x s) <-> In a (add x' s')
rewrite !add_iff, Hx, Hs; intuition. Qed.

Proper (E.eq ==> Equal ==> Equal) remove

Proper (E.eq ==> Equal ==> Equal) remove
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [=] s'
a:elt

In a (remove x s) <-> In a (remove x' s')
rewrite !remove_iff, Hx, Hs; intuition. Qed.

Proper (Equal ==> Equal ==> Equal) union

Proper (Equal ==> Equal ==> Equal) union
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'
a:elt

In a (union s1 s2) <-> In a (union s1' s2')
rewrite !union_iff, Hs1, Hs2; intuition. Qed.

Proper (Equal ==> Equal ==> Equal) inter

Proper (Equal ==> Equal ==> Equal) inter
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'
a:elt

In a (inter s1 s2) <-> In a (inter s1' s2')
rewrite !inter_iff, Hs1, Hs2; intuition. Qed.

Proper (Equal ==> Equal ==> Equal) diff

Proper (Equal ==> Equal ==> Equal) diff
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'
a:elt

In a (diff s1 s2) <-> In a (diff s1' s2')
rewrite !diff_iff, Hs1, Hs2; intuition. Qed.

Proper (Equal ==> Equal ==> iff) Subset

Proper (Equal ==> Equal ==> iff) Subset
unfold Equal, Subset; firstorder. Qed.

Proper (Equal ==> Equal ==> Logic.eq) subset

Proper (Equal ==> Equal ==> Logic.eq) subset
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

subset s1 s2 = subset s1' s2'
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

s1 [<=] s2 <-> subset s1 s2 = true -> subset s1 s2 = subset s1' s2'
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

s1' [<=] s2' <-> subset s1 s2 = true -> subset s1 s2 = subset s1' s2'
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

subset s1' s2' = true <-> subset s1 s2 = true -> subset s1 s2 = subset s1' s2'
destruct (subset s1 s2); destruct (subset s1' s2'); intuition. Qed.

Proper (Equal ==> Equal ==> Logic.eq) equal

Proper (Equal ==> Equal ==> Logic.eq) equal
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

equal s1 s2 = equal s1' s2'
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

s1 [=] s2 <-> equal s1 s2 = true -> equal s1 s2 = equal s1' s2'
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

s1' [=] s2' <-> equal s1 s2 = true -> equal s1 s2 = equal s1' s2'
s1, s1':t
Hs1:s1 [=] s1'
s2, s2':t
Hs2:s2 [=] s2'

equal s1' s2' = true <-> equal s1 s2 = true -> equal s1 s2 = equal s1' s2'
destruct (equal s1 s2); destruct (equal s1' s2'); intuition. Qed.

PreOrder Subset

PreOrder Subset
firstorder. Qed. Definition Subset_refl := @PreOrder_Reflexive _ _ SubsetSetoid. Definition Subset_trans := @PreOrder_Transitive _ _ SubsetSetoid.

Proper (E.eq ==> Subset ==> impl) In

Proper (E.eq ==> Subset ==> impl) In
x, y:E.t
H:E.eq x y
x0, y0:t
H0:x0 [<=] y0
H1:In x x0

In y y0
eauto with set. Qed.

Proper (Subset --> impl) Empty

Proper (Subset --> impl) Empty
firstorder. Qed.

Proper (E.eq ==> Subset ==> Subset) add

Proper (E.eq ==> Subset ==> Subset) add
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [<=] s'
a:elt

In a (add x s) -> In a (add x' s')
rewrite !add_iff, Hx; intuition. Qed.

Proper (E.eq ==> Subset ==> Subset) remove

Proper (E.eq ==> Subset ==> Subset) remove
x, x':E.t
Hx:E.eq x x'
s, s':t
Hs:s [<=] s'
a:elt

In a (remove x s) -> In a (remove x' s')
rewrite !remove_iff, Hx; intuition. Qed.

Proper (Subset ==> Subset ==> Subset) union

Proper (Subset ==> Subset ==> Subset) union
s1, s1':t
Hs1:s1 [<=] s1'
s2, s2':t
Hs2:s2 [<=] s2'
a:elt

In a (union s1 s2) -> In a (union s1' s2')
rewrite !union_iff, Hs1, Hs2; intuition. Qed.

Proper (Subset ==> Subset ==> Subset) inter

Proper (Subset ==> Subset ==> Subset) inter
s1, s1':t
Hs1:s1 [<=] s1'
s2, s2':t
Hs2:s2 [<=] s2'
a:elt

In a (inter s1 s2) -> In a (inter s1' s2')
rewrite !inter_iff, Hs1, Hs2; intuition. Qed.

Proper (Subset ==> Subset --> Subset) diff

Proper (Subset ==> Subset --> Subset) diff
s1, s1':t
Hs1:s1 [<=] s1'
s2, s2':t
Hs2:flip Subset s2 s2'
a:elt

In a (diff s1 s2) -> In a (diff s1' s2')
rewrite !diff_iff, Hs1, Hs2; intuition. Qed. (* [fold], [filter], [for_all], [exists_] and [partition] requires some knowledge on [f] in order to be known as morphisms. *) Generalizable Variables f.

forall f : E.t -> bool, Proper (E.eq ==> Logic.eq) f -> Proper (Equal ==> Equal) (filter f)

forall f : E.t -> bool, Proper (E.eq ==> Logic.eq) f -> Proper (Equal ==> Equal) (filter f)
f:E.t -> bool
Hf:Proper (E.eq ==> Logic.eq) f
s, s':t
Hs:s [=] s'
a:elt

In a (filter f s) <-> In a (filter f s')
rewrite !filter_iff, Hs by auto; intuition. Qed.

forall f : E.t -> bool, Proper (E.eq ==> Logic.eq) f -> Proper (Subset ==> Subset) (filter f)

forall f : E.t -> bool, Proper (E.eq ==> Logic.eq) f -> Proper (Subset ==> Subset) (filter f)
f:E.t -> bool
Hf:Proper (E.eq ==> Logic.eq) f
s, s':t
Hs:s [<=] s'
a:elt

In a (filter f s) -> In a (filter f s')
rewrite !filter_iff, Hs by auto; intuition. Qed.

forall f f' : E.t -> bool, Proper (E.eq ==> Logic.eq) f -> (forall x : E.t, f x = f' x) -> forall s s' : t, s [=] s' -> filter f s [=] filter f' s'

forall f f' : E.t -> bool, Proper (E.eq ==> Logic.eq) f -> (forall x : E.t, f x = f' x) -> forall s s' : t, s [=] s' -> filter f s [=] filter f' s'
f, f':E.t -> bool
Hf:Proper (E.eq ==> Logic.eq) f
Hff':forall x0 : E.t, f x0 = f' x0
s, s':t
Hss':s [=] s'
x:elt

In x (filter f s) <-> In x (filter f' s')
f, f':E.t -> bool
Hf:Proper (E.eq ==> Logic.eq) f
Hff':forall x0 : E.t, f x0 = f' x0
s, s':t
Hss':s [=] s'
x:elt

In x s /\ f x = true <-> In x s' /\ f' x = true
f, f':E.t -> bool
Hf:Proper (E.eq ==> Logic.eq) f
Hff':forall x0 : E.t, f x0 = f' x0
s, s':t
Hss':s [=] s'
x:elt
Proper (E.eq ==> Logic.eq) f'
f, f':E.t -> bool
Hf:Proper (E.eq ==> Logic.eq) f
Hff':forall x0 : E.t, f x0 = f' x0
s, s':t
Hss':s [=] s'
x:elt

Proper (E.eq ==> Logic.eq) f'
red; red; intros; rewrite <- 2 Hff'; auto. Qed. (* For [elements], [min_elt], [max_elt] and [choose], we would need setoid structures on [list elt] and [option elt]. *) (* Later: Add Morphism cardinal ; cardinal_m. *) End WFactsOn.
Now comes variants for self-contained weak sets and for full sets. For these variants, only one argument is necessary. Thanks to the subtyping WS≤S, the Facts functor which is meant to be used on modules (M:S) can simply be an alias of WFacts.
Module WFacts (M:WSets) := WFactsOn M.E M.
Module Facts := WFacts.