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) *)
(************************************************************************)
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.
Section ImplSpec. Variable s s' : t. Variable x y : elt.s, s':tx, y:eltE.eq x y -> In x s -> In y sintros E; rewrite E; auto. Qed.s, s':tx, y:eltE.eq x y -> In x s -> In y ss, s':tx, y:eltIn x s -> mem x s = trueintros; apply <- mem_spec; auto. Qed.s, s':tx, y:eltIn x s -> mem x s = trues, s':tx, y:eltmem x s = true -> In x sintros; apply -> mem_spec; auto. Qed.s, s':tx, y:eltmem x s = true -> In x ss, s':tx, y:elts [=] s' -> equal s s' = trueintros; apply <- equal_spec; auto. Qed.s, s':tx, y:elts [=] s' -> equal s s' = trues, s':tx, y:eltequal s s' = true -> s [=] s'intros; apply -> equal_spec; auto. Qed.s, s':tx, y:eltequal s s' = true -> s [=] s's, s':tx, y:elts [<=] s' -> subset s s' = trueintros; apply <- subset_spec; auto. Qed.s, s':tx, y:elts [<=] s' -> subset s s' = trues, s':tx, y:eltsubset s s' = true -> s [<=] s'intros; apply -> subset_spec; auto. Qed.s, s':tx, y:eltsubset s s' = true -> s [<=] s's, s':tx, y:eltEmpty s -> is_empty s = trueintros; apply <- is_empty_spec; auto. Qed.s, s':tx, y:eltEmpty s -> is_empty s = trues, s':tx, y:eltis_empty s = true -> Empty sintros; apply -> is_empty_spec; auto. Qed.s, s':tx, y:eltis_empty s = true -> Empty ss, s':tx, y:eltE.eq x y -> In y (add x s)s, s':tx, y:eltE.eq x y -> In y (add x s)auto with relations. Qed.s, s':tx, y:eltH:E.eq x yE.eq y x \/ In y ss, s':tx, y:eltIn y s -> In y (add x s)intros; apply <- add_spec; auto. Qed.s, s':tx, y:eltIn y s -> In y (add x s)s, s':tx, y:elt~ E.eq x y -> In y (add x s) -> In y ss, s':tx, y:elt~ E.eq x y -> In y (add x s) -> In y ss, s':tx, y:elt~ E.eq x y -> E.eq y x \/ In y s -> In y selim H; auto with relations. Qed.s, s':tx, y:eltH:~ E.eq x yH':E.eq y xIn y ss, s':tx, y:eltE.eq x y -> ~ In y (remove x s)intros; rewrite remove_spec; intuition. Qed.s, s':tx, y:eltE.eq x y -> ~ In y (remove x s)s, s':tx, y:elt~ E.eq x y -> In y s -> In y (remove x s)intros; apply <- remove_spec; auto with relations. Qed.s, s':tx, y:elt~ E.eq x y -> In y s -> In y (remove x s)s, s':tx, y:eltIn y (remove x s) -> In y srewrite remove_spec; intuition. Qed.s, s':tx, y:eltIn y (remove x s) -> In y ss, s':tx, y:eltIn y (singleton x) -> E.eq x yrewrite singleton_spec; auto with relations. Qed.s, s':tx, y:eltIn y (singleton x) -> E.eq x ys, s':tx, y:eltE.eq x y -> In y (singleton x)rewrite singleton_spec; auto with relations. Qed.s, s':tx, y:eltE.eq x y -> In y (singleton x)s, s':tx, y:eltIn x (union s s') -> In x s \/ In x s'rewrite union_spec; auto. Qed.s, s':tx, y:eltIn x (union s s') -> In x s \/ In x s's, s':tx, y:eltIn x s -> In x (union s s')rewrite union_spec; auto. Qed.s, s':tx, y:eltIn x s -> In x (union s s')s, s':tx, y:eltIn x s' -> In x (union s s')rewrite union_spec; auto. Qed.s, s':tx, y:eltIn x s' -> In x (union s s')s, s':tx, y:eltIn x (inter s s') -> In x srewrite inter_spec; intuition. Qed.s, s':tx, y:eltIn x (inter s s') -> In x ss, s':tx, y:eltIn x (inter s s') -> In x s'rewrite inter_spec; intuition. Qed.s, s':tx, y:eltIn x (inter s s') -> In x s's, s':tx, y:eltIn x s -> In x s' -> In x (inter s s')rewrite inter_spec; intuition. Qed.s, s':tx, y:eltIn x s -> In x s' -> In x (inter s s')s, s':tx, y:eltIn x (diff s s') -> In x srewrite diff_spec; intuition. Qed.s, s':tx, y:eltIn x (diff s s') -> In x ss, s':tx, y:eltIn x (diff s s') -> ~ In x s'rewrite diff_spec; intuition. Qed.s, s':tx, y:eltIn x (diff s s') -> ~ In x s's, s':tx, y:eltIn 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':tx, y:eltIn x s -> ~ In x s' -> In x (diff s s')s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> In x (filter f s) -> In x sintros P; rewrite filter_spec; intuition. Qed.s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> In x (filter f s) -> In x ss, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> In x (filter f s) -> f x = trueintros P; rewrite filter_spec; intuition. Qed.s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> In x (filter f s) -> f x = trues, s':tx, y:eltf:elt -> boolProper (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':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> In x s -> f x = true -> In x (filter f s)s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s -> for_all f s = trueintros; apply <- for_all_spec; auto. Qed.s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s -> for_all f s = trues, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> for_all f s = true -> For_all (fun x0 : elt => f x0 = true) sintros; apply -> for_all_spec; auto. Qed.s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> for_all f s = true -> For_all (fun x0 : elt => f x0 = true) ss, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s -> exists_ f s = trueintros; apply <- exists_spec; auto. Qed.s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s -> exists_ f s = trues, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> exists_ f s = true -> Exists (fun x0 : elt => f x0 = true) sintros; apply -> exists_spec; auto. Qed.s, s':tx, y:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> exists_ f s = true -> Exists (fun x0 : elt => f x0 = true) ss, s':tx, y:eltf:elt -> boolIn x s -> InA E.eq x (elements s)intros; apply <- elements_spec1; auto. Qed.s, s':tx, y:eltf:elt -> boolIn x s -> InA E.eq x (elements s)s, s':tx, y:eltf:elt -> boolInA E.eq x (elements s) -> In x sintros; 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.s, s':tx, y:eltf:elt -> boolInA E.eq x (elements s) -> In x s
Section IffSpec. Variable s s' s'' : t. Variable x y z : elt.s, s', s'':tx, y, z:eltE.eq x y -> In x s <-> In y sintros E; rewrite E; intuition. Qed.s, s', s'':tx, y, z:eltE.eq x y -> In x s <-> In y ss, s', s'':tx, y, z:eltIn x s <-> mem x s = trueapply iff_sym, mem_spec. Qed.s, s', s'':tx, y, z:eltIn x s <-> mem x s = trues, s', s'':tx, y, z:elt~ In x s <-> mem x s = falserewrite <-mem_spec; destruct (mem x s); intuition. Qed.s, s', s'':tx, y, z:elt~ In x s <-> mem x s = falses, s', s'':tx, y, z:elts [=] s' <-> equal s s' = trueapply iff_sym, equal_spec. Qed.s, s', s'':tx, y, z:elts [=] s' <-> equal s s' = trues, s', s'':tx, y, z:elts [<=] s' <-> subset s s' = trueapply iff_sym, subset_spec. Qed.s, s', s'':tx, y, z:elts [<=] s' <-> subset s s' = trues, s', s'':tx, y, z:eltIn x empty <-> Falseintuition; apply (empty_spec H). Qed.s, s', s'':tx, y, z:eltIn x empty <-> Falses, s', s'':tx, y, z:eltEmpty s <-> is_empty s = trueapply iff_sym, is_empty_spec. Qed.s, s', s'':tx, y, z:eltEmpty s <-> is_empty s = trues, s', s'':tx, y, z:eltIn y (singleton x) <-> E.eq x yrewrite singleton_spec; intuition. Qed.s, s', s'':tx, y, z:eltIn y (singleton x) <-> E.eq x ys, s', s'':tx, y, z:eltIn y (add x s) <-> E.eq x y \/ In y srewrite add_spec; intuition. Qed.s, s', s'':tx, y, z:eltIn y (add x s) <-> E.eq x y \/ In y ss, s', s'':tx, y, z:elt~ E.eq x y -> In y (add x s) <-> In y ss, s', s'':tx, y, z:elt~ E.eq x y -> In y (add x s) <-> In y selim H; auto with relations. Qed.s, s', s'':tx, y, z:eltH:E.eq x y -> FalseH1:E.eq y xIn y ss, s', s'':tx, y, z:eltIn y (remove x s) <-> In y s /\ ~ E.eq x yrewrite remove_spec; intuition. Qed.s, s', s'':tx, y, z:eltIn y (remove x s) <-> In y s /\ ~ E.eq x ys, s', s'':tx, y, z:elt~ E.eq x y -> In y (remove x s) <-> In y srewrite remove_spec; intuition. Qed. Variable f : elt -> bool.s, s', s'':tx, y, z:elt~ E.eq x y -> In y (remove x s) <-> In y ss, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = trueintros; apply iff_sym, for_all_spec; auto. Qed.s, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = trues, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = trueintros; apply iff_sym, exists_spec; auto. Qed.s, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = trues, s', s'':tx, y, z:eltf:elt -> boolIn 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).s, s', s'':tx, y, z:eltf:elt -> boolIn x s <-> InA E.eq x (elements s)
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)).
Section BoolSpec. Variable s s' s'' : t. Variable x y z : elt.s, s', s'':tx, y, z:eltE.eq x y -> mem x s = mem y ss, s', s'':tx, y, z:eltE.eq x y -> mem x s = mem y ss, s', s'':tx, y, z:eltH:E.eq x ymem x s = mem y sdestruct (mem x s); destruct (mem y s); intuition. Qed.s, s', s'':tx, y, z:eltH:E.eq x yIn x s <-> mem x s = true -> In y s <-> mem y s = true -> In x s <-> In y s -> mem x s = mem y ss, s', s'':tx, y, z:eltmem y empty = falses, s', s'':tx, y, z:eltmem y empty = falsedestruct (mem y empty); intuition. Qed.s, s', s'':tx, y, z:eltIn y empty <-> False -> In y empty <-> mem y empty = true -> mem y empty = falses, s', s'':tx, y, z:eltmem y (add x s) = eqb x y || mem y ss, s', s'':tx, y, z:eltmem y (add x s) = eqb x y || mem y sdestruct (eq_dec x y); destruct (mem y s); destruct (mem y (add x s)); intuition. Qed.s, s', s'':tx, y, z:eltIn 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 ss, s', s'':tx, y, z:elt~ E.eq x y -> mem y (add x s) = mem y ss, s', s'':tx, y, z:elt~ E.eq x y -> mem y (add x s) = mem y sdestruct (mem y s); destruct (mem y (add x s)); intuition. Qed.s, s', s'':tx, y, z:eltH:~ E.eq x yIn 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 ss, s', s'':tx, y, z:eltmem y (remove x s) = mem y s && negb (eqb x y)s, s', s'':tx, y, z:eltmem y (remove x s) = mem y s && negb (eqb x y)destruct (eq_dec x y); destruct (mem y s); destruct (mem y (remove x s)); simpl; intuition. Qed.s, s', s'':tx, y, z:eltIn 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)s, s', s'':tx, y, z:elt~ E.eq x y -> mem y (remove x s) = mem y ss, s', s'':tx, y, z:elt~ E.eq x y -> mem y (remove x s) = mem y sdestruct (mem y s); destruct (mem y (remove x s)); intuition. Qed.s, s', s'':tx, y, z:eltH:~ E.eq x yIn 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 ss, s', s'':tx, y, z:eltmem y (singleton x) = eqb x ys, s', s'':tx, y, z:eltmem y (singleton x) = eqb x ydestruct (eq_dec x y); destruct (mem y (singleton x)); intuition. Qed.s, s', s'':tx, y, z:eltIn 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)s, s', s'':tx, y, z:eltmem x (union s s') = mem x s || mem x s's, s', s'':tx, y, z:eltmem 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'':tx, y, z:eltIn 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's, s', s'':tx, y, z:eltmem x (inter s s') = mem x s && mem x s's, s', s'':tx, y, z:eltmem 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'':tx, y, z:eltIn 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's, s', s'':tx, y, z:eltmem x (diff s s') = mem x s && negb (mem x s')s, s', s'':tx, y, z:eltmem 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'':tx, y, z:eltIn 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')s, s', s'':tx, y, z:eltmem x s = existsb (eqb x) (elements s)s, s', s'':tx, y, z:eltmem x s = existsb (eqb x) (elements s)s, s', s'':tx, y, z:eltIn 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'':tx, y, z:eltIn 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'':tx, y, z:eltH:In x s <-> true = trueH0: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 = falses, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> true = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> true = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> true = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> true = trueH1:false = true <-> (exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true)a:E.tHa1:E.eq x aHa2:List.In a (elements s)exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:elta:E.tHa1:E.eq x aHa2:List.In a (elements s)H:false = true -> exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = trueH3:(exists x0 : E.t, List.In x0 (elements s) /\ eqb x x0 = true) -> false = trueH1:In x sH2:true = trueeqb x a = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trues, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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 ss, s', s'':tx, y, z:eltH:In x s <-> false = trueH0: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'':tx, y, z:eltH:In x s <-> false = trueH0: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 = trueexists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)s, s', s'':tx, y, z:eltH:In x s <-> false = trueH0:In x s <-> (exists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s))a:E.tHa1:List.In a (elements s)Ha2:eqb x a = trueexists y0 : E.t, E.eq x y0 /\ List.In y0 (elements s)unfold eqb in *; destruct (eq_dec x a); auto; discriminate. Qed. Variable f : elt->bool.s, s', s'':tx, y, z:elta:E.tHa1:List.In a (elements s)Ha2:eqb x a = trueH1:In x s -> false = trueH2:false = true -> In x sH: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 sE.eq x as, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> mem x (filter f s) = mem x s && f xs, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> mem x (filter f s) = mem x s && f xs, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fmem x (filter f s) = mem x s && f xdestruct (mem x s); destruct (mem x (filter f s)); destruct (f x); simpl; intuition. Qed.s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fIn 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 xs, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> for_all f s = forallb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> for_all f s = forallb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) ffor_all f s = forallb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fforallb 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'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fforallb 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'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> false = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)false = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:In x0 sf x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = trueH1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:In x0 sf x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = trueH1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:InA E.eq x0 (elements s)f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = trueH1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:exists y0 : E.t, E.eq x0 y0 /\ List.In y0 (elements s)f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = trueH1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:elta:E.tHa1:E.eq x0 aHa2:List.In a (elements s)f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true -> forall x1 : elt, List.In x1 (elements s) -> f x1 = trueH1:(forall x1 : elt, In x1 s -> f x1 = true) <-> false = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:elta:E.tHa1:E.eq x0 aHa2:List.In a (elements s)f a = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x0 : elt, List.In x0 (elements s) -> f x0 = true)H1:(forall x0 : elt, In x0 s -> f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)false = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)H1:(forall x1 : elt, In x1 s -> f x1 = true) <-> true = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:List.In x0 (elements s)f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)H1:true = true -> forall x1 : elt, In x1 s -> f x1 = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:List.In x0 (elements s)f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)H1:true = true -> forall x1 : elt, In x1 s -> f x1 = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:List.In x0 (elements s)In x0 ss, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)H1:true = true -> forall x1 : elt, In x1 s -> f x1 = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:List.In x0 (elements s)InA E.eq x0 (elements s)exists x0; split; auto with relations. Qed.s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (forall x1 : elt, List.In x1 (elements s) -> f x1 = true)H1:true = true -> forall x1 : elt, In x1 s -> f x1 = trueH2:forall x1 : elt, In x1 s <-> InA E.eq x1 (elements s)x0:eltH3:List.In x0 (elements s)exists y0 : E.t, E.eq x0 y0 /\ List.In y0 (elements s)s, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> exists_ f s = existsb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolProper (E.eq ==> Logic.eq) f -> exists_ f s = existsb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fexists_ f s = existsb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fexistsb 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'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fexistsb 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'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)false = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)exists x0 : elt, In x0 s /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:true = true -> exists x0 : elt, List.In x0 (elements s) /\ f x0 = trueH1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)exists x0 : elt, In x0 s /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)a:eltHa1:List.In a (elements s)Ha2:f a = trueexists x0 : elt, In x0 s /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> false = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)a:eltHa1:List.In a (elements s)Ha2:f a = trueIn a ss, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)true = falses, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)false = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:(exists x0 : elt, In x0 s /\ f x0 = true) <-> true = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)exists x0 : elt, List.In x0 (elements s) /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0:false = true <-> (exists x0 : elt, List.In x0 (elements s) /\ f x0 = true)H1:true = true -> exists x0 : elt, In x0 s /\ f x0 = trueH2:forall x0 : elt, In x0 s <-> InA E.eq x0 (elements s)exists x0 : elt, List.In x0 (elements s) /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0: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:eltHa1:In a sHa2:f a = trueexists x0 : elt, List.In x0 (elements s) /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0: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:eltHa1:InA E.eq a (elements s)Ha2:f a = trueexists x0 : elt, List.In x0 (elements s) /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0: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:eltHa1:exists y0 : E.t, E.eq a y0 /\ List.In y0 (elements s)Ha2:f a = trueexists x0 : elt, List.In x0 (elements s) /\ f x0 = trues, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0: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:eltb:E.tHb1:E.eq a bHb2:List.In b (elements s)Ha2:f a = trueexists x0 : elt, List.In x0 (elements s) /\ f x0 = truerewrite <- (H _ _ Hb1); auto. Qed. End BoolSpec.s, s', s'':tx, y, z:eltf:elt -> boolH:Proper (E.eq ==> Logic.eq) fH0: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:eltb:E.tHb1:E.eq a bHb2:List.In b (elements s)Ha2:f a = trueList.In b (elements s) /\ f b = true
Proper (E.eq ==> Equal ==> iff) InProper (E.eq ==> Equal ==> iff) Inrewrite (In_eq_iff s H); auto. Qed.x, y:E.tH:E.eq x ys, s':tH0:forall a : elt, In a s <-> In a s'In x s <-> In y s'Proper (Equal ==> iff) EmptyProper (Equal ==> iff) Emptysetoid_rewrite E; auto. Qed.s, s':tE: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)Proper (Equal ==> Logic.eq) is_emptyProper (Equal ==> Logic.eq) is_emptys, s':tH:s [=] s'is_empty s = is_empty s's, s':tH:s [=] s'Empty s <-> is_empty s = true -> is_empty s = is_empty s's, s':tH:s [=] s'Empty s' <-> is_empty s = true -> is_empty s = is_empty s'destruct (is_empty s); destruct (is_empty s'); intuition. Qed.s, s':tH:s [=] s'is_empty s' = true <-> is_empty s = true -> is_empty s = is_empty s'Proper (E.eq ==> Equal ==> Logic.eq) memProper (E.eq ==> Equal ==> Logic.eq) memx, x':E.tHx:E.eq x x's, s':tHs:s [=] s'mem x s = mem x' s'x, x':E.tHx:E.eq x x's, s':tHs:s [=] s'In x s <-> mem x s = true -> mem x s = mem x' s'destruct (mem x s), (mem x' s'); intuition. Qed.x, x':E.tHx:E.eq x x's, s':tHs:s [=] s'mem x' s' = true <-> mem x s = true -> mem x s = mem x' s'Proper (E.eq ==> Equal) singletonProper (E.eq ==> Equal) singletonrewrite !singleton_iff, H; intuition. Qed.x, y:E.tH:E.eq x ya:eltIn a (singleton x) <-> In a (singleton y)Proper (E.eq ==> Equal ==> Equal) addProper (E.eq ==> Equal ==> Equal) addrewrite !add_iff, Hx, Hs; intuition. Qed.x, x':E.tHx:E.eq x x's, s':tHs:s [=] s'a:eltIn a (add x s) <-> In a (add x' s')Proper (E.eq ==> Equal ==> Equal) removeProper (E.eq ==> Equal ==> Equal) removerewrite !remove_iff, Hx, Hs; intuition. Qed.x, x':E.tHx:E.eq x x's, s':tHs:s [=] s'a:eltIn a (remove x s) <-> In a (remove x' s')Proper (Equal ==> Equal ==> Equal) unionProper (Equal ==> Equal ==> Equal) unionrewrite !union_iff, Hs1, Hs2; intuition. Qed.s1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'a:eltIn a (union s1 s2) <-> In a (union s1' s2')Proper (Equal ==> Equal ==> Equal) interProper (Equal ==> Equal ==> Equal) interrewrite !inter_iff, Hs1, Hs2; intuition. Qed.s1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'a:eltIn a (inter s1 s2) <-> In a (inter s1' s2')Proper (Equal ==> Equal ==> Equal) diffProper (Equal ==> Equal ==> Equal) diffrewrite !diff_iff, Hs1, Hs2; intuition. Qed.s1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'a:eltIn a (diff s1 s2) <-> In a (diff s1' s2')Proper (Equal ==> Equal ==> iff) Subsetunfold Equal, Subset; firstorder. Qed.Proper (Equal ==> Equal ==> iff) SubsetProper (Equal ==> Equal ==> Logic.eq) subsetProper (Equal ==> Equal ==> Logic.eq) subsets1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'subset s1 s2 = subset s1' s2's1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2's1 [<=] s2 <-> subset s1 s2 = true -> subset s1 s2 = subset s1' s2's1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2's1' [<=] s2' <-> subset s1 s2 = true -> subset s1 s2 = subset s1' s2'destruct (subset s1 s2); destruct (subset s1' s2'); intuition. Qed.s1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'subset s1' s2' = true <-> subset s1 s2 = true -> subset s1 s2 = subset s1' s2'Proper (Equal ==> Equal ==> Logic.eq) equalProper (Equal ==> Equal ==> Logic.eq) equals1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'equal s1 s2 = equal s1' s2's1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2's1 [=] s2 <-> equal s1 s2 = true -> equal s1 s2 = equal s1' s2's1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2's1' [=] s2' <-> equal s1 s2 = true -> equal s1 s2 = equal s1' s2'destruct (equal s1 s2); destruct (equal s1' s2'); intuition. Qed.s1, s1':tHs1:s1 [=] s1's2, s2':tHs2:s2 [=] s2'equal s1' s2' = true <-> equal s1 s2 = true -> equal s1 s2 = equal s1' s2'PreOrder Subsetfirstorder. Qed. Definition Subset_refl := @PreOrder_Reflexive _ _ SubsetSetoid. Definition Subset_trans := @PreOrder_Transitive _ _ SubsetSetoid.PreOrder SubsetProper (E.eq ==> Subset ==> impl) InProper (E.eq ==> Subset ==> impl) Ineauto with set. Qed.x, y:E.tH:E.eq x yx0, y0:tH0:x0 [<=] y0H1:In x x0In y y0Proper (Subset --> impl) Emptyfirstorder. Qed.Proper (Subset --> impl) EmptyProper (E.eq ==> Subset ==> Subset) addProper (E.eq ==> Subset ==> Subset) addrewrite !add_iff, Hx; intuition. Qed.x, x':E.tHx:E.eq x x's, s':tHs:s [<=] s'a:eltIn a (add x s) -> In a (add x' s')Proper (E.eq ==> Subset ==> Subset) removeProper (E.eq ==> Subset ==> Subset) removerewrite !remove_iff, Hx; intuition. Qed.x, x':E.tHx:E.eq x x's, s':tHs:s [<=] s'a:eltIn a (remove x s) -> In a (remove x' s')Proper (Subset ==> Subset ==> Subset) unionProper (Subset ==> Subset ==> Subset) unionrewrite !union_iff, Hs1, Hs2; intuition. Qed.s1, s1':tHs1:s1 [<=] s1's2, s2':tHs2:s2 [<=] s2'a:eltIn a (union s1 s2) -> In a (union s1' s2')Proper (Subset ==> Subset ==> Subset) interProper (Subset ==> Subset ==> Subset) interrewrite !inter_iff, Hs1, Hs2; intuition. Qed.s1, s1':tHs1:s1 [<=] s1's2, s2':tHs2:s2 [<=] s2'a:eltIn a (inter s1 s2) -> In a (inter s1' s2')Proper (Subset ==> Subset --> Subset) diffProper (Subset ==> Subset --> Subset) diffrewrite !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.s1, s1':tHs1:s1 [<=] s1's2, s2':tHs2:flip Subset s2 s2'a:eltIn a (diff s1 s2) -> In a (diff s1' s2')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)rewrite !filter_iff, Hs by auto; intuition. Qed.f:E.t -> boolHf:Proper (E.eq ==> Logic.eq) fs, s':tHs:s [=] s'a:eltIn a (filter f s) <-> In a (filter f s')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)rewrite !filter_iff, Hs by auto; intuition. Qed.f:E.t -> boolHf:Proper (E.eq ==> Logic.eq) fs, s':tHs:s [<=] s'a:eltIn a (filter f s) -> In a (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'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 -> boolHf:Proper (E.eq ==> Logic.eq) fHff':forall x0 : E.t, f x0 = f' x0s, s':tHss':s [=] s'x:eltIn x (filter f s) <-> In x (filter f' s')f, f':E.t -> boolHf:Proper (E.eq ==> Logic.eq) fHff':forall x0 : E.t, f x0 = f' x0s, s':tHss':s [=] s'x:eltIn x s /\ f x = true <-> In x s' /\ f' x = truef, f':E.t -> boolHf:Proper (E.eq ==> Logic.eq) fHff':forall x0 : E.t, f x0 = f' x0s, s':tHss':s [=] s'x:eltProper (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.f, f':E.t -> boolHf:Proper (E.eq ==> Logic.eq) fHff':forall x0 : E.t, f x0 = f' x0s, s':tHss':s [=] s'x:eltProper (E.eq ==> Logic.eq) f'
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.