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 properties from FSetInterface.S.
Contrary to the functor in FSetEqProperties it uses
predicates over sets instead of sets operations, i.e.
In x s instead of mem x s=true,
Equal s s' instead of equal s s'=true, etc.
Require Export FSetInterface. Require Import DecidableTypeEx FSetFacts FSetDecide. Set Implicit Arguments. Unset Strict Implicit. Hint Unfold transpose compat_op Proper respectful : fset. Hint Extern 1 (Equivalence _) => constructor; congruence : fset.
First, a functor for Weak Sets in functorial version.
Module WProperties_fun (Import E : DecidableType)(M : WSfun E). Module Import Dec := WDecide_fun E M. Module Import FM := Dec.F (* FSetFacts.WFacts_fun E M *). Import M.forall (x : elt) (s : t), {In x s} + {~ In x s}intros; generalize (mem_iff s x); case (mem x s); intuition. Qed. Definition Add x s s' := forall y, In y s' <-> E.eq x y \/ In y s.forall (x : elt) (s : t), {In x s} + {~ In x s}forall (x : E.t) (s s' : t), Add x s s' <-> s' [=] add x sforall (x : E.t) (s s' : t), Add x s s' <-> s' [=] add x sforall (x : E.t) (s s' : t), (forall y : elt, In y s' <-> E.eq x y \/ In y s) <-> s' [=] add x sx:E.ts, s':tH:forall y : elt, In y s' <-> E.eq x y \/ In y ss' [=] add x sx:E.ts, s':tH:s' [=] add x sy:eltIn y s' <-> E.eq x y \/ In y sx:E.ts, s':tH:forall y : elt, In y s' <-> E.eq x y \/ In y sa:eltIn a s' <-> In a (add x s)x:E.ts, s':tH:s' [=] add x sy:eltIn y s' <-> E.eq x y \/ In y sx:E.ts, s':ta:eltE.eq x a \/ In a s <-> In a (add x s)x:E.ts, s':tH:s' [=] add x sy:eltIn y s' <-> E.eq x y \/ In y sfsetdec. Qed. Ltac expAdd := repeat rewrite Add_Equal. Section BasicProperties. Variable s s' s'' s1 s2 s3 : t. Variable x x' : elt.x:E.ts, s':tH:s' [=] add x sy:eltIn y s' <-> E.eq x y \/ In y ss, s', s'', s1, s2, s3:tx, x':elts [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] ss, s', s'', s1, s2, s3:tx, x':elts [=] s' -> s' [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] s' -> s' [=] ss, s', s'', s1, s2, s3:tx, x':elts1 [=] s2 -> s2 [=] s3 -> s1 [=] s3fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts1 [=] s2 -> s2 [=] s3 -> s1 [=] s3s, s', s'', s1, s2, s3:tx, x':elts [<=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] ss, s', s'', s1, s2, s3:tx, x':elts1 [<=] s2 -> s2 [<=] s3 -> s1 [<=] s3fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts1 [<=] s2 -> s2 [<=] s3 -> s1 [<=] s3s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> s' [<=] s -> s [=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> s' [<=] s -> s [=] s's, s', s'', s1, s2, s3:tx, x':elts [=] s' -> s [<=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] s' -> s [<=] s's, s', s'', s1, s2, s3:tx, x':eltempty [<=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltempty [<=] ss, s', s'', s1, s2, s3:tx, x':elts1 [<=] s2 -> remove x s1 [<=] s2fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts1 [<=] s2 -> remove x s1 [<=] s2s, s', s'', s1, s2, s3:tx, x':elts1 [<=] s3 -> diff s1 s2 [<=] s3fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts1 [<=] s3 -> diff s1 s2 [<=] s3s, s', s'', s1, s2, s3:tx, x':eltIn x s2 -> s1 [<=] s2 -> add x s1 [<=] s2fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s2 -> s1 [<=] s2 -> add x s1 [<=] s2s, s', s'', s1, s2, s3:tx, x':elts1 [<=] s2 -> s1 [<=] add x s2fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts1 [<=] s2 -> s1 [<=] add x s2s, s', s'', s1, s2, s3:tx, x':eltIn x s1 -> s1 [<=] s2 -> In x s2fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s1 -> s1 [<=] s2 -> In x s2s, s', s'', s1, s2, s3:tx, x':elts1 [=] s2 <-> s1 [<=] s2 /\ s2 [<=] s1intuition fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts1 [=] s2 <-> s1 [<=] s2 /\ s2 [<=] s1s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> s [=] emptyfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> s [=] emptys, s', s'', s1, s2, s3:tx, x':elts [=] empty -> Empty sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] empty -> Empty ss, s', s'', s1, s2, s3:tx, x':eltIn x s -> add x s [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s -> add x s [=] ss, s', s'', s1, s2, s3:tx, x':eltadd x (add x' s) [=] add x' (add x s)fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltadd x (add x' s) [=] add x' (add x s)s, s', s'', s1, s2, s3:tx, x':elt~ In x s -> remove x s [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elt~ In x s -> remove x s [=] ss, s', s'', s1, s2, s3:tx, x':elts [=] s' -> remove x s [=] remove x s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] s' -> remove x s [=] remove x s's, s', s'', s1, s2, s3:tx, x':eltIn x s -> add x (remove x s) [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s -> add x (remove x s) [=] ss, s', s'', s1, s2, s3:tx, x':elt~ In x s -> remove x (add x s) [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elt~ In x s -> remove x (add x s) [=] ss, s', s'', s1, s2, s3:tx, x':eltsingleton x [=] add x emptyfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltsingleton x [=] add x emptys, s', s'', s1, s2, s3:tx, x':eltIn x s -> remove x s [=] empty -> singleton x [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s -> remove x s [=] empty -> singleton x [=] ss, s', s'', s1, s2, s3:tx, x':eltunion s s' [=] union s' sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltunion s s' [=] union s' ss, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> union s s' [=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> union s s' [=] s's, s', s'', s1, s2, s3:tx, x':elts [=] s' -> union s s'' [=] union s' s''fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] s' -> union s s'' [=] union s' s''s, s', s'', s1, s2, s3:tx, x':elts' [=] s'' -> union s s' [=] union s s''fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts' [=] s'' -> union s s' [=] union s s''s, s', s'', s1, s2, s3:tx, x':eltunion (union s s') s'' [=] union s (union s' s'')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltunion (union s s') s'' [=] union s (union s' s'')s, s', s'', s1, s2, s3:tx, x':eltadd x s [=] union (singleton x) sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltadd x s [=] union (singleton x) ss, s', s'', s1, s2, s3:tx, x':eltunion (add x s) s' [=] add x (union s s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltunion (add x s) s' [=] add x (union s s')s, s', s'', s1, s2, s3:tx, x':eltunion (remove x s) (add x s') [=] union (add x s) (remove x s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltunion (remove x s) (add x s') [=] union (add x s) (remove x s')s, s', s'', s1, s2, s3:tx, x':eltIn x s -> union (remove x s) (add x s') [=] union s s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s -> union (remove x s) (add x s') [=] union s s's, s', s'', s1, s2, s3:tx, x':elts [<=] union s s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] union s s's, s', s'', s1, s2, s3:tx, x':elts' [<=] union s s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts' [<=] union s s's, s', s'', s1, s2, s3:tx, x':elts [<=] s'' -> s' [<=] s'' -> union s s' [<=] s''fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s'' -> s' [<=] s'' -> union s s' [<=] s''s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> union s s'' [<=] union s' s''fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> union s s'' [<=] union s' s''s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> union s'' s [<=] union s'' s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> union s'' s [<=] union s'' s's, s', s'', s1, s2, s3:tx, x':eltEmpty s -> union s s' [=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> union s s' [=] s's, s', s'', s1, s2, s3:tx, x':eltEmpty s -> union s' s [=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> union s' s [=] s's, s', s'', s1, s2, s3:tx, x':elt~ In x s -> ~ In x s' -> ~ In x (union s s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elt~ In x s -> ~ In x s' -> ~ In x (union s s')s, s', s'', s1, s2, s3:tx, x':eltinter s s' [=] inter s' sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltinter s s' [=] inter s' ss, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> inter s s' [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> inter s s' [=] ss, s', s'', s1, s2, s3:tx, x':elts [=] s' -> inter s s'' [=] inter s' s''fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [=] s' -> inter s s'' [=] inter s' s''s, s', s'', s1, s2, s3:tx, x':elts' [=] s'' -> inter s s' [=] inter s s''fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts' [=] s'' -> inter s s' [=] inter s s''s, s', s'', s1, s2, s3:tx, x':eltinter (inter s s') s'' [=] inter s (inter s' s'')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltinter (inter s s') s'' [=] inter s (inter s' s'')s, s', s'', s1, s2, s3:tx, x':eltinter (union s s') s'' [=] union (inter s s'') (inter s' s'')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltinter (union s s') s'' [=] union (inter s s'') (inter s' s'')s, s', s'', s1, s2, s3:tx, x':eltunion (inter s s') s'' [=] inter (union s s'') (union s' s'')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltunion (inter s s') s'' [=] inter (union s s'') (union s' s'')s, s', s'', s1, s2, s3:tx, x':eltIn x s' -> inter (add x s) s' [=] add x (inter s s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s' -> inter (add x s) s' [=] add x (inter s s')s, s', s'', s1, s2, s3:tx, x':elt~ In x s' -> inter (add x s) s' [=] inter s s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elt~ In x s' -> inter (add x s) s' [=] inter s s's, s', s'', s1, s2, s3:tx, x':eltEmpty s -> Empty (inter s s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> Empty (inter s s')s, s', s'', s1, s2, s3:tx, x':eltEmpty s' -> Empty (inter s s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s' -> Empty (inter s s')s, s', s'', s1, s2, s3:tx, x':eltinter s s' [<=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltinter s s' [<=] ss, s', s'', s1, s2, s3:tx, x':eltinter s s' [<=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltinter s s' [<=] s's, s', s'', s1, s2, s3:tx, x':elts'' [<=] s -> s'' [<=] s' -> s'' [<=] inter s s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts'' [<=] s -> s'' [<=] s' -> s'' [<=] inter s s's, s', s'', s1, s2, s3:tx, x':eltEmpty s -> Empty (diff s s')fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> Empty (diff s s')s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> diff s' s [=] s'fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltEmpty s -> diff s' s [=] s's, s', s'', s1, s2, s3:tx, x':eltdiff s s' [<=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltdiff s s' [<=] ss, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> diff s s' [=] emptyfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':elts [<=] s' -> diff s s' [=] emptys, s', s'', s1, s2, s3:tx, x':eltremove x s [=] diff s (singleton x)fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltremove x s [=] diff s (singleton x)s, s', s'', s1, s2, s3:tx, x':eltinter (diff s s') (inter s s') [=] emptyfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltinter (diff s s') (inter s s') [=] emptys, s', s'', s1, s2, s3:tx, x':eltunion (diff s s') (inter s s') [=] sfsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltunion (diff s s') (inter s s') [=] ss, s', s'', s1, s2, s3:tx, x':eltAdd x s (add x s)expAdd; fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltAdd x s (add x s)s, s', s'', s1, s2, s3:tx, x':eltIn x s -> Add x (remove x s) sexpAdd; fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s -> Add x (remove x s) ss, s', s'', s1, s2, s3:tx, x':eltAdd x s s' -> Add x (union s s'') (union s' s'')expAdd; fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltAdd x s s' -> Add x (union s s'') (union s' s'')s, s', s'', s1, s2, s3:tx, x':eltIn x s'' -> Add x s s' -> Add x (inter s s'') (inter s' s'')expAdd; fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s'' -> Add x s s' -> Add x (inter s s'') (inter s' s'')s, s', s'', s1, s2, s3:tx, x':eltIn x s'' -> Add x s s' -> union s s'' [=] union s' s''expAdd; fsetdec. Qed.s, s', s'', s1, s2, s3:tx, x':eltIn x s'' -> Add x s s' -> union s s'' [=] union s' s''s, s', s'', s1, s2, s3:tx, x':elt~ In x s'' -> Add x s s' -> inter s s'' [=] inter s' s''expAdd; fsetdec. Qed. End BasicProperties. Hint Immediate equal_sym add_remove remove_add union_sym inter_sym: set. Hint Resolve equal_refl equal_trans subset_refl subset_equal subset_antisym subset_trans subset_empty subset_remove_3 subset_diff subset_add_3 subset_add_2 in_subset empty_is_empty_1 empty_is_empty_2 add_equal remove_equal singleton_equal_add union_subset_equal union_equal_1 union_equal_2 union_assoc add_union_singleton union_add union_subset_1 union_subset_2 union_subset_3 inter_subset_equal inter_equal_1 inter_equal_2 inter_assoc union_inter_1 union_inter_2 inter_add_1 inter_add_2 empty_inter_1 empty_inter_2 empty_union_1 empty_union_2 empty_diff_1 empty_diff_2 union_Add inter_Add union_Equal inter_Add_2 not_in_union inter_subset_1 inter_subset_2 inter_subset_3 diff_subset diff_subset_equal remove_diff_singleton diff_inter_empty diff_inter_all Add_add Add_remove Equal_remove add_add : set.s, s', s'', s1, s2, s3:tx, x':elt~ In x s'' -> Add x s s' -> inter s s'' [=] inter s' s''
forall s : t, Empty s <-> elements s = nilforall s : t, Empty s <-> elements s = nils:tEmpty s <-> elements s = nils:t(forall a : elt, ~ In a s) <-> elements s = nils:tH:forall a : elt, ~ In a selements s = nils:tH:elements s = nila:elt~ In a ss:tH:forall a : elt, ~ In a sforall a : elt, ~ List.In a (elements s)s:tH:forall a : elt, ~ In a sH0:forall a : elt, ~ List.In a (elements s)elements s = nils:tH:elements s = nila:elt~ In a ss:tH:forall a0 : elt, ~ In a0 sa:eltH0:List.In a (elements s)Falses:tH:forall a : elt, ~ In a sH0:forall a : elt, ~ List.In a (elements s)elements s = nils:tH:elements s = nila:elt~ In a ss:tH:forall a0 : elt, ~ In a0 sa:eltH0:List.In a (elements s)In a ss:tH:forall a : elt, ~ In a sH0:forall a : elt, ~ List.In a (elements s)elements s = nils:tH:elements s = nila:elt~ In a ss:tH:forall a0 : elt, ~ In a0 sa:eltH0:List.In a (elements s)InA E.eq a (elements s)s:tH:forall a : elt, ~ In a sH0:forall a : elt, ~ List.In a (elements s)elements s = nils:tH:elements s = nila:elt~ In a ss:tH:forall a : elt, ~ In a sH0:forall a : elt, ~ List.In a (elements s)elements s = nils:tH:elements s = nila:elt~ In a ss:tH:forall a : elt, ~ In a se:eltl:list eltH0:forall a : elt, ~ List.In a (e :: l)e :: l = nils:tH:elements s = nila:elt~ In a ss:tH:elements s = nila:elt~ In a ss:tH:elements s = nila:eltH0:In a sFalses:tH:elements s = nila:eltH0:InA E.eq a (elements s)Falserewrite H in H0; destruct H0 as (_,H0); inversion H0. Qed.s:tH:elements s = nila:eltx:E.tH0:E.eq a x /\ List.In x (elements s)Falseelements empty = nilrewrite <-elements_Empty; auto with set. Qed.elements empty = nil
Definition of_list (l : list elt) := List.fold_right add empty l. Definition to_list := elements.forall (l : list elt) (x : elt), In x (of_list l) <-> InA E.eq x lforall (l : list elt) (x : elt), In x (of_list l) <-> InA E.eq x lx:eltIn x empty <-> InA E.eq x nila:eltl:list eltIHl:forall x0 : elt, In x0 (of_list l) <-> InA E.eq x0 lx:eltIn x (add a (of_list l)) <-> InA E.eq x (a :: l)x:eltFalse <-> Falsea:eltl:list eltIHl:forall x0 : elt, In x0 (of_list l) <-> InA E.eq x0 lx:eltIn x (add a (of_list l)) <-> InA E.eq x (a :: l)a:eltl:list eltIHl:forall x0 : elt, In x0 (of_list l) <-> InA E.eq x0 lx:eltIn x (add a (of_list l)) <-> InA E.eq x (a :: l)intuition. Qed.a:eltl:list eltIHl:forall x0 : elt, In x0 (of_list l) <-> InA E.eq x0 lx:eltE.eq a x \/ InA E.eq x l <-> E.eq x a \/ InA E.eq x lforall l : list elt, equivlistA E.eq (to_list (of_list l)) lforall l : list elt, equivlistA E.eq (to_list (of_list l)) lrewrite <- elements_iff; apply of_list_1. Qed.l:list eltx:E.tInA E.eq x (elements (of_list l)) <-> InA E.eq x lforall s : t, of_list (to_list s) [=] sforall s : t, of_list (to_list s) [=] srewrite of_list_1; symmetry; apply elements_iff. Qed.s:ta:eltIn a (of_list (elements s)) <-> In a s
Section Fold.
Alternative specification via fold_right
s:tA:Typei:Af:elt -> A -> Afold f s i = fold_right f i (rev (elements s))s:tA:Typei:Af:elt -> A -> Afold f s i = fold_right f i (rev (elements s))s:tA:Typei:Af:elt -> A -> Afold_left (fun (a : A) (e : elt) => f e a) (elements s) i = fold_right f i (rev (elements s))apply fold_left_rev_right. Qed. Notation NoDup := (NoDupA E.eq). Notation InA := (InA E.eq).s:tA:Typei:Af:elt -> A -> Afold_right f i (rev (elements s)) = fold_left (fun (a : A) (e : elt) => f e a) (elements s) i
In the following lemma, the step hypothesis is deliberately restricted
to the precise set s we are considering.
forall (A : Type) (P : t -> A -> Type) (f : elt -> A -> A) (i : A) (s : t), (forall s' : t, Empty s' -> P s' i) -> (forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)) -> P s (fold f s i)forall (A : Type) (P : t -> A -> Type) (f : elt -> A -> A) (i : A) (s : t), (forall s' : t, Empty s' -> P s' i) -> (forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)) -> P s (fold f s i)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)P s (fold f s i)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)P s (fold_right f i (rev (elements s)))A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltP s (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltforall (x : E.t) (a : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)P s (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s'0 : t, Empty s'0 -> P s'0 iPstep:forall (x0 : elt) (a0 : A) (s'0 s''0 : t), In x0 s -> ~ In x0 s'0 -> Add x0 s'0 s''0 -> P s'0 a0 -> P s''0 (f x0 a0)l:=rev (elements s):list eltx:E.ta:As', s'':tH:InA x lH0:~ In x s'H1:Add x s' s''X:P s' aIn x sA:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)P s (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)P s (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)Hdup:NoDup lP s (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPempty:forall s' : t, Empty s' -> P s' iPstep:forall (x : elt) (a : A) (s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)l:=rev (elements s):list eltPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)Hdup:NoDup lHsame:forall x : elt, In x s <-> InA x lP s (fold_right f i l)(* empty *)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' iPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x nil -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)Hdup:NoDup nilforall s : t, (forall x : elt, In x s <-> InA x nil) -> P s (fold_right f i nil)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s : t, (forall x : elt, In x s <-> InA x l) -> P s (fold_right f i l)forall s : t, (forall x : elt, In x s <-> InA x (a :: l)) -> P s (fold_right f i (a :: l))A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' iPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x nil -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)Hdup:NoDup nils:tHsame:forall x : elt, In x s <-> InA x nilP s iA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s : t, (forall x : elt, In x s <-> InA x l) -> P s (fold_right f i l)forall s : t, (forall x : elt, In x s <-> InA x (a :: l)) -> P s (fold_right f i (a :: l))A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' iPstep':forall (x : E.t) (a : A) (s' s'' : t), InA x nil -> ~ In x s' -> Add x s' s'' -> P s' a -> P s'' (f x a)Hdup:NoDup nils:tHsame:forall x : elt, In x s <-> InA x nilEmpty sA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s : t, (forall x : elt, In x s <-> InA x l) -> P s (fold_right f i l)forall s : t, (forall x : elt, In x s <-> InA x (a :: l)) -> P s (fold_right f i (a :: l))A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' iPstep':forall (x0 : E.t) (a : A) (s' s'' : t), InA x0 nil -> ~ In x0 s' -> Add x0 s' s'' -> P s' a -> P s'' (f x0 a)Hdup:NoDup nils:tHsame:forall x0 : elt, In x0 s <-> InA x0 nilx:elt~ In x sA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s : t, (forall x : elt, In x s <-> InA x l) -> P s (fold_right f i l)forall s : t, (forall x : elt, In x s <-> InA x (a :: l)) -> P s (fold_right f i (a :: l))(* step *)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s : t, (forall x : elt, In x s <-> InA x l) -> P s (fold_right f i l)forall s : t, (forall x : elt, In x s <-> InA x (a :: l)) -> P s (fold_right f i (a :: l))A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)P s (f a (fold_right f i l))A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)~ In a (of_list l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)Add a (of_list l) sA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)P (of_list l) (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)Add a (of_list l) sA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)P (of_list l) (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)forall y : elt, In y s <-> E.eq a y \/ In y (of_list l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)P (of_list l) (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)y:eltIn y s <-> E.eq a y \/ In y (of_list l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)P (of_list l) (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)P (of_list l) (fold_right f i l)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)NoDup lA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)forall x : elt, In x (of_list l) <-> InA x lA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)NoDup lA:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)forall x : elt, In x (of_list l) <-> InA x lexact (of_list_1 l). Qed.A:TypeP:t -> A -> Typef:elt -> A -> Ai:APempty:forall s' : t, Empty s' -> P s' ia:eltl:list eltPstep':forall (x : E.t) (a0 : A) (s' s'' : t), InA x (a :: l) -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)Hdup:NoDup (a :: l)IHl:(forall (x : E.t) (a0 : A) (s' s'' : t), InA x l -> ~ In x s' -> Add x s' s'' -> P s' a0 -> P s'' (f x a0)) -> NoDup l -> forall s0 : t, (forall x : elt, In x s0 <-> InA x l) -> P s0 (fold_right f i l)s:tHsame:forall x : elt, In x s <-> InA x (a :: l)forall x : elt, In x (of_list l) <-> InA x l
Same, with empty and add instead of Empty and Add. In this
case, P must be compatible with equality of sets
forall (A : Type) (P : t -> A -> Type) (f : elt -> A -> A) (i : A) (s : t), (forall (s0 s' : t) (a : A), s0 [=] s' -> P s0 a -> P s' a) -> P empty i -> (forall (x : elt) (a : A) (s' : t), In x s -> ~ In x s' -> P s' a -> P (add x s') (f x a)) -> P s (fold f s i)forall (A : Type) (P : t -> A -> Type) (f : elt -> A -> A) (i : A) (s : t), (forall (s0 s' : t) (a : A), s0 [=] s' -> P s0 a -> P s' a) -> P empty i -> (forall (x : elt) (a : A) (s' : t), In x s -> ~ In x s' -> P s' a -> P (add x s') (f x a)) -> P s (fold f s i)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPmorphism:forall (s0 s' : t) (a : A), s0 [=] s' -> P s0 a -> P s' aPempty:P empty iPstep:forall (x : elt) (a : A) (s' : t), In x s -> ~ In x s' -> P s' a -> P (add x s') (f x a)P s (fold f s i)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPmorphism:forall (s0 s'0 : t) (a : A), s0 [=] s'0 -> P s0 a -> P s'0 aPempty:P empty iPstep:forall (x : elt) (a : A) (s'0 : t), In x s -> ~ In x s'0 -> P s'0 a -> P (add x s'0) (f x a)s':tH:Empty s'P s' iA:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPmorphism:forall (s0 s'0 : t) (a0 : A), s0 [=] s'0 -> P s0 a0 -> P s'0 a0Pempty:P empty iPstep:forall (x0 : elt) (a0 : A) (s'0 : t), In x0 s -> ~ In x0 s'0 -> P s'0 a0 -> P (add x0 s'0) (f x0 a0)x:elta:As', s'':tH:In x sH0:~ In x s'H1:Add x s' s''X:P s' aP s'' (f x a)A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPmorphism:forall (s0 s'0 : t) (a0 : A), s0 [=] s'0 -> P s0 a0 -> P s'0 a0Pempty:P empty iPstep:forall (x0 : elt) (a0 : A) (s'0 : t), In x0 s -> ~ In x0 s'0 -> P s'0 a0 -> P (add x0 s'0) (f x0 a0)x:elta:As', s'':tH:In x sH0:~ In x s'H1:Add x s' s''X:P s' aP s'' (f x a)apply Pmorphism with (add x s'); auto with set. Qed.A:TypeP:t -> A -> Typef:elt -> A -> Ai:As:tPmorphism:forall (s0 s'0 : t) (a0 : A), s0 [=] s'0 -> P s0 a0 -> P s'0 a0Pempty:P empty iPstep:forall (x0 : elt) (a0 : A) (s'0 : t), In x0 s -> ~ In x0 s'0 -> P s'0 a0 -> P (add x0 s'0) (f x0 a0)x:elta:As', s'':tH:In x sH0:~ In x s'H1:s'' [=] add x s'X:P s' aP s'' (f x a)forall (A : Type) (P : A -> Type) (f : elt -> A -> A) (i : A) (s : t), P i -> (forall (x : elt) (a : A), In x s -> P a -> P (f x a)) -> P (fold f s i)intros; apply fold_rec_bis with (P:=fun _ => P); auto. Qed.forall (A : Type) (P : A -> Type) (f : elt -> A -> A) (i : A) (s : t), P i -> (forall (x : elt) (a : A), In x s -> P a -> P (f x a)) -> P (fold f s i)
fold_rec_weak is a weaker principle than fold_rec_bis :
the step hypothesis must here be applicable to any x.
At the same time, it looks more like an induction principle,
and hence can be easier to use.
forall (A : Type) (P : t -> A -> Type) (f : elt -> A -> A) (i : A), (forall (s s' : t) (a : A), s [=] s' -> P s a -> P s' a) -> P empty i -> (forall (x : elt) (a : A) (s : t), ~ In x s -> P s a -> P (add x s) (f x a)) -> forall s : t, P s (fold f s i)intros; apply fold_rec_bis; auto. Qed.forall (A : Type) (P : t -> A -> Type) (f : elt -> A -> A) (i : A), (forall (s s' : t) (a : A), s [=] s' -> P s a -> P s' a) -> P empty i -> (forall (x : elt) (a : A) (s : t), ~ In x s -> P s a -> P (add x s) (f x a)) -> forall s : t, P s (fold f s i)forall (A B : Type) (R : A -> B -> Type) (f : elt -> A -> A) (g : elt -> B -> B) (i : A) (j : B) (s : t), R i j -> (forall (x : elt) (a : A) (b : B), In x s -> R a b -> R (f x a) (g x b)) -> R (fold f s i) (fold g s j)forall (A B : Type) (R : A -> B -> Type) (f : elt -> A -> A) (g : elt -> B -> B) (i : A) (j : B) (s : t), R i j -> (forall (x : elt) (a : A) (b : B), In x s -> R a b -> R (f x a) (g x b)) -> R (fold f s i) (fold g s j)A, B:TypeR:A -> B -> Typef:elt -> A -> Ag:elt -> B -> Bi:Aj:Bs:tRempty:R i jRstep:forall (x : elt) (a : A) (b : B), In x s -> R a b -> R (f x a) (g x b)R (fold f s i) (fold g s j)A, B:TypeR:A -> B -> Typef:elt -> A -> Ag:elt -> B -> Bi:Aj:Bs:tRempty:R i jRstep:forall (x : elt) (a : A) (b : B), In x s -> R a b -> R (f x a) (g x b)R (fold_right f i (rev (elements s))) (fold_right g j (rev (elements s)))A, B:TypeR:A -> B -> Typef:elt -> A -> Ag:elt -> B -> Bi:Aj:Bs:tRempty:R i jRstep:forall (x : elt) (a : A) (b : B), In x s -> R a b -> R (f x a) (g x b)l:=rev (elements s):list eltR (fold_right f i l) (fold_right g j l)A, B:TypeR:A -> B -> Typef:elt -> A -> Ag:elt -> B -> Bi:Aj:Bs:tRempty:R i jRstep:forall (x : elt) (a : A) (b : B), In x s -> R a b -> R (f x a) (g x b)l:=rev (elements s):list eltRstep':forall (x : E.t) (a : A) (b : B), InA x l -> R a b -> R (f x a) (g x b)R (fold_right f i l) (fold_right g j l)induction l; simpl; auto. Qed.A, B:TypeR:A -> B -> Typef:elt -> A -> Ag:elt -> B -> Bi:Aj:BRempty:R i jl:list eltRstep':forall (x : E.t) (a : A) (b : B), InA x l -> R a b -> R (f x a) (g x b)R (fold_right f i l) (fold_right g j l)
From the induction principle on fold, we can deduce some general
induction principles on sets.
forall P : t -> Type, (forall s : t, Empty s -> P s) -> (forall s s' : t, P s -> forall x : elt, ~ In x s -> Add x s s' -> P s') -> forall s : t, P sforall P : t -> Type, (forall s : t, Empty s -> P s) -> (forall s s' : t, P s -> forall x : elt, ~ In x s -> Add x s s' -> P s') -> forall s : t, P sapply (@fold_rec _ (fun s _ => P s) (fun _ _ => tt) tt s); eauto. Qed.P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : elt, ~ In x s0 -> Add x s0 s' -> P s's:tP sforall P : t -> Type, (forall s s' : t, s [=] s' -> P s -> P s') -> P empty -> (forall (x : elt) (s : t), ~ In x s -> P s -> P (add x s)) -> forall s : t, P sforall P : t -> Type, (forall s s' : t, s [=] s' -> P s -> P s') -> P empty -> (forall (x : elt) (s : t), ~ In x s -> P s -> P (add x s)) -> forall s : t, P sapply (@fold_rec_bis _ (fun s _ => P s) (fun _ _ => tt) tt s); eauto. Qed.P:t -> TypeX:forall s0 s' : t, s0 [=] s' -> P s0 -> P s'X0:P emptyX1:forall (x : elt) (s0 : t), ~ In x s0 -> P s0 -> P (add x s0)s:tP s
fold can be used to reconstruct the same initial set.
forall s : t, fold add s empty [=] sforall s : t, fold add s empty [=] ss:tfold add s empty [=] ss:tforall (x : elt) (a s' s'' : t), In x s -> ~ In x s' -> Add x s' s'' -> a [=] s' -> add x a [=] s''rewrite H2; rewrite Add_Equal in H1; auto with set. Qed.s:tx:elta, s', s'':tH:In x sH0:~ In x s'H1:Add x s' s''H2:a [=] s'add x a [=] s''
When FSets was first designed, the order in which Ocaml's Set.fold
takes the set elements was unspecified. This specification reflects
this fact:
forall (s : t) (A : Type) (i : A) (f : elt -> A -> A), exists l : list elt, NoDup l /\ (forall x : elt, In x s <-> InA x l) /\ fold f s i = fold_right f i lforall (s : t) (A : Type) (i : A) (f : elt -> A -> A), exists l : list elt, NoDup l /\ (forall x : elt, In x s <-> InA x l) /\ fold f s i = fold_right f i ls:tA:Typei:Af:elt -> A -> ANoDup (rev (elements s))s:tA:Typei:Af:elt -> A -> A(forall x : elt, In x s <-> InA x (rev (elements s))) /\ fold f s i = fold_right f i (rev (elements s))s:tA:Typei:Af:elt -> A -> A(forall x : elt, In x s <-> InA x (rev (elements s))) /\ fold f s i = fold_right f i (rev (elements s))s:tA:Typei:Af:elt -> A -> Ax:eltIn x s <-> InA x (rev (elements s))s:tA:Typei:Af:elt -> A -> Afold f s i = fold_right f i (rev (elements s))s:tA:Typei:Af:elt -> A -> Ax:elt(exists y : E.t, E.eq x y /\ List.In y (elements s)) <-> (exists y : E.t, E.eq x y /\ List.In y (rev (elements s)))s:tA:Typei:Af:elt -> A -> Afold f s i = fold_right f i (rev (elements s))apply fold_spec_right. Qed.s:tA:Typei:Af:elt -> A -> Afold f s i = fold_right f i (rev (elements s))
An alternate (and previous) specification for fold was based on
the recursive structure of a set. It is now lemmas fold_1 and
fold_2.
forall (s : t) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), Empty s -> eqA (fold f s i) iforall (s : t) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), Empty s -> eqA (fold f s i) is:tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:forall a : elt, ~ In a sl:list eltH1:NoDup lH2:forall x : elt, In x s <-> InA x lH3:fold f s i = fold_right f i leqA (fold f s i) is:tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:forall a : elt, ~ In a sl:list eltH1:NoDup lH2:forall x : elt, In x s <-> InA x leqA (fold_right f i l) is:tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> Al:list eltH1:NoDup lH:forall a : elt, ~ In a sH2:forall x : elt, In x s <-> InA x nileqA i is:tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> Al:list eltH1:NoDup le:eltl0:list eltH:forall a : elt, ~ In a sH2:forall x : elt, In x s <-> InA x (e :: l0)eqA (f e (fold_right f i l0)) is:tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> Al:list eltH1:NoDup le:eltl0:list eltH:forall a : elt, ~ In a sH2:forall x : elt, In x s <-> InA x (e :: l0)eqA (f e (fold_right f i l0)) ielim (H2 e); intuition. Qed.s:tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> Al:list eltH1:NoDup le:eltl0:list eltH:forall a : elt, ~ In a sH2:forall x : elt, In x s <-> InA x (e :: l0)In e sforall (s s' : t) (x : elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), compat_op E.eq eqA f -> transpose eqA f -> ~ In x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i))forall (s s' : t) (x : elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), compat_op E.eq eqA f -> transpose eqA f -> ~ In x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i))s, s':tx:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:transpose eqA fH1:~ In x sH2:Add x s s'l:list eltHl:NoDup lHl1:forall x0 : elt, In x0 s <-> InA x0 lHl2:fold f s i = fold_right f i ll':list eltHl':NoDup l'Hl'1:forall x0 : elt, In x0 s' <-> InA x0 l'Hl'2:fold f s' i = fold_right f i l'eqA (fold f s' i) (f x (fold f s i))s, s':tx:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:transpose eqA fH1:~ In x sH2:Add x s s'l:list eltHl:NoDup lHl1:forall x0 : elt, In x0 s <-> InA x0 ll':list eltHl':NoDup l'Hl'1:forall x0 : elt, In x0 s' <-> InA x0 l'eqA (fold_right f i l') (f x (fold_right f i l))s, s':tx:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:transpose eqA fH1:~ In x sH2:Add x s s'l:list eltHl:NoDup lHl1:forall x0 : elt, In x0 s <-> InA x0 ll':list eltHl':NoDup l'Hl'1:forall x0 : elt, In x0 s' <-> InA x0 l'~ InA x ls, s':tx:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:transpose eqA fH1:~ In x sH2:Add x s s'l:list eltHl:NoDup lHl1:forall x0 : elt, In x0 s <-> InA x0 ll':list eltHl':NoDup l'Hl'1:forall x0 : elt, In x0 s' <-> InA x0 l'equivlistA E.eq l' (x :: l)intros a; rewrite InA_cons; rewrite <- Hl1; rewrite <- Hl'1; rewrite (H2 a); intuition. Qed.s, s':tx:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:transpose eqA fH1:~ In x sH2:Add x s s'l:list eltHl:NoDup lHl1:forall x0 : elt, In x0 s <-> InA x0 ll':list eltHl':NoDup l'Hl'1:forall x0 : elt, In x0 s' <-> InA x0 l'equivlistA E.eq l' (x :: l)
In fact, fold on empty sets is more than equivalent to
the initial element, it is Leibniz-equal to it.
forall (s : t) (A : Type) (i : A) (f : elt -> A -> A), Empty s -> fold f s i = iforall (s : t) (A : Type) (i : A) (f : elt -> A -> A), Empty s -> fold f s i = is:tA:Typei:Af:elt -> A -> AH:Empty sfold f s i = irewrite elements_Empty in H; rewrite H; simpl; auto. Qed. Section Fold_More. Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA). Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f)(Ass:transpose eqA f).s:tA:Typei:Af:elt -> A -> AH:Empty sfold_left (fun (a : A) (e : elt) => f e a) (elements s) i = iA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), eqA (fold f s (f x i)) (f x (fold f s i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), eqA (fold f s (f x i)) (f x (fold f s i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx:elteqA (fold f s (f x i)) (f x (fold f s i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx:elteqA (f x i) (f x i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx, x0:elta, b:AH:In x0 sH0:eqA a (f x b)eqA (f x0 a) (f x (f x0 b))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx, x0:elta, b:AH:In x0 sH0:eqA a (f x b)eqA (f x0 a) (f x (f x0 b))apply Comp; auto with *. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx, x0:elta, b:AH:In x0 sH0:eqA a (f x b)eqA (f x0 a) (f x0 (f x b))
A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i i' : A) (s : t), eqA i i' -> eqA (fold f s i) (fold f s i')A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i i' : A) (s : t), eqA i i' -> eqA (fold f s i) (fold f s i')A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi, i':As:tH:eqA i i'eqA (fold f s i) (fold f s i')intros; apply Comp; auto with *. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi, i':As:tH:eqA i i'forall (x : elt) (a b : A), In x s -> eqA a b -> eqA (f x a) (f x b)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), s [=] s' -> eqA (fold f s i) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), s [=] s' -> eqA (fold f s i) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tH:Empty ss':tH0:s [=] s'eqA (fold f s i) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (fold f s' i) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tH:Empty ss':tH0:s [=] s'eqA (fold f s i) iA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tH:Empty ss':tH0:s [=] s'eqA i (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (fold f s' i) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tH:Empty ss':tH0:s [=] s'eqA i (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (fold f s' i) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tH:Empty ss':tH0:s [=] s'Empty s'A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (fold f s' i) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (fold f s' i) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (fold f s' i) (f x (fold f s i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (f x (fold f s i)) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0eqA (f x (fold f s i)) (fold f s'0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:Add x s s's'0:tH2:s' [=] s'0Add x s s'0rewrite <- H2; auto. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall s'1 : t, s [=] s'1 -> eqA (fold f s i) (fold f s'1 i)x:eltH0:~ In x sH1:forall y0 : elt, In y0 s' <-> E.eq x y0 \/ In y0 ss'0:tH2:s' [=] s'0y:eltIn y s'0 <-> E.eq x y \/ In y s
A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall i : A, fold f empty i = iintros i; apply fold_1b; auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall i : A, fold f empty i = iA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), ~ In x s -> eqA (fold f (add x s) i) (f x (fold f s i))intros; apply fold_2 with (eqA := eqA); auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), ~ In x s -> eqA (fold f (add x s) i) (f x (fold f s i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), In x s -> eqA (fold f (add x s) i) (fold f s i)intros; apply fold_equal; auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), In x s -> eqA (fold f (add x s) i) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), In x s -> eqA (f x (fold f (remove x s) i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), In x s -> eqA (f x (fold f (remove x s) i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx:eltH:In x seqA (f x (fold f (remove x s) i)) (fold f s i)apply fold_2 with (eqA:=eqA); auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx:eltH:In x seqA (fold f s i) (f x (fold f (remove x s) i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), ~ In x s -> eqA (fold f (remove x s) i) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s : t) (x : elt), ~ In x s -> eqA (fold f (remove x s) i) (fold f s i)apply fold_equal; auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As:tx:eltH:~ In x seqA (fold f (remove x s) i) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f (union s s') (fold f (inter s s') i)) (fold f s' (fold f (inter s s') i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f s' (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f s' (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f s' (fold f (inter s s') i)) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f s' i) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f (inter s s') i) iA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f s' i) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s:tH:Empty seqA (fold f s' i) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'0:tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s'0eqA (fold f (union s'0 s') (fold f (inter s'0 s') i)) (fold f s'0 (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))(* In x s' *)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f (union s'' s') (f x (fold f (inter s s') i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (f x (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (inter s'' s') i) (f x (fold f (inter s s') i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (f x (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'~ In x (inter s s')A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (f x (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (f x (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (f x (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s'' s') (f x (fold f (inter s s') i))) (fold f (union s s') (f x (fold f (inter s s') i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s s') (f x (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'union s'' s' [=] union s s'A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s s') (f x (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s s') (f x (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (fold f (union s s') (f x (fold f (inter s s') i))) (f x (fold f (union s s') (fold f (inter s s') i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''i0:In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))(* ~(In x s') *)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s'' s') (fold f (inter s'' s') i)) (f x (fold f (union s s') (fold f (inter s'' s') i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s'' s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s'' s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s'' s') i))) (f x (fold f (union s s') (fold f (inter s s') i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (union s s') (fold f (inter s'' s') i)) (fold f (union s s') (fold f (inter s s') i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (fold f (inter s'' s') i) (fold f (inter s s') i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'inter s'' s' [=] inter s s'A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f (union s s') (fold f (inter s s') i))) (f x (fold f s (fold f s' i)))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))symmetry; apply fold_2 with (eqA:=eqA); auto. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As', s, s'':tH:eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))x:eltH0:~ In x sH1:Add x s s''n:~ In x s'eqA (f x (fold f s (fold f s' i))) (fold f s'' (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), eqA (fold f (diff s s') (fold f (inter s s') i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), eqA (fold f (diff s s') (fold f (inter s s') i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f (diff s s') (fold f (inter s s') i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f (diff s s') (fold f (inter s s') i)) (fold f (union (diff s s') (inter s s')) (fold f (inter (diff s s') (inter s s')) i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f (union (diff s s') (inter s s')) (fold f (inter (diff s s') (inter s s')) i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f (union (diff s s') (inter s s')) (fold f (inter (diff s s') (inter s s')) i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f (union (diff s s') (inter s s')) (fold f (inter (diff s s') (inter s s')) i)) (fold f s (fold f (inter (diff s s') (inter s s')) i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f s (fold f (inter (diff s s') (inter s s')) i)) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f s (fold f (inter (diff s s') (inter s s')) i)) (fold f s i)apply fold_1; auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':teqA (fold f (inter (diff s s') (inter s s')) i) iA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), (forall x : elt, ~ (In x s /\ In x s')) -> eqA (fold f (union s s') i) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fforall (i : A) (s s' : t), (forall x : elt, ~ (In x s /\ In x s')) -> eqA (fold f (union s s') i) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA (fold f (union s s') i) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA (fold f (union s s') i) (fold f (union s s') (fold f (inter s s') i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA i (fold f (inter s s') i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')Empty (inter s s')A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))apply fold_union_inter; auto. Qed. End Fold_More.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tH:forall x : elt, ~ (In x s /\ In x s')eqA (fold f (union s s') (fold f (inter s s') i)) (fold f s (fold f s' i))forall (s : t) (p : nat), fold (fun _ : elt => S) s p = fold (fun _ : elt => S) s 0 + pforall (s : t) (p : nat), fold (fun _ : elt => S) s p = fold (fun _ : elt => S) s 0 + papply fold_rel with (R:=fun u v => u = v + p); simpl; auto. Qed. End Fold.s:tp:natfold (fun _ : elt => S) s p = fold (fun _ : elt => S) s 0 + p
forall s : t, cardinal s = fold (fun _ : elt => S) s 0forall s : t, cardinal s = fold (fun _ : elt => S) s 0symmetry; apply fold_left_length; auto. Qed.s:tlength (elements s) = fold_left (fun (a : nat) (_ : elt) => S a) (elements s) 0
forall s : t, exists l : list elt, NoDupA E.eq l /\ (forall x : elt, In x s <-> InA E.eq x l) /\ cardinal s = length lintros; exists (elements s); intuition; apply cardinal_1. Qed.forall s : t, exists l : list elt, NoDupA E.eq l /\ (forall x : elt, In x s <-> InA E.eq x l) /\ cardinal s = length lforall s : t, Empty s -> cardinal s = 0intros; rewrite cardinal_fold; apply fold_1; auto with fset. Qed.forall s : t, Empty s -> cardinal s = 0forall (s s' : t) (x : elt), ~ In x s -> Add x s s' -> cardinal s' = S (cardinal s)forall (s s' : t) (x : elt), ~ In x s -> Add x s s' -> cardinal s' = S (cardinal s)s, s':tx:eltH:~ In x sH0:Add x s s'fold (fun _ : elt => S) s' 0 = S (fold (fun _ : elt => S) s 0)apply fold_2; auto with fset. Qed.s, s':tx:eltH:~ In x sH0:Add x s s'fold (fun _ : elt => (fun _ : elt => S) x) s' 0 = (fun _ : elt => S) x (fold (fun _ : elt => (fun _ : elt => S) x) s 0)
forall s : t, Empty s <-> cardinal s = 0forall s : t, Empty s <-> cardinal s = 0s:tEmpty s <-> cardinal s = 0destruct (elements s); intuition; discriminate. Qed.s:telements s = nil <-> length (elements s) = 0forall s : t, cardinal s = 0 -> Empty sintros; rewrite cardinal_Empty; auto. Qed. Hint Resolve cardinal_inv_1 : fset.forall s : t, cardinal s = 0 -> Empty sforall (s : t) (n : nat), cardinal s = S n -> {x : elt | In x s}forall (s : t) (n : nat), cardinal s = S n -> {x : elt | In x s}s:tn:natH:length (elements s) = S n{x : elt | In x s}s:tn:natH:length (elements s) = S n(forall x : elt, InA E.eq x (elements s) -> In x s) -> {x : elt | In x s}exists e; auto. Qed.s:tn:nate:eltl:list eltH:length (e :: l) = S n(forall x : elt, InA E.eq x (e :: l) -> In x s) -> {x : elt | In x s}forall s : t, cardinal s <> 0 -> {x : elt | In x s}intro; generalize (@cardinal_inv_2 s); destruct cardinal; [intuition|eauto]. Qed.forall s : t, cardinal s <> 0 -> {x : elt | In x s}
forall s s' : t, s [=] s' -> cardinal s = cardinal s'forall s s' : t, s [=] s' -> cardinal s = cardinal s's, s':tH:s [=] s'cardinal s' = cardinal sn:natforall s s' : t, cardinal s = n -> s [=] s' -> cardinal s' = ns, s':tHeqn:cardinal s = 0H:s [=] s'cardinal s' = 0n:natIHn:forall s0 s'0 : t, cardinal s0 = n -> s0 [=] s'0 -> cardinal s'0 = ns, s':tHeqn:cardinal s = S nH:s [=] s'cardinal s' = S nn:natIHn:forall s0 s'0 : t, cardinal s0 = n -> s0 [=] s'0 -> cardinal s'0 = ns, s':tHeqn:cardinal s = S nH:s [=] s'cardinal s' = S nn:natIHn:forall s0 s'0 : t, cardinal s0 = n -> s0 [=] s'0 -> cardinal s'0 = ns, s':tHeqn:cardinal s = S nH:s [=] s'x:eltH2:In x scardinal s' = S nn:natIHn:forall s0 s'0 : t, cardinal s0 = n -> s0 [=] s'0 -> cardinal s'0 = ns, s':tH:s [=] s'x:eltH2:In x scardinal s = S n -> cardinal s' = S nrewrite (cardinal_2 (s:=remove x s') (s':=s') (x:=x)); eauto with set. Qed.n:natIHn:forall s0 s'0 : t, cardinal s0 = n -> s0 [=] s'0 -> cardinal s'0 = ns, s':tH:s [=] s'x:eltH2:In x sS (cardinal (remove x s)) = S n -> cardinal s' = S nforall x y : t, x [=] y -> cardinal x = cardinal yexact Equal_cardinal. Qed. Hint Resolve Add_add Add_remove Equal_remove cardinal_inv_1 Equal_cardinal : fset.forall x y : t, x [=] y -> cardinal x = cardinal y
cardinal empty = 0rewrite cardinal_fold; apply fold_1; auto with set fset. Qed. Hint Immediate empty_cardinal cardinal_1 : set.cardinal empty = 0forall x : elt, cardinal (singleton x) = 1forall x : elt, cardinal (singleton x) = 1x:eltcardinal (singleton x) = 1x:eltcardinal (add x empty) = 1apply cardinal_2 with x; auto with set. Qed. Hint Resolve singleton_cardinal: set.x:eltcardinal (add x empty) = S (cardinal empty)forall s s' : t, cardinal (diff s s') + cardinal (inter s s') = cardinal sforall s s' : t, cardinal (diff s s') + cardinal (inter s s') = cardinal ss, s':tfold (fun _ : elt => S) (diff s s') 0 + fold (fun _ : elt => S) (inter s s') 0 = fold (fun _ : elt => S) s 0apply fold_diff_inter with (eqA:=@Logic.eq nat); auto with fset. Qed.s, s':tfold (fun _ : elt => S) (diff s s') (fold (fun _ : elt => S) (inter s s') 0) = fold (fun _ : elt => S) s 0forall s s' : t, (forall x : elt, ~ (In x s /\ In x s')) -> cardinal (union s s') = cardinal s + cardinal s'forall s s' : t, (forall x : elt, ~ (In x s /\ In x s')) -> cardinal (union s s') = cardinal s + cardinal s's, s':tH:forall x : elt, ~ (In x s /\ In x s')fold (fun _ : elt => S) (union s s') 0 = fold (fun _ : elt => S) s 0 + fold (fun _ : elt => S) s' 0apply fold_union; auto with fset. Qed.s, s':tH:forall x : elt, ~ (In x s /\ In x s')fold (fun _ : elt => S) (union s s') 0 = fold (fun _ : elt => S) s (fold (fun _ : elt => S) s' 0)forall s s' : t, s [<=] s' -> cardinal s <= cardinal s'forall s s' : t, s [<=] s' -> cardinal s <= cardinal s's, s':tH:s [<=] s'cardinal s <= cardinal s's, s':tH:s [<=] s'cardinal s <= cardinal (diff s' s) + cardinal (inter s' s)rewrite (inter_subset_equal H); auto with arith. Qed.s, s':tH:s [<=] s'cardinal s <= cardinal (diff s' s) + cardinal (inter s s')forall (s s' : t) (x : elt), s [<=] s' -> In x s' -> ~ In x s -> cardinal s < cardinal s'forall (s s' : t) (x : elt), s [<=] s' -> In x s' -> ~ In x s -> cardinal s < cardinal s's, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x scardinal s < cardinal s's, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x scardinal s < cardinal (diff s' s) + cardinal (inter s' s)s, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x scardinal s < cardinal (diff s' s) + cardinal (inter s s')s, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x scardinal s < cardinal (diff s' s) + cardinal ss, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x s(cardinal (diff s' s) = 0 -> Empty (diff s' s)) -> cardinal s < cardinal (diff s' s) + cardinal ss, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x s(0 = 0 -> Empty (diff s' s)) -> cardinal s < 0 + cardinal ss, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x sn:nat(S n = 0 -> Empty (diff s' s)) -> cardinal s < S n + cardinal ss, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x sH2:0 = 0 -> Empty (diff s' s)In x (diff s' s)s, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x sn:nat(S n = 0 -> Empty (diff s' s)) -> cardinal s < S n + cardinal ss, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x sn:nat(S n = 0 -> Empty (diff s' s)) -> cardinal s < S n + cardinal ss, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x sn:natcardinal s < S n + cardinal sapply Plus.plus_lt_le_compat; auto with arith. Qed.s, s':tx:eltH:s [<=] s'H0:In x s'H1:~ In x sn:nat0 + cardinal s < S n + cardinal sforall s s' : t, cardinal (union s s') + cardinal (inter s s') = cardinal s + cardinal s'forall s s' : t, cardinal (union s s') + cardinal (inter s s') = cardinal s + cardinal s's, s':tcardinal (union s s') + cardinal (inter s s') = cardinal s + cardinal s's, s':tfold (fun _ : elt => S) (union s s') 0 + fold (fun _ : elt => S) (inter s s') 0 = fold (fun _ : elt => S) s 0 + fold (fun _ : elt => S) s' 0apply fold_union_inter with (eqA:=@Logic.eq nat); auto with fset. Qed.s, s':tfold (fun _ : elt => S) (union s s') (fold (fun _ : elt => S) (inter s s') 0) = fold (fun _ : elt => S) s (fold (fun _ : elt => S) s' 0)forall s s' : t, cardinal (union s s') = cardinal s + cardinal s' - cardinal (inter s s')forall s s' : t, cardinal (union s s') = cardinal s + cardinal s' - cardinal (inter s s')s, s':tcardinal (union s s') = cardinal s + cardinal s' - cardinal (inter s s')s, s':tcardinal (union s s') = cardinal (union s s') + cardinal (inter s s') - cardinal (inter s s')auto with arith. Qed.s, s':tcardinal (union s s') = cardinal (inter s s') + cardinal (union s s') - cardinal (inter s s')forall s s' : t, cardinal (union s s') <= cardinal s + cardinal s'forall s s' : t, cardinal (union s s') <= cardinal s + cardinal s'intros; rewrite <- H; auto with arith. Qed.s, s':tcardinal (union s s') + cardinal (inter s s') = cardinal s + cardinal s' -> cardinal (union s s') <= cardinal s + cardinal s'forall (s : t) (x : elt), In x s -> cardinal (add x s) = cardinal sauto with set fset. Qed.forall (s : t) (x : elt), In x s -> cardinal (add x s) = cardinal sforall (s : t) (x : elt), ~ In x s -> cardinal (add x s) = S (cardinal s)forall (s : t) (x : elt), ~ In x s -> cardinal (add x s) = S (cardinal s)s:tx:eltH:~ In x scardinal (add x s) = S (cardinal s)change S with ((fun _ => S) x); apply fold_add with (eqA:=@Logic.eq nat); auto with fset. Qed.s:tx:eltH:~ In x sfold (fun _ : elt => S) (add x s) 0 = S (fold (fun _ : elt => S) s 0)forall (s : t) (x : elt), In x s -> S (cardinal (remove x s)) = cardinal sforall (s : t) (x : elt), In x s -> S (cardinal (remove x s)) = cardinal ss:tx:eltH:In x sS (cardinal (remove x s)) = cardinal ss:tx:eltH:In x sS (fold (fun _ : elt => S) (remove x s) 0) = fold (fun _ : elt => S) s 0apply remove_fold_1 with (eqA:=@Logic.eq nat); auto with fset. Qed.s:tx:eltH:In x s(fun _ : elt => S) x (fold (fun _ : elt => (fun _ : elt => S) x) (remove x s) 0) = fold (fun _ : elt => (fun _ : elt => S) x) s 0forall (s : t) (x : elt), ~ In x s -> cardinal (remove x s) = cardinal sauto with set fset. Qed. Hint Resolve subset_cardinal union_cardinal add_cardinal_1 add_cardinal_2 : fset. End WProperties_fun.forall (s : t) (x : elt), ~ In x s -> cardinal (remove x s) = cardinal 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 Properties functor which is meant to be
used on modules (M:S) can simply be an alias of WProperties.
Module WProperties (M:WS) := WProperties_fun M.E M. Module Properties := WProperties.
Now comes some properties specific to the element ordering,
invalid for Weak Sets.
Module OrdProperties (M:S). Module ME:=OrderedTypeFacts(M.E). Module Import P := Properties M. Import FM. Import M.E. Import M.
First, a specialized version of SortA_equivlistA_eqlistA:
forall l l' : list elt, Sorted E.lt l -> Sorted E.lt l' -> equivlistA E.eq l l' -> eqlistA E.eq l l'apply SortA_equivlistA_eqlistA; eauto with *. Qed. Definition gtb x y := match E.compare x y with GT _ => true | _ => false end. Definition leb x := fun y => negb (gtb x y). Definition elements_lt x s := List.filter (gtb x) (elements s). Definition elements_ge x s := List.filter (leb x) (elements s).forall l l' : list elt, Sorted E.lt l -> Sorted E.lt l' -> equivlistA E.eq l l' -> eqlistA E.eq l l'forall x y : E.t, gtb x y = true <-> E.lt y xintros; unfold gtb; destruct (E.compare x y); intuition; try discriminate; ME.order. Qed.forall x y : E.t, gtb x y = true <-> E.lt y xforall x y : E.t, leb x y = true <-> ~ E.lt y xintros; unfold leb, gtb; destruct (E.compare x y); intuition; try discriminate; ME.order. Qed.forall x y : E.t, leb x y = true <-> ~ E.lt y xforall x : E.t, Proper (E.eq ==> Logic.eq) (gtb x)forall x : E.t, Proper (E.eq ==> Logic.eq) (gtb x)x, a, b:E.tH:E.eq a bgtb x a = gtb x bx, a, b:E.tH:E.eq a btrue = true <-> E.lt a x -> false = true <-> E.lt b x -> true = falsex, a, b:E.tH:E.eq a bfalse = true <-> E.lt a x -> true = true <-> E.lt b x -> false = truex, a, b:E.tH:E.eq a bH0:true = true <-> E.lt a xH1:false = true <-> E.lt b xtrue = falsex, a, b:E.tH:E.eq a bfalse = true <-> E.lt a x -> true = true <-> E.lt b x -> false = truex, a, b:E.tH:E.eq a bH0:true = true <-> E.lt a xH1:false = true <-> E.lt b xE.lt b xx, a, b:E.tH:E.eq a bfalse = true <-> E.lt a x -> true = true <-> E.lt b x -> false = truex, a, b:E.tH:E.eq a bH0:true = true <-> E.lt a xH1:false = true <-> E.lt b xE.lt a xx, a, b:E.tH:E.eq a bfalse = true <-> E.lt a x -> true = true <-> E.lt b x -> false = truex, a, b:E.tH:E.eq a bfalse = true <-> E.lt a x -> true = true <-> E.lt b x -> false = truex, a, b:E.tH:E.eq a bH0:false = true <-> E.lt a xH1:true = true <-> E.lt b xfalse = truex, a, b:E.tH:E.eq a bH0:false = true <-> E.lt a xH1:true = true <-> E.lt b xE.lt a xrewrite <- H1; auto. Qed.x, a, b:E.tH:E.eq a bH0:false = true <-> E.lt a xH1:true = true <-> E.lt b xE.lt b xforall x : E.t, Proper (E.eq ==> Logic.eq) (leb x)forall x : E.t, Proper (E.eq ==> Logic.eq) (leb x)f_equal; apply gtb_compat; auto. Qed. Hint Resolve gtb_compat leb_compat : fset.x, a, b:E.tH:E.eq a bnegb (gtb x a) = negb (gtb x b)forall (x : E.t) (s : t), elements s = elements_lt x s ++ elements_ge x sforall (x : E.t) (s : t), elements s = elements_lt x s ++ elements_ge x sx:E.ts:telements s = List.filter (gtb x) (elements s) ++ List.filter (fun y : E.t => negb (gtb x y)) (elements s)x:E.ts:tforall x0 y : E.t, gtb x x0 = true -> gtb x y = false -> E.lt x0 yx:E.ts:tx0, y:E.tH:gtb x x0 = trueH0:gtb x y = falseE.lt x0 yx:E.ts:tx0, y:E.tH:E.lt x0 xH0:gtb x y = falseE.lt x0 yx:E.ts:tx0, y:E.tH:E.lt x0 xH0:gtb x y = false~ E.lt y xx:E.ts:tx0, y:E.tH:E.lt x0 xH0:gtb x y = falseH1:~ E.lt y xE.lt x0 yME.order. Qed.x:E.ts:tx0, y:E.tH:E.lt x0 xH0:gtb x y = falseH1:~ E.lt y xE.lt x0 yforall (s s' : t) (x : elt), ~ In x s -> Add x s s' -> eqlistA E.eq (elements s') (elements_lt x s ++ x :: elements_ge x s)forall (s s' : t) (x : elt), ~ In x s -> Add x s s' -> eqlistA E.eq (elements s') (elements_lt x s ++ x :: elements_ge x s)s, s':tx:eltH:~ In x sH0:Add x s s'eqlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'Sorted E.lt (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'Sorted E.lt (List.filter (gtb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'Sorted E.lt (x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'Sorted E.lt (x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'Sorted E.lt (List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'HdRel E.lt x (List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'HdRel E.lt x (List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'forall y : E.t, InA E.eq y (List.filter (leb x) (elements s)) -> E.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:InA E.eq y (List.filter (leb x) (elements s))E.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:InA E.eq y (elements s)H2:leb x y = trueE.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:InA E.eq y (elements s)H2:~ E.lt y xE.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:In y sH2:~ E.lt y xE.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:In y sH2:~ E.lt y x~ E.eq x ys, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:In y sH2:~ E.lt y xH3:~ E.eq x yE.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'y:E.tH1:In y sH2:~ E.lt y xH3:~ E.eq x yE.lt x ys, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (List.filter (gtb x) (elements s)) -> InA E.eq y (x :: List.filter (leb x) (elements s)) -> E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (List.filter (gtb x) (elements s))H2:InA E.eq y (x :: List.filter (leb x) (elements s))E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:gtb x x0 = trueH2:InA E.eq y (x :: List.filter (leb x) (elements s))E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.lt x0 xH2:InA E.eq y (x :: List.filter (leb x) (elements s))E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.lt x0 xH4:E.eq y xE.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.lt x0 xH4:InA E.eq y (List.filter (leb x) (elements s))E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.lt x0 xH4:InA E.eq y (List.filter (leb x) (elements s))E.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.lt x0 xH2:InA E.eq y (elements s)H4:leb x y = trueE.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.lt x0 xH2:InA E.eq y (elements s)H4:~ E.lt y xE.lt x0 ys, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'equivlistA E.eq (elements s') (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'a:E.tInA E.eq a (elements s') <-> InA E.eq a (List.filter (gtb x) (elements s) ++ x :: List.filter (leb x) (elements s))s, s':tx:eltH:~ In x sH0:Add x s s'a:E.tE.eq x a \/ In a s <-> InA E.eq a (elements s) /\ E.lt a x \/ E.eq a x \/ InA E.eq a (elements s) /\ ~ E.lt a xs, s':tx:eltH:In x s -> FalseH0:Add x s s'a:E.tH2:In a sInA E.eq a (elements s) /\ E.lt a x \/ E.eq a x \/ InA E.eq a (elements s) /\ (E.lt a x -> False)fold (~E.lt a x); auto with *. Qed. Definition Above x s := forall y, In y s -> E.lt y x. Definition Below x s := forall y, In y s -> E.lt x y.s, s':tx:eltH:In x s -> FalseH0:Add x s s'a:E.tH2:In a sl:E.lt x aInA E.eq a (elements s) /\ E.lt a x \/ E.eq a x \/ InA E.eq a (elements s) /\ (E.lt a x -> False)forall (s s' : t) (x : E.t), Above x s -> Add x s s' -> eqlistA E.eq (elements s') (elements s ++ x :: nil)forall (s s' : t) (x : E.t), Above x s -> Add x s s' -> eqlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'eqlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'Sorted E.lt (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (elements s) -> InA E.eq y (x :: nil) -> E.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H2:InA E.eq y (x :: nil)E.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:E.eq y xE.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:InA E.eq y nilE.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'x0, y:E.tH1:In x0 sH3:E.eq y xE.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:InA E.eq y nilE.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (elements s)H3:InA E.eq y nilE.lt x0 ys, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'equivlistA E.eq (elements s') (elements s ++ x :: nil)s, s':tx:E.tH:Above x sH0:Add x s s'a:E.tInA E.eq a (elements s') <-> InA E.eq a (elements s ++ x :: nil)do 2 rewrite <- elements_iff; rewrite (H0 a); intuition. Qed.s, s':tx:E.tH:Above x sH0:Add x s s'a:E.tInA E.eq a (elements s') <-> InA E.eq a (elements s) \/ E.eq a x \/ Falseforall (s s' : t) (x : E.t), Below x s -> Add x s s' -> eqlistA E.eq (elements s') (x :: elements s)forall (s s' : t) (x : E.t), Below x s -> Add x s s' -> eqlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'eqlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'Sorted E.lt (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'Sorted E.lt ((x :: nil) ++ elements s)s, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'forall x0 y : E.t, InA E.eq x0 (x :: nil) -> InA E.eq y (elements s) -> E.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'x0, y:E.tH1:InA E.eq x0 (x :: nil)H2:InA E.eq y (elements s)E.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'x0, y:E.tH2:InA E.eq y (elements s)H3:E.eq x0 xE.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'x0, y:E.tH2:InA E.eq y (elements s)H3:InA E.eq x0 nilE.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'x0, y:E.tH2:In y sH3:E.eq x0 xE.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'x0, y:E.tH2:InA E.eq y (elements s)H3:InA E.eq x0 nilE.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'x0, y:E.tH2:InA E.eq y (elements s)H3:InA E.eq x0 nilE.lt x0 ys, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'equivlistA E.eq (elements s') (x :: elements s)s, s':tx:E.tH:Below x sH0:Add x s s'a:E.tInA E.eq a (elements s') <-> InA E.eq a (x :: elements s)do 2 rewrite <- elements_iff; rewrite (H0 a); intuition. Qed.s, s':tx:E.tH:Below x sH0:Add x s s'a:E.tInA E.eq a (elements s') <-> E.eq a x \/ InA E.eq a (elements s)
Two other induction principles on sets: we can be more restrictive
on the element we add at each step.
forall P : t -> Type, (forall s : t, Empty s -> P s) -> (forall s s' : t, P s -> forall x : E.t, Above x s -> Add x s s' -> P s') -> forall s : t, P sforall P : t -> Type, (forall s : t, Empty s -> P s) -> (forall s s' : t, P s -> forall x : E.t, Above x s -> Add x s s' -> P s') -> forall s : t, P sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eP (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eAbove e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some en = cardinal (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eAbove e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eS n = S (cardinal (remove e s))P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eH0:S n = S (cardinal (remove e s))n = cardinal (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eAbove e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eH0:S n = S (cardinal (remove e s))n = cardinal (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eAbove e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some eAbove e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some ey:eltH0:In y (remove e s)E.lt y eP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:max_elt s = Some ey:eltH0:In y sH1:~ E.eq e yE.lt y eP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneP srewrite cardinal_Empty in H0; rewrite H0 in Heqn; inversion Heqn. Qed.P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Above x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:max_elt s = NoneH0:Empty sP sforall P : t -> Type, (forall s : t, Empty s -> P s) -> (forall s s' : t, P s -> forall x : E.t, Below x s -> Add x s s' -> P s') -> forall s : t, P sforall P : t -> Type, (forall s : t, Empty s -> P s) -> (forall s s' : t, P s -> forall x : E.t, Below x s -> Add x s s' -> P s') -> forall s : t, P sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eP (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eBelow e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some en = cardinal (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eBelow e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eS n = S (cardinal (remove e s))P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eH0:S n = S (cardinal (remove e s))n = cardinal (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eBelow e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eH0:S n = S (cardinal (remove e s))n = cardinal (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eBelow e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some eBelow e (remove e s)P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some ey:eltH0:In y (remove e s)E.lt e yP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal se:eltH:min_elt s = Some ey:eltH0:In y sH1:~ E.eq e yE.lt e yP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP sP:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneP srewrite cardinal_Empty in H0; auto; rewrite H0 in Heqn; inversion Heqn. Qed.P:t -> TypeX:forall s0 : t, Empty s0 -> P s0X0:forall s0 s' : t, P s0 -> forall x : E.t, Below x s0 -> Add x s0 s' -> P s'n:natIHn:forall s0 : t, n = cardinal s0 -> P s0s:tHeqn:S n = cardinal sH:min_elt s = NoneH0:Empty sP s
More properties of fold : behavior with respect to Above/Below
forall (s s' : t) (x : E.t) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), compat_op E.eq eqA f -> Above x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i))forall (s s' : t) (x : E.t) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), compat_op E.eq eqA f -> Above x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Above x sH1:Add x s s'eqA (fold f s' i) (f x (fold f s i))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Above x sH1:Add x s s'eqA (fold_right f i (rev (elements s'))) (f x (fold_right f i (rev (elements s))))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Above x sH1:Add x s s'eqA (fold_right f i (rev (elements s'))) (fold_right f i (rev (x :: nil) ++ rev (elements s)))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Above x sH1:Add x s s'eqlistA E.eq (rev (elements s')) (rev (x :: nil) ++ rev (elements s))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Above x sH1:Add x s s'eqlistA E.eq (rev (elements s')) (rev (elements s ++ x :: nil))apply elements_Add_Above; auto. Qed.s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Above x sH1:Add x s s'eqlistA E.eq (elements s') (elements s ++ x :: nil)forall (s s' : t) (x : E.t) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), compat_op E.eq eqA f -> Below x s -> Add x s s' -> eqA (fold f s' i) (fold f s (f x i))forall (s s' : t) (x : E.t) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (i : A) (f : elt -> A -> A), compat_op E.eq eqA f -> Below x s -> Add x s s' -> eqA (fold f s' i) (fold f s (f x i))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'eqA (fold f s' i) (fold f s (f x i))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'eqA (fold_left (fun (a : A) (e : elt) => f e a) (elements s') i) (fold_left (fun (a : A) (e : elt) => f e a) (elements s) (f x i))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'g:=fun (a : A) (e : elt) => f e a:A -> elt -> AeqA (fold_left g (elements s') i) (fold_left g (elements s) (f x i))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'g:=fun (a : A) (e : elt) => f e a:A -> elt -> AeqA (fold_left g (elements s') i) (fold_left g (x :: elements s) i)s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'g:=fun (a : A) (e : elt) => f e a:A -> elt -> AeqA (fold_left (fun (a : A) (e : elt) => f e a) (elements s') i) (fold_left (fun (a : A) (e : elt) => f e a) (x :: elements s) i)s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'g:=fun (a : A) (e : elt) => f e a:A -> elt -> AeqA (fold_right f i (rev (elements s'))) (fold_right f i (rev (x :: elements s)))s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'g:=fun (a : A) (e : elt) => f e a:A -> elt -> AeqlistA E.eq (rev (elements s')) (rev (x :: elements s))apply elements_Add_Below; auto. Qed.s, s':tx:E.tA:TypeeqA:A -> A -> Propst:Equivalence eqAi:Af:elt -> A -> AH:compat_op E.eq eqA fH0:Below x sH1:Add x s s'g:=fun (a : A) (e : elt) => f e a:A -> elt -> AeqlistA E.eq (elements s') (x :: elements s)
The following results have already been proved earlier,
but we can now prove them with one hypothesis less:
no need for (transpose eqA f).
Section FoldOpt. Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA). Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f).A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fforall (i : A) (s s' : t), s [=] s' -> eqA (fold f s i) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fforall (i : A) (s s' : t), s [=] s' -> eqA (fold f s i) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fi:As, s':tH:s [=] s'eqA (fold f s i) (fold f s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fi:As, s':tH:s [=] s'eqA (fold_right f i (rev (elements s))) (fold_right f i (rev (elements s')))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fi:As, s':tH:s [=] s'eqlistA E.eq (rev (elements s)) (rev (elements s'))A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fi:As, s':tH:s [=] s'eqlistA E.eq (elements s) (elements s')red; intro a; do 2 rewrite <- elements_iff; auto. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fi:As, s':tH:s [=] s'equivlistA E.eq (elements s) (elements s')A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fforall (i : A) (s : t) (x : elt), In x s -> eqA (fold f (add x s) i) (fold f s i)intros; apply fold_equal; auto with set. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fforall (i : A) (s : t) (x : elt), In x s -> eqA (fold f (add x s) i) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fforall (i : A) (s : t) (x : elt), ~ In x s -> eqA (fold f (remove x s) i) (fold f s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fforall (i : A) (s : t) (x : elt), ~ In x s -> eqA (fold f (remove x s) i) (fold f s i)apply fold_equal; auto with set. Qed. End FoldOpt.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fi:As:tx:eltH:~ In x seqA (fold f (remove x s) i) (fold f s i)
An alternative version of choose_3
forall s s' : t, s [=] s' -> match choose s with | Some x => match choose s' with | Some x' => E.eq x x' | None => False end | None => match choose s' with | Some _ => False | None => True end endforall s s' : t, s [=] s' -> match choose s with | Some x => match choose s' with | Some x' => E.eq x x' | None => False end | None => match choose s' with | Some _ => False | None => True end ends, s':tH:s [=] s'e:eltH0:forall x : elt, Some e = Some x -> In x sH1:Some e = None -> Empty sH2:forall x : elt, None = Some x -> In x s'H4:forall x y : elt, Some e = Some x -> None = Some y -> s [=] s' -> E.eq x yH5:Empty s'Falses, s':tH:s [=] s'e:eltH0:forall x : elt, None = Some x -> In x sH2:forall x : elt, Some e = Some x -> In x s'H3:Some e = None -> Empty s'H4:forall x y : elt, None = Some x -> Some e = Some y -> s [=] s' -> E.eq x yH5:Empty sFalseapply H5 with e; rewrite H; auto. Qed. End OrdProperties.s, s':tH:s [=] s'e:eltH0:forall x : elt, None = Some x -> In x sH2:forall x : elt, Some e = Some x -> In x s'H3:Some e = None -> Empty s'H4:forall x y : elt, None = Some x -> Some e = Some y -> s [=] s' -> E.eq x yH5:Empty sFalse