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 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.
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 ssplit; apply In_1; auto. 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 = truesplit; [apply mem_1|apply mem_2]. 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_iff; 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' = truesplit; [apply equal_1|apply equal_2]. Qed.s, s', s'':tx, y, z:elts [=] s' <-> equal s s' = trues, s', s'':tx, y, z:elts [<=] s' <-> subset s s' = truesplit; [apply subset_1|apply subset_2]. Qed.s, s', s'':tx, y, z:elts [<=] s' <-> subset s s' = trues, s', s'':tx, y, z:eltIn x empty <-> Falseintuition; apply (empty_1 H). Qed.s, s', s'':tx, y, z:eltIn x empty <-> Falses, s', s'':tx, y, z:eltEmpty s <-> is_empty s = truesplit; [apply is_empty_1|apply is_empty_2]. 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 ysplit; [apply singleton_1|apply singleton_2]. 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 ss, s', s'':tx, y, z:eltIn y (add x s) <-> E.eq x y \/ In y ss, s', s'':tx, y, z:eltIn y (add x s) -> E.eq x y \/ In y sintro H; right; exact (add_3 E H). Qed.s, s', s'':tx, y, z:eltE:~ E.eq x yIn 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 ssplit; [apply add_3|apply add_2]; auto. Qed.s, s', s'':tx, y, z:elt~ E.eq x y -> In y (add x s) <-> In y ss, s', s'':tx, y, z:eltIn y (remove x s) <-> In y s /\ ~ E.eq x ys, s', s'':tx, y, z:eltIn y (remove x s) <-> In y s /\ ~ E.eq x ys, s', s'':tx, y, z:eltH:In y (remove x s)~ E.eq x yapply (remove_1 H0 H). Qed.s, s', s'':tx, y, z:eltH:In y (remove x s)H0:E.eq x yFalses, s', s'':tx, y, z:elt~ E.eq x y -> In y (remove x s) <-> In y ssplit; [apply remove_3|apply remove_2]; auto. Qed.s, s', s'':tx, y, z:elt~ E.eq x y -> In y (remove x s) <-> In y ss, s', s'':tx, y, z:eltIn 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'':tx, y, z:eltIn x (union s s') <-> In x s \/ In x s's, s', s'':tx, y, z:eltIn 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'':tx, y, z:eltIn x (inter s s') <-> In x s /\ In x s's, s', s'':tx, y, z:eltIn 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'':tx, y, z:eltIn x (diff s s') <-> In x s /\ ~ In x s's, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> In x (filter f s) <-> In x s /\ f x = truesplit; [split; [apply filter_1 with f | apply filter_2 with s] | destruct 1; apply filter_3]; auto. Qed.s, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> In x (filter f s) <-> In x s /\ f x = trues, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = truesplit; [apply for_all_1 | apply for_all_2]; auto. Qed.s, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> For_all (fun x0 : elt => f x0 = true) s <-> for_all f s = trues, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> Exists (fun x0 : elt => f x0 = true) s <-> exists_ f s = truesplit; [apply exists_1 | apply exists_2]; auto. Qed.s, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.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)split; [apply elements_1 | apply elements_2]. Qed. End IffSpec.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 -> boolcompat_bool E.eq f -> mem x (filter f s) = mem x s && f xs, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> mem x (filter f s) = mem x s && f xs, s', s'':tx, y, z:eltf:elt -> boolH:compat_bool E.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:compat_bool E.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 -> boolcompat_bool E.eq f -> for_all f s = forallb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> for_all f s = forallb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:compat_bool E.eq ffor_all f s = forallb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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 srewrite InA_alt; eauto. Qed.s, s', s'':tx, y, z:eltf:elt -> boolH:compat_bool E.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)s, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> exists_ f s = existsb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolcompat_bool E.eq f -> exists_ f s = existsb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:compat_bool E.eq fexists_ f s = existsb f (elements s)s, s', s'':tx, y, z:eltf:elt -> boolH:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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:compat_bool E.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
Equivalence E.eqconstructor ; red; [apply E.eq_refl|apply E.eq_sym|apply E.eq_trans]. Qed.Equivalence E.eqEquivalence Equalconstructor ; red; [apply eq_refl | apply eq_sym | apply eq_trans]. Qed.Equivalence EqualProper (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 ==> Logic.eq) is_emptyProper (Equal ==> Logic.eq) is_emptys, s':tH:forall a : elt, In a s <-> In a s'is_empty s = is_empty s's, s':tH: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':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> true = trueH1:(forall a : elt, ~ In a s') <-> false = truetrue = falses, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> false = trueH1:(forall a : elt, ~ In a s') <-> true = truefalse = trues, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> true = trueH1:(forall a : elt, ~ In a s') <-> false = truefalse = trues, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> false = trueH1:(forall a : elt, ~ In a s') <-> true = truefalse = trues, s':tH:forall a0 : elt, In a0 s <-> In a0 s'H0:(forall a0 : elt, ~ In a0 s) <-> true = trueH1:(forall a0 : elt, ~ In a0 s') <-> false = truea:eltHa:In a s'Falses, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> false = trueH1:(forall a : elt, ~ In a s') <-> true = truefalse = trues, s':tH:forall a0 : elt, In a0 s <-> In a0 s'H0:(forall a0 : elt, ~ In a0 s) <-> true = trueH1:(forall a0 : elt, ~ In a0 s') <-> false = truea:eltHa:In a sFalses, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> false = trueH1:(forall a : elt, ~ In a s') <-> true = truefalse = trues, s':tH:forall a0 : elt, In a0 s <-> In a0 s'H0:true = true -> forall a0 : elt, ~ In a0 sH1:(forall a0 : elt, ~ In a0 s') <-> false = truea:eltHa:In a sFalses, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> false = trueH1:(forall a : elt, ~ In a s') <-> true = truefalse = trues, s':tH:forall a : elt, In a s <-> In a s'H0:(forall a : elt, ~ In a s) <-> false = trueH1:(forall a : elt, ~ In a s') <-> true = truefalse = trues, s':tH:forall a0 : elt, In a0 s <-> In a0 s'H0:(forall a0 : elt, ~ In a0 s) <-> false = trueH1:(forall a0 : elt, ~ In a0 s') <-> true = truea:eltHa:In a sFalses, s':tH:forall a0 : elt, In a0 s <-> In a0 s'H0:(forall a0 : elt, ~ In a0 s) <-> false = trueH1:(forall a0 : elt, ~ In a0 s') <-> true = truea:eltHa:In a s'Falseexact (H1 Logic.eq_refl _ Ha). Qed.s, s':tH:forall a0 : elt, In a0 s <-> In a0 s'H0:(forall a0 : elt, ~ In a0 s) <-> false = trueH1:true = true -> forall a0 : elt, ~ In a0 s'a:eltHa:In a s'FalseProper (Equal ==> iff) Emptyrepeat red; intros; do 2 rewrite is_empty_iff; rewrite H; intuition. Qed.Proper (Equal ==> iff) EmptyProper (E.eq ==> Equal ==> Logic.eq) memProper (E.eq ==> Equal ==> Logic.eq) memx, y:E.tH:E.eq x ys, s':tH0:forall a : elt, In a s <-> In a s'mem x s = mem y s'x, y:E.tH:E.eq x ys, s':tIn x s <-> In y s' -> mem x s = mem y s'destruct (mem x s); destruct (mem y s'); intuition. Qed.x, y:E.tH:E.eq x ys, s':tIn 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'Proper (E.eq ==> Equal) singletonProper (E.eq ==> Equal) singletonx, y:E.tH:E.eq x ya:eltIn a (singleton x) <-> In a (singleton y)x, y:E.tH:E.eq x ya:eltH0:E.eq x aE.eq y ax, y:E.tH:E.eq x ya:eltH0:E.eq y aE.eq x aapply E.eq_trans with y; auto. Qed.x, y:E.tH:E.eq x ya:eltH0:E.eq y aE.eq x aProper (E.eq ==> Equal ==> Equal) addProper (E.eq ==> Equal ==> Equal) adddo 2 rewrite add_iff; rewrite H; rewrite H0; intuition. Qed.x, y:E.tH:E.eq x ys, s':tH0:forall a0 : elt, In a0 s <-> In a0 s'a:eltIn a (add x s) <-> In a (add y s')Proper (E.eq ==> Equal ==> Equal) removeProper (E.eq ==> Equal ==> Equal) removedo 2 rewrite remove_iff; rewrite H; rewrite H0; intuition. Qed.x, y:E.tH:E.eq x ys, s':tH0:forall a0 : elt, In a0 s <-> In a0 s'a:eltIn a (remove x s) <-> In a (remove y s')Proper (Equal ==> Equal ==> Equal) unionProper (Equal ==> Equal ==> Equal) uniondo 2 rewrite union_iff; rewrite H; rewrite H0; intuition. Qed.s, s':tH:forall a0 : elt, In a0 s <-> In a0 s's'', s''':tH0:forall a0 : elt, In a0 s'' <-> In a0 s'''a:eltIn a (union s s'') <-> In a (union s' s''')Proper (Equal ==> Equal ==> Equal) interProper (Equal ==> Equal ==> Equal) interdo 2 rewrite inter_iff; rewrite H; rewrite H0; intuition. Qed.s, s':tH:forall a0 : elt, In a0 s <-> In a0 s's'', s''':tH0:forall a0 : elt, In a0 s'' <-> In a0 s'''a:eltIn a (inter s s'') <-> In a (inter s' s''')Proper (Equal ==> Equal ==> Equal) diffProper (Equal ==> Equal ==> Equal) diffdo 2 rewrite diff_iff; rewrite H; rewrite H0; intuition. Qed.s, s':tH:forall a0 : elt, In a0 s <-> In a0 s's'', s''':tH0:forall a0 : elt, In a0 s'' <-> In a0 s'''a:eltIn a (diff s s'') <-> In a (diff s' s''')Proper (Equal ==> Equal ==> iff) Subsetunfold Equal, Subset; firstorder. Qed.Proper (Equal ==> Equal ==> iff) SubsetProper (Equal ==> Equal ==> Logic.eq) subsetProper (Equal ==> Equal ==> Logic.eq) subsets, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''subset s s'' = subset s' s'''s, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''s [<=] s'' <-> subset s s'' = true -> s' [<=] s''' <-> subset s' s''' = true -> subset s s'' = subset s' s'''s, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''H1:s [<=] s'' <-> true = trueH2:s' [<=] s''' <-> false = truetrue = falses, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''H1:s [<=] s'' <-> false = trueH2:s' [<=] s''' <-> true = truefalse = truerewrite H in H1; rewrite H0 in H1; intuition. Qed.s, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''H1:s [<=] s'' <-> false = trueH2:s' [<=] s''' <-> true = truefalse = trueProper (Equal ==> Equal ==> Logic.eq) equalProper (Equal ==> Equal ==> Logic.eq) equals, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''equal s s'' = equal s' s'''s, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''s [=] s'' <-> equal s s'' = true -> s' [=] s''' <-> equal s' s''' = true -> equal s s'' = equal s' s'''s, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''H1:s [=] s'' <-> true = trueH2:s' [=] s''' <-> false = truetrue = falses, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''H1:s [=] s'' <-> false = trueH2:s' [=] s''' <-> true = truefalse = truerewrite H in H1; rewrite H0 in H1; intuition. Qed. (* [Subset] is a setoid order *)s, s':tH:s [=] s's'', s''':tH0:s'' [=] s'''H1:s [=] s'' <-> false = trueH2:s' [=] s''' <-> true = truefalse = trueforall s : t, s [<=] sred; auto. Qed.forall s : t, s [<=] sforall 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.forall s s' s'' : t, s [<=] s' -> s' [<=] s'' -> s [<=] s''Proper (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 y0forall x y : t, y [<=] x -> impl (Empty x) (Empty y)unfold Subset, Empty, Basics.impl; firstorder. Qed.forall x y : t, y [<=] x -> impl (Empty x) (Empty y)forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> add x x0 [<=] add y y0forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> add x x0 [<=] add y y0do 2 rewrite add_iff; rewrite H; intuition. Qed.x, y:E.tH:E.eq x ys, s':tH0:forall a0 : elt, In a0 s -> In a0 s'a:eltIn a (add x s) -> In a (add y s')forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> remove x x0 [<=] remove y y0forall x y : E.t, E.eq x y -> forall x0 y0 : t, x0 [<=] y0 -> remove x x0 [<=] remove y y0do 2 rewrite remove_iff; rewrite H; intuition. Qed.x, y:E.tH:E.eq x ys, s':tH0:forall a0 : elt, In a0 s -> In a0 s'a:eltIn a (remove x s) -> In a (remove y s')forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> union x x0 [<=] union y y0forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> union x x0 [<=] union y y0do 2 rewrite union_iff; intuition. Qed.s, s':tH:s [<=] s's'', s''':tH0:s'' [<=] s'''a:eltIn a (union s s'') -> In a (union s' s''')forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> inter x x0 [<=] inter y y0forall x y : t, x [<=] y -> forall x0 y0 : t, x0 [<=] y0 -> inter x x0 [<=] inter y y0do 2 rewrite inter_iff; intuition. Qed.s, s':tH:s [<=] s's'', s''':tH0:s'' [<=] s'''a:eltIn a (inter s s'') -> In a (inter s' s''')forall x y : t, x [<=] y -> forall x0 y0 : t, y0 [<=] x0 -> diff x x0 [<=] diff y y0forall x y : t, x [<=] y -> forall x0 y0 : t, y0 [<=] x0 -> diff x x0 [<=] diff y y0do 2 rewrite diff_iff; intuition. Qed. (* [fold], [filter], [for_all], [exists_] and [partition] cannot be proved morphism without additional hypothesis on [f]. For instance: *)s, s':tH:forall a0 : elt, In a0 s -> In a0 s's'', s''':tH0:forall a0 : elt, In a0 s''' -> In a0 s''a:eltIn a (diff s s'') -> In a (diff s' 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 : E.t -> bool, compat_bool E.eq f -> 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'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 -> boolHf:compat_bool E.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:compat_bool E.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:compat_bool E.eq fHff':forall x0 : E.t, f x0 = f' x0s, s':tHss':s [=] s'x:eltcompat_bool E.eq f'repeat red; intros; rewrite <- 2 Hff'; auto. Qed.f, f':E.t -> boolHf:compat_bool E.eq fHff':forall x0 : E.t, f x0 = f' x0s, s':tHss':s [=] s'x:eltcompat_bool E.eq f'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.forall f : E.t -> bool, compat_bool E.eq f -> forall s s' : t, s [<=] s' -> filter f s [<=] filter f s'
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.