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 WSS, 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.