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 FSetInterface.S. These facts are mainly the specifications of FSetInterface.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 FSetInterface.
Set Implicit Arguments.
Unset Strict Implicit.
First, a functor for Weak Sets in functorial version.
Module WFacts_fun (Import E : DecidableType)(Import M : WSfun E).

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

Specifications written using equivalences

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
split; apply In_1; auto. 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
split; [apply mem_1|apply mem_2]. 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_iff; 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
split; [apply equal_1|apply equal_2]. 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
split; [apply subset_1|apply subset_2]. 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_1 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
split; [apply is_empty_1|apply is_empty_2]. 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
split; [apply singleton_1|apply singleton_2]. 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
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
E:~ E.eq x y

In y (add x s) -> E.eq x y \/ In y s
intro H; right; exact (add_3 E H). 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
split; [apply add_3|apply add_2]; auto. 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
s, s', s'':t
x, y, z:elt
H:In y (remove x s)

~ E.eq x y
s, s', s'':t
x, y, z:elt
H:In y (remove x s)
H0:E.eq x y

False
apply (remove_1 H0 H). 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
split; [apply remove_3|apply remove_2]; auto. Qed.
s, s', s'':t
x, y, z:elt

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

In x (union s s') <-> In x s \/ In x s'
split; [apply union_1 | destruct 1; [apply union_2|apply union_3]]; auto. Qed.
s, s', s'':t
x, y, z:elt

In x (inter s s') <-> In x s /\ In x s'
s, s', s'':t
x, y, z:elt

In x (inter s s') <-> In x s /\ In x s'
split; [split; [apply inter_1 with s' | apply inter_2 with s] | destruct 1; apply inter_3]; auto. Qed.
s, s', s'':t
x, y, z:elt

In x (diff s s') <-> In x s /\ ~ In x s'
s, s', s'':t
x, y, z:elt

In x (diff s s') <-> In x s /\ ~ In x s'
split; [split; [apply diff_1 with s' | apply diff_2 with s] | destruct 1; apply diff_3]; auto. Qed. Variable f : elt->bool.
s, s', s'':t
x, y, z:elt
f:elt -> bool

compat_bool E.eq f -> In x (filter f s) <-> In x s /\ f x = true
s, s', s'':t
x, y, z:elt
f:elt -> bool

compat_bool E.eq f -> In x (filter f s) <-> In x s /\ f x = true
split; [split; [apply filter_1 with f | apply filter_2 with s] | destruct 1; apply filter_3]; auto. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

compat_bool E.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

compat_bool E.eq f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = true
split; [apply for_all_1 | apply for_all_2]; auto. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

compat_bool E.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

compat_bool E.eq f -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = true
split; [apply exists_1 | apply exists_2]; 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)
split; [apply elements_1 | apply elements_2]. Qed. End IffSpec.
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

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

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

mem x (filter f s) = mem x s && f x
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:compat_bool E.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

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

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

for_all f s = forallb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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)
rewrite InA_alt; eauto. Qed.
s, s', s'':t
x, y, z:elt
f:elt -> bool

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

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

exists_ f s = existsb f (elements s)
s, s', s'':t
x, y, z:elt
f:elt -> bool
H:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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.

E.eq and Equal are setoid equalities


Equivalence E.eq

Equivalence E.eq
constructor ; red; [apply E.eq_refl|apply E.eq_sym|apply E.eq_trans]. Qed.

Equivalence Equal

Equivalence Equal
constructor ; red; [apply eq_refl | apply eq_sym | apply eq_trans]. Qed.

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 ==> Logic.eq) is_empty

Proper (Equal ==> Logic.eq) is_empty
s, s':t
H:forall a : elt, In a s <-> In a s'

is_empty s = is_empty s'
s, s':t
H:forall a : elt, In a s <-> In a s'

Empty s <-> is_empty s = true -> Empty s' <-> is_empty s' = true -> is_empty s = is_empty s'
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> true = true
H1:(forall a : elt, ~ In a s') <-> false = true

true = false
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> false = true
H1:(forall a : elt, ~ In a s') <-> true = true
false = true
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> true = true
H1:(forall a : elt, ~ In a s') <-> false = true

false = true
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> false = true
H1:(forall a : elt, ~ In a s') <-> true = true
false = true
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
H0:(forall a0 : elt, ~ In a0 s) <-> true = true
H1:(forall a0 : elt, ~ In a0 s') <-> false = true
a:elt
Ha:In a s'

False
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> false = true
H1:(forall a : elt, ~ In a s') <-> true = true
false = true
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
H0:(forall a0 : elt, ~ In a0 s) <-> true = true
H1:(forall a0 : elt, ~ In a0 s') <-> false = true
a:elt
Ha:In a s

False
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> false = true
H1:(forall a : elt, ~ In a s') <-> true = true
false = true
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
H0:true = true -> forall a0 : elt, ~ In a0 s
H1:(forall a0 : elt, ~ In a0 s') <-> false = true
a:elt
Ha:In a s

False
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> false = true
H1:(forall a : elt, ~ In a s') <-> true = true
false = true
s, s':t
H:forall a : elt, In a s <-> In a s'
H0:(forall a : elt, ~ In a s) <-> false = true
H1:(forall a : elt, ~ In a s') <-> true = true

false = true
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
H0:(forall a0 : elt, ~ In a0 s) <-> false = true
H1:(forall a0 : elt, ~ In a0 s') <-> true = true
a:elt
Ha:In a s

False
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
H0:(forall a0 : elt, ~ In a0 s) <-> false = true
H1:(forall a0 : elt, ~ In a0 s') <-> true = true
a:elt
Ha:In a s'

False
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
H0:(forall a0 : elt, ~ In a0 s) <-> false = true
H1:true = true -> forall a0 : elt, ~ In a0 s'
a:elt
Ha:In a s'

False
exact (H1 Logic.eq_refl _ Ha). Qed.

Proper (Equal ==> iff) Empty

Proper (Equal ==> iff) Empty
repeat red; intros; do 2 rewrite is_empty_iff; rewrite H; intuition. Qed.

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

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

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

In x s <-> In y s' -> mem x s = mem y s'
x, y:E.t
H:E.eq x y
s, s':t

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.

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)
x, y:E.t
H:E.eq x y
a:elt
H0:E.eq x a

E.eq y a
x, y:E.t
H:E.eq x y
a:elt
H0:E.eq y a
E.eq x a
x, y:E.t
H:E.eq x y
a:elt
H0:E.eq y a

E.eq x a
apply E.eq_trans with y; auto. Qed.

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

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

In a (add x s) <-> In a (add y s')
do 2 rewrite add_iff; rewrite H; rewrite H0; intuition. Qed.

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

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

In a (remove x s) <-> In a (remove y s')
do 2 rewrite remove_iff; rewrite H; rewrite H0; intuition. Qed.

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

Proper (Equal ==> Equal ==> Equal) union
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
s'', s''':t
H0:forall a0 : elt, In a0 s'' <-> In a0 s'''
a:elt

In a (union s s'') <-> In a (union s' s''')
do 2 rewrite union_iff; rewrite H; rewrite H0; intuition. Qed.

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

Proper (Equal ==> Equal ==> Equal) inter
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
s'', s''':t
H0:forall a0 : elt, In a0 s'' <-> In a0 s'''
a:elt

In a (inter s s'') <-> In a (inter s' s''')
do 2 rewrite inter_iff; rewrite H; rewrite H0; intuition. Qed.

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

Proper (Equal ==> Equal ==> Equal) diff
s, s':t
H:forall a0 : elt, In a0 s <-> In a0 s'
s'', s''':t
H0:forall a0 : elt, In a0 s'' <-> In a0 s'''
a:elt

In a (diff s s'') <-> In a (diff s' s''')
do 2 rewrite diff_iff; rewrite H; rewrite H0; 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
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''

subset s s'' = subset s' s'''
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''

s [<=] s'' <-> subset s s'' = true -> s' [<=] s''' <-> subset s' s''' = true -> subset s s'' = subset s' s'''
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''
H1:s [<=] s'' <-> true = true
H2:s' [<=] s''' <-> false = true

true = false
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''
H1:s [<=] s'' <-> false = true
H2:s' [<=] s''' <-> true = true
false = true
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''
H1:s [<=] s'' <-> false = true
H2:s' [<=] s''' <-> true = true

false = true
rewrite H in H1; rewrite H0 in H1; intuition. Qed.

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

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

equal s s'' = equal s' s'''
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''

s [=] s'' <-> equal s s'' = true -> s' [=] s''' <-> equal s' s''' = true -> equal s s'' = equal s' s'''
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''
H1:s [=] s'' <-> true = true
H2:s' [=] s''' <-> false = true

true = false
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''
H1:s [=] s'' <-> false = true
H2:s' [=] s''' <-> true = true
false = true
s, s':t
H:s [=] s'
s'', s''':t
H0:s'' [=] s'''
H1:s [=] s'' <-> false = true
H2:s' [=] s''' <-> true = true

false = true
rewrite H in H1; rewrite H0 in H1; intuition. Qed. (* [Subset] is a setoid order *)

forall s : t, s [<=] s

forall s : t, s [<=] s
red; auto. Qed.

forall s s' s'' : t, s [<=] s' -> s' [<=] s'' -> s [<=] s''

forall s s' s'' : t, s [<=] s' -> s' [<=] s'' -> s [<=] s''
unfold Subset; eauto. Qed. Add Relation t Subset reflexivity proved by Subset_refl transitivity proved by Subset_trans as 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.

forall x y : t, y [<=] x -> impl (Empty x) (Empty y)

forall x y : t, y [<=] x -> impl (Empty x) (Empty y)
unfold Subset, Empty, Basics.impl; firstorder. Qed.

forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> add x x0 [<=] add y y0

forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> add x x0 [<=] add y y0
x, y:E.t
H:E.eq x y
s, s':t
H0:forall a0 : elt, In a0 s -> In a0 s'
a:elt

In a (add x s) -> In a (add y s')
do 2 rewrite add_iff; rewrite H; intuition. Qed.

forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> remove x x0 [<=] remove y y0

forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> remove x x0 [<=] remove y y0
x, y:E.t
H:E.eq x y
s, s':t
H0:forall a0 : elt, In a0 s -> In a0 s'
a:elt

In a (remove x s) -> In a (remove y s')
do 2 rewrite remove_iff; rewrite H; intuition. Qed.

forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> union x x0 [<=] union y y0

forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> union x x0 [<=] union y y0
s, s':t
H:s [<=] s'
s'', s''':t
H0:s'' [<=] s'''
a:elt

In a (union s s'') -> In a (union s' s''')
do 2 rewrite union_iff; intuition. Qed.

forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> inter x x0 [<=] inter y y0

forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> inter x x0 [<=] inter y y0
s, s':t
H:s [<=] s'
s'', s''':t
H0:s'' [<=] s'''
a:elt

In a (inter s s'') -> In a (inter s' s''')
do 2 rewrite inter_iff; intuition. Qed.

forall x y : t, x [<=] y -> forall x0 y0 : t, y0 [<=] x0 -> diff x x0 [<=] diff y y0

forall x y : t, x [<=] y -> forall x0 y0 : t, y0 [<=] x0 -> diff x x0 [<=] diff y y0
s, s':t
H:forall a0 : elt, In a0 s -> In a0 s'
s'', s''':t
H0:forall a0 : elt, In a0 s''' -> In a0 s''
a:elt

In a (diff s s'') -> In a (diff s' s''')
do 2 rewrite diff_iff; intuition. Qed. (* [fold], [filter], [for_all], [exists_] and [partition] cannot be proved morphism without additional hypothesis on [f]. For instance: *)

forall f : E.t -> bool, compat_bool E.eq f -> forall s s' : t, s [=] s' -> filter f s [=] filter f s'

forall f : E.t -> bool, compat_bool E.eq f -> forall s s' : t, s [=] s' -> filter f s [=] filter f s'
unfold Equal; intros; repeat rewrite filter_iff; auto; rewrite H0; tauto. Qed.

forall f f' : E.t -> bool, compat_bool E.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, compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.eq f
Hff':forall x0 : E.t, f x0 = f' x0
s, s':t
Hss':s [=] s'
x:elt
compat_bool E.eq f'
f, f':E.t -> bool
Hf:compat_bool E.eq f
Hff':forall x0 : E.t, f x0 = f' x0
s, s':t
Hss':s [=] s'
x:elt

compat_bool E.eq f'
repeat red; intros; rewrite <- 2 Hff'; auto. Qed.

forall f : E.t -> bool, compat_bool E.eq f -> forall s s' : t, s [<=] s' -> filter f s [<=] filter f s'

forall f : E.t -> bool, compat_bool E.eq f -> forall s s' : t, s [<=] s' -> filter f s [<=] filter f s'
unfold Subset; intros; rewrite filter_iff in *; intuition. 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 WFacts_fun.
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:WS) := WFacts_fun M.E M.
Module Facts := WFacts.