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 module proves many properties of finite sets that
are consequences of the axiomatization in FsetInterface
Contrary to the functor in FsetProperties it uses
sets operations instead of predicates over sets, i.e.
mem x s=true instead of In x s,
equal s s'=true instead of Equal s s', etc.
Require Import FSetProperties Zerob Sumbool Omega DecidableTypeEx. Module WEqProperties_fun (Import E:DecidableType)(M:WSfun E). Module Import MP := WProperties_fun E M. Import FM Dec.F. Import M. Definition Add := MP.Add. Section BasicProperties.
Some old specifications written with boolean equalities.
Variable s s' s'': t. Variable x y z : elt.s, s', s'':tx, y, z:eltE.eq x y -> mem x s = mem y sintro H; rewrite H; auto. Qed.s, s', s'':tx, y, z:eltE.eq x y -> mem x s = mem y ss, s', s'':tx, y, z:elt(forall a : elt, mem a s = mem a s') -> equal s s' = trues, s', s'':tx, y, z:elt(forall a : elt, mem a s = mem a s') -> equal s s' = truedo 2 rewrite mem_iff; rewrite H; tauto. Qed.s, s', s'':tx, y, z:eltH:forall a0 : elt, mem a0 s = mem a0 s'a:eltIn a s <-> In a s's, s', s'':tx, y, z:eltequal s s' = true -> forall a : elt, mem a s = mem a s'intros; rewrite (equal_2 H); auto. Qed.s, s', s'':tx, y, z:eltequal s s' = true -> forall a : elt, mem a s = mem a s's, s', s'':tx, y, z:elt(forall a : elt, mem a s = true -> mem a s' = true) -> subset s s' = trues, s', s'':tx, y, z:elt(forall a : elt, mem a s = true -> mem a s' = true) -> subset s s' = truedo 2 rewrite mem_iff; auto. Qed.s, s', s'':tx, y, z:eltH:forall a0 : elt, mem a0 s = true -> mem a0 s' = truea:eltIn a s -> In a s's, s', s'':tx, y, z:eltsubset s s' = true -> forall a : elt, mem a s = true -> mem a s' = trueintros H a; do 2 rewrite <- mem_iff; apply subset_2; auto. Qed.s, s', s'':tx, y, z:eltsubset s s' = true -> forall a : elt, mem a s = true -> mem a s' = trues, s', s'':tx, y, z:eltmem x empty = falserewrite <- not_mem_iff; auto with set. Qed.s, s', s'':tx, y, z:eltmem x empty = falses, s', s'':tx, y, z:eltis_empty s = equal s emptys, s', s'':tx, y, z:eltis_empty s = equal s emptys, s', s'':tx, y, z:eltH:is_empty s = trueequal s empty = trues, s', s'':tx, y, z:eltH:equal s empty = trueis_empty s = truerewrite <- is_empty_iff; auto with set. Qed.s, s', s'':tx, y, z:eltH:equal s empty = trueis_empty s = trues, s', s'':tx, y, z:eltchoose s = Some x -> mem x s = trueauto with set. Qed.s, s', s'':tx, y, z:eltchoose s = Some x -> mem x s = trues, s', s'':tx, y, z:eltchoose s = None -> is_empty s = trueauto with set. Qed.s, s', s'':tx, y, z:eltchoose s = None -> is_empty s = trues, s', s'':tx, y, z:eltmem x (add x s) = trueauto with set. Qed.s, s', s'':tx, y, z:eltmem x (add x s) = trues, s', s'':tx, y, z:elt~ E.eq x y -> mem y (add x s) = mem y sapply add_neq_b. Qed.s, s', s'':tx, y, z:elt~ E.eq x y -> mem y (add x s) = mem y ss, s', s'':tx, y, z:eltmem x (remove x s) = falserewrite <- not_mem_iff; auto with set. Qed.s, s', s'':tx, y, z:eltmem x (remove x s) = falses, s', s'':tx, y, z:elt~ E.eq x y -> mem y (remove x s) = mem y sapply remove_neq_b. Qed.s, s', s'':tx, y, z:elt~ E.eq x y -> mem y (remove x s) = mem y ss, s', s'':tx, y, z:eltequal (singleton x) (add x empty) = truerewrite (singleton_equal_add x); auto with set. Qed.s, s', s'':tx, y, z:eltequal (singleton x) (add x empty) = trues, s', s'':tx, y, z:eltmem x (union s s') = mem x s || mem x s'apply union_b. Qed.s, s', s'':tx, y, z:eltmem x (union s s') = mem x s || mem x s's, s', s'':tx, y, z:eltmem x (inter s s') = mem x s && mem x s'apply inter_b. Qed.s, s', s'':tx, y, z:eltmem x (inter s s') = mem x s && mem x s's, s', s'':tx, y, z:eltmem x (diff s s') = mem x s && negb (mem x s')apply diff_b. Qed.s, s', s'':tx, y, z:eltmem x (diff s s') = mem x s && negb (mem x s')
properties of mem
s, s', s'':tx, y, z:elt~ In x s -> mem x s = falseintros; rewrite <- not_mem_iff; auto. Qed.s, s', s'':tx, y, z:elt~ In x s -> mem x s = falses, s', s'':tx, y, z:eltmem x s = false -> ~ In x sintros; rewrite not_mem_iff; auto. Qed.s, s', s'':tx, y, z:eltmem x s = false -> ~ In x s
Properties of equal
s, s', s'':tx, y, z:eltequal s s = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal s s = trues, s', s'':tx, y, z:eltequal s s' = equal s' sintros; apply bool_1; do 2 rewrite <- equal_iff; intuition. Qed.s, s', s'':tx, y, z:eltequal s s' = equal s' ss, s', s'':tx, y, z:eltequal s s' = true -> equal s' s'' = true -> equal s s'' = trueintros; rewrite (equal_2 H); auto. Qed.s, s', s'':tx, y, z:eltequal s s' = true -> equal s' s'' = true -> equal s s'' = trues, s', s'':tx, y, z:eltequal s s' = true -> equal s s'' = equal s' s''intros; rewrite (equal_2 H); auto. Qed.s, s', s'':tx, y, z:eltequal s s' = true -> equal s s'' = equal s' s''s, s', s'':tx, y, z:eltequal s s' = true -> cardinal s = cardinal s'auto with set fset. Qed. (* Properties of [subset] *)s, s', s'':tx, y, z:eltequal s s' = true -> cardinal s = cardinal s's, s', s'':tx, y, z:eltsubset s s = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s s = trues, s', s'':tx, y, z:eltsubset s s' = true -> subset s' s = true -> equal s s' = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s s' = true -> subset s' s = true -> equal s s' = trues, s', s'':tx, y, z:eltsubset s s' = true -> subset s' s'' = true -> subset s s'' = trues, s', s'':tx, y, z:eltsubset s s' = true -> subset s' s'' = true -> subset s s'' = trueapply subset_trans with s'; auto. Qed.s, s', s'':tx, y, z:eltH:s [<=] s'H0:s' [<=] s''s [<=] s''s, s', s'':tx, y, z:eltequal s s' = true -> subset s s' = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal s s' = true -> subset s s' = true
Properties of choose
s, s', s'':tx, y, z:eltis_empty s = false -> {x0 : elt | choose s = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltis_empty s = false -> {x0 : elt | choose s = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltH:is_empty s = false{x0 : elt | choose s = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltH:is_empty s = false(forall x0 : elt, choose s = Some x0 -> In x0 s) -> (choose s = None -> Empty s) -> {x0 : elt | choose s = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltH:is_empty s = falsee:eltH0:forall x0 : elt, Some e = Some x0 -> In x0 sH1:Some e = None -> Empty s{x0 : elt | Some e = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltH:is_empty s = falseH0:forall x0 : elt, None = Some x0 -> In x0 sH1:None = None -> Empty s{x0 : elt | None = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltH:is_empty s = falseH0:forall x0 : elt, None = Some x0 -> In x0 sH1:None = None -> Empty s{x0 : elt | None = Some x0 /\ mem x0 s = true}intros; rewrite (is_empty_1 H1) in H; discriminate. Qed.s, s', s'':tx, y, z:eltH:is_empty s = falseH0:forall x0 : elt, None = Some x0 -> In x0 sEmpty s -> {x0 : elt | None = Some x0 /\ mem x0 s = true}s, s', s'':tx, y, z:eltchoose empty = Nones, s', s'':tx, y, z:eltchoose empty = Nones, s', s'':tx, y, z:elt(forall x0 : elt, choose empty = Some x0 -> In x0 empty) -> choose empty = Noneelim (@empty_1 e); auto. Qed.s, s', s'':tx, y, z, e:eltH:forall x0 : elt, Some e = Some x0 -> In x0 emptySome e = None
Properties of add
s, s', s'':tx, y, z:eltmem y s = true -> mem y (add x s) = trueauto with set. Qed.s, s', s'':tx, y, z:eltmem y s = true -> mem y (add x s) = trues, s', s'':tx, y, z:eltmem x s = true -> equal (add x s) s = trueauto with set. Qed.s, s', s'':tx, y, z:eltmem x s = true -> equal (add x s) s = true
Properties of remove
s, s', s'':tx, y, z:eltmem y (remove x s) = true -> mem y s = truerewrite remove_b; intros H;destruct (andb_prop _ _ H); auto. Qed.s, s', s'':tx, y, z:eltmem y (remove x s) = true -> mem y s = trues, s', s'':tx, y, z:eltmem x s = false -> equal (remove x s) s = trues, s', s'':tx, y, z:eltmem x s = false -> equal (remove x s) s = truerewrite not_mem_iff; auto. Qed.s, s', s'':tx, y, z:eltH:mem x s = false~ In x ss, s', s'':tx, y, z:eltmem x s = true -> equal (add x (remove x s)) s = trueintros; apply equal_1; apply add_remove; auto with set. Qed.s, s', s'':tx, y, z:eltmem x s = true -> equal (add x (remove x s)) s = trues, s', s'':tx, y, z:eltmem x s = false -> equal (remove x (add x s)) s = trues, s', s'':tx, y, z:eltmem x s = false -> equal (remove x (add x s)) s = truerewrite not_mem_iff; auto. Qed.s, s', s'':tx, y, z:eltH:mem x s = false~ In x s
Properties of is_empty
s, s', s'':tx, y, z:eltis_empty s = zerob (cardinal s)s, s', s'':tx, y, z:eltis_empty s = zerob (cardinal s)s, s', s'':tx, y, z:eltH:is_empty s = truezerob (cardinal s) = trues, s', s'':tx, y, z:eltH:zerob (cardinal s) = trueis_empty s = trues, s', s'':tx, y, z:eltH:zerob (cardinal s) = trueis_empty s = trueauto with set fset. Qed.s, s', s'':tx, y, z:eltH:zerob (cardinal s) = trueH0:cardinal s = 0is_empty s = true
Properties of singleton
s, s', s'':tx, y, z:eltmem x (singleton x) = trueauto with set. Qed.s, s', s'':tx, y, z:eltmem x (singleton x) = trues, s', s'':tx, y, z:elt~ E.eq x y -> mem y (singleton x) = falses, s', s'':tx, y, z:elt~ E.eq x y -> mem y (singleton x) = falseunfold eqb; destruct (E.eq_dec x y); intuition. Qed.s, s', s'':tx, y, z:eltH:~ E.eq x yeqb x y = falses, s', s'':tx, y, z:eltmem y (singleton x) = true -> E.eq x yintros; apply singleton_1; auto with set. Qed.s, s', s'':tx, y, z:eltmem y (singleton x) = true -> E.eq x y
Properties of union
s, s', s'':tx, y, z:eltequal (union s s') (union s' s) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (union s s') (union s' s) = trues, s', s'':tx, y, z:eltsubset s s' = true -> equal (union s s') s' = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s s' = true -> equal (union s s') s' = trues, s', s'':tx, y, z:eltequal s s' = true -> equal (union s s'') (union s' s'') = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal s s' = true -> equal (union s s'') (union s' s'') = trues, s', s'':tx, y, z:eltequal s' s'' = true -> equal (union s s') (union s s'') = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal s' s'' = true -> equal (union s s') (union s s'') = trues, s', s'':tx, y, z:eltequal (union (union s s') s'') (union s (union s' s'')) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (union (union s s') s'') (union s (union s' s'')) = trues, s', s'':tx, y, z:eltequal (add x s) (union (singleton x) s) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (add x s) (union (singleton x) s) = trues, s', s'':tx, y, z:eltequal (union (add x s) s') (add x (union s s')) = trueauto with set. Qed. (* characterisation of [union] via [subset] *)s, s', s'':tx, y, z:eltequal (union (add x s) s') (add x (union s s')) = trues, s', s'':tx, y, z:eltsubset s (union s s') = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s (union s s') = trues, s', s'':tx, y, z:eltsubset s' (union s s') = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s' (union s s') = trues, s', s'':tx, y, z:eltsubset s s'' = true -> subset s' s'' = true -> subset (union s s') s'' = trueintros; apply subset_1; apply union_subset_3; auto with set. Qed.s, s', s'':tx, y, z:eltsubset s s'' = true -> subset s' s'' = true -> subset (union s s') s'' = true
Properties of inter
s, s', s'':tx, y, z:eltequal (inter s s') (inter s' s) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (inter s s') (inter s' s) = trues, s', s'':tx, y, z:eltsubset s s' = true -> equal (inter s s') s = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s s' = true -> equal (inter s s') s = trues, s', s'':tx, y, z:eltequal s s' = true -> equal (inter s s'') (inter s' s'') = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal s s' = true -> equal (inter s s'') (inter s' s'') = trues, s', s'':tx, y, z:eltequal s' s'' = true -> equal (inter s s') (inter s s'') = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal s' s'' = true -> equal (inter s s') (inter s s'') = trues, s', s'':tx, y, z:eltequal (inter (inter s s') s'') (inter s (inter s' s'')) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (inter (inter s s') s'') (inter s (inter s' s'')) = trues, s', s'':tx, y, z:eltequal (inter (union s s') s'') (union (inter s s'') (inter s' s'')) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (inter (union s s') s'') (union (inter s s'') (inter s' s'')) = trues, s', s'':tx, y, z:eltequal (union (inter s s') s'') (inter (union s s'') (union s' s'')) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (union (inter s s') s'') (inter (union s s'') (union s' s'')) = trues, s', s'':tx, y, z:eltmem x s' = true -> equal (inter (add x s) s') (add x (inter s s')) = trueauto with set. Qed.s, s', s'':tx, y, z:eltmem x s' = true -> equal (inter (add x s) s') (add x (inter s s')) = trues, s', s'':tx, y, z:eltmem x s' = false -> equal (inter (add x s) s') (inter s s') = trues, s', s'':tx, y, z:eltmem x s' = false -> equal (inter (add x s) s') (inter s s') = truerewrite not_mem_iff; auto. Qed. (* characterisation of [union] via [subset] *)s, s', s'':tx, y, z:eltH:mem x s' = false~ In x s's, s', s'':tx, y, z:eltsubset (inter s s') s = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset (inter s s') s = trues, s', s'':tx, y, z:eltsubset (inter s s') s' = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset (inter s s') s' = trues, s', s'':tx, y, z:eltsubset s'' s = true -> subset s'' s' = true -> subset s'' (inter s s') = trueintros; apply subset_1; apply inter_subset_3; auto with set. Qed.s, s', s'':tx, y, z:eltsubset s'' s = true -> subset s'' s' = true -> subset s'' (inter s s') = true
Properties of diff
s, s', s'':tx, y, z:eltsubset (diff s s') s = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset (diff s s') s = trues, s', s'':tx, y, z:eltsubset s s' = true -> equal (diff s s') empty = trueauto with set. Qed.s, s', s'':tx, y, z:eltsubset s s' = true -> equal (diff s s') empty = trues, s', s'':tx, y, z:eltequal (remove x s) (diff s (singleton x)) = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (remove x s) (diff s (singleton x)) = trues, s', s'':tx, y, z:eltequal (inter (diff s s') (inter s s')) empty = trueauto with set. Qed.s, s', s'':tx, y, z:eltequal (inter (diff s s') (inter s s')) empty = trues, s', s'':tx, y, z:eltequal (union (diff s s') (inter s s')) s = trueauto with set. Qed. End BasicProperties. Hint Immediate empty_mem is_empty_equal_empty add_mem_1 remove_mem_1 singleton_equal_add union_mem inter_mem diff_mem equal_sym add_remove remove_add : set. Hint Resolve equal_mem_1 subset_mem_1 choose_mem_1 choose_mem_2 add_mem_2 remove_mem_2 equal_refl equal_equal subset_refl subset_equal subset_antisym add_mem_3 add_equal remove_mem_3 remove_equal : set.s, s', s'':tx, y, z:eltequal (union (diff s s') (inter s s')) s = true
General recursion principle
forall P : t -> Type, (forall s s' : t, equal s s' = true -> P s -> P s') -> (forall (s : t) (x : elt), mem x s = false -> P s -> P (add x s)) -> P empty -> forall s : t, P sforall P : t -> Type, (forall s s' : t, equal s s' = true -> P s -> P s') -> (forall (s : t) (x : elt), mem x s = false -> P s -> P (add x s)) -> P empty -> forall s : t, P sP:t -> TypeX:forall s0 s' : t, equal s0 s' = true -> P s0 -> P s'X0:forall (s0 : t) (x : elt), mem x s0 = false -> P s0 -> P (add x s0)X1:P emptys:tP sP:t -> TypeX:forall s1 s' : t, equal s1 s' = true -> P s1 -> P s'X0:forall (s1 : t) (x : elt), mem x s1 = false -> P s1 -> P (add x s1)X1:P emptys, s0:tH:Empty s0P s0P:t -> TypeX:forall s1 s'0 : t, equal s1 s'0 = true -> P s1 -> P s'0X0:forall (s1 : t) (x0 : elt), mem x0 s1 = false -> P s1 -> P (add x0 s1)X1:P emptys, s0, s':tX2:P s0x:eltH:~ In x s0H0:MP.Add x s0 s'P s'P:t -> TypeX:forall s1 s'0 : t, equal s1 s'0 = true -> P s1 -> P s'0X0:forall (s1 : t) (x0 : elt), mem x0 s1 = false -> P s1 -> P (add x0 s1)X1:P emptys, s0, s':tX2:P s0x:eltH:~ In x s0H0:MP.Add x s0 s'P s'P:t -> TypeX:forall s1 s'0 : t, equal s1 s'0 = true -> P s1 -> P s'0X0:forall (s1 : t) (x0 : elt), mem x0 s1 = false -> P s1 -> P (add x0 s1)X1:P emptys, s0, s':tX2:P s0x:eltH:~ In x s0H0:MP.Add x s0 s'equal (add x s0) s' = trueP:t -> TypeX:forall s1 s'0 : t, equal s1 s'0 = true -> P s1 -> P s'0X0:forall (s1 : t) (x0 : elt), mem x0 s1 = false -> P s1 -> P (add x0 s1)X1:P emptys, s0, s':tX2:P s0x:eltH:~ In x s0H0:MP.Add x s0 s'P (add x s0)apply X0; auto with set; apply mem_3; auto. Qed.P:t -> TypeX:forall s1 s'0 : t, equal s1 s'0 = true -> P s1 -> P s'0X0:forall (s1 : t) (x0 : elt), mem x0 s1 = false -> P s1 -> P (add x0 s1)X1:P emptys, s0, s':tX2:P s0x:eltH:~ In x s0H0:MP.Add x s0 s'P (add x s0)
Properties of fold
forall (s s' : t) (x : elt), ~ (In x s /\ In x s') <-> mem x s && mem x s' = falseforall (s s' : t) (x : elt), ~ (In x s /\ In x s') <-> mem x s && mem x s' = falsedestruct (mem x s); destruct (mem x s'); intuition. Qed. Section Fold. 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). Variables (i:A). Variables (s s':t)(x:elt).s, s':tx:elt~ (mem x s = true /\ mem x s' = true) <-> mem x s && mem x s' = falseA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltfold f empty i = iapply fold_empty; auto. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltfold f empty i = iA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltequal s s' = true -> eqA (fold f s i) (fold f s' i)intros; apply fold_equal 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, s':tx:eltequal s s' = true -> 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':tx:eltmem x s = false -> 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 fi:As, s':tx:eltmem x s = false -> eqA (fold f (add x s) i) (f x (fold f s i))rewrite not_mem_iff; auto. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltH:mem x s = false~ In x sA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltmem x s = true -> eqA (fold f (add x s) i) (fold f s i)intros; apply add_fold 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, s':tx:eltmem x s = true -> 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 fi:As, s':tx:eltmem x s = true -> eqA (f x (fold f (remove x s) i)) (fold f s i)intros; apply remove_fold_1 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, s':tx:eltmem x s = true -> 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, s':tx:eltmem x s = false -> 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 fi:As, s':tx:eltmem x s = false -> eqA (fold f (remove x s) i) (fold f s i)rewrite not_mem_iff; auto. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltH:mem x s = false~ In x sA:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:elt(forall x0 : elt, mem x0 s && mem x0 s' = false) -> 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':tx:elt(forall x0 : elt, mem x0 s && mem x0 s' = false) -> eqA (fold f (union s s') i) (fold f s (fold f s' i))intros; rewrite exclusive_set; auto. Qed. End Fold.A:TypeeqA:A -> A -> Propst:Equivalence eqAf:elt -> A -> AComp:compat_op E.eq eqA fAss:transpose eqA fi:As, s':tx:eltH:forall x0 : elt, mem x0 s && mem x0 s' = falseforall x0 : elt, ~ (In x0 s /\ In x0 s')
Properties of cardinal
forall (s : t) (x : elt), mem x s = true -> cardinal (add x s) = cardinal sauto with set fset. Qed.forall (s : t) (x : elt), mem x s = true -> cardinal (add x s) = cardinal sforall (s : t) (x : elt), mem x s = false -> cardinal (add x s) = S (cardinal s)forall (s : t) (x : elt), mem x s = false -> cardinal (add x s) = S (cardinal s)rewrite not_mem_iff; auto. Qed.s:tx:eltH:mem x s = false~ In x sforall (s : t) (x : elt), mem x s = true -> S (cardinal (remove x s)) = cardinal sintros; apply remove_cardinal_1; auto with set. Qed.forall (s : t) (x : elt), mem x s = true -> S (cardinal (remove x s)) = cardinal sforall (s : t) (x : elt), mem x s = false -> cardinal (remove x s) = cardinal sintros; apply Equal_cardinal; apply equal_2; auto with set. Qed.forall (s : t) (x : elt), mem x s = false -> cardinal (remove x s) = cardinal sforall s s' : t, (forall x : elt, mem x s && mem x s' = false) -> cardinal (union s s') = cardinal s + cardinal s'forall s s' : t, (forall x : elt, mem x s && mem x s' = false) -> cardinal (union s s') = cardinal s + cardinal s'rewrite exclusive_set; auto. Qed.s, s':tH:forall x0 : elt, mem x0 s && mem x0 s' = falsex:elt~ (In x s /\ In x s')forall s s' : t, subset s s' = true -> cardinal s <= cardinal s'intros; apply subset_cardinal; auto with set. Qed. Section Bool.forall s s' : t, subset s s' = true -> cardinal s <= cardinal s'
Properties of filter
Variable f:elt->bool. Variable Comp: Proper (E.eq==>Logic.eq) f.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fProper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))repeat red; intros; f_equal; auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fProper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), mem x (filter f s) = mem x s && f xintros; apply filter_b; auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), mem x (filter f s) = mem x s && f xf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, for_all f s = is_empty (filter (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, for_all f s = is_empty (filter (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:for_all f s = trueis_empty (filter (fun x : elt => negb (f x)) s) = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:for_all f s = trueEmpty (filter (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:for_all f s = truea:elt~ In a (filter (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:for_all f s = truea:elt~ (In a s /\ negb (f a) = true)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:for_all f s = truea:eltH0:In a sH1:negb (f a) = trueFalsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:For_all (fun x : elt => f x = true) sa:eltH0:In a sH1:negb (f a) = trueFalsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = truex:eltH0:In x sf x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH0:In x sEmpty (filter (fun x0 : elt => negb (f x0)) s) -> f x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH0:In x s~ In x (filter (fun x0 : elt => negb (f x0)) s) -> f x = truedestruct (f x); auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH0:In x s~ (In x s /\ negb (f x) = true) -> f x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, exists_ f s = negb (is_empty (filter f s))f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, exists_ f s = negb (is_empty (filter f s))f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:exists_ f s = truenegb (is_empty (filter f s)) = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = trueexists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:exists_ f s = truea:eltHa1:In a sHa2:f a = truenegb (is_empty (filter f s)) = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = trueexists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:exists_ f s = truea:eltHa1:In a sHa2:f a = trueis_empty (filter f s) <> truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = trueexists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = trueexists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = true(forall x : elt, choose (filter f s) = Some x -> In x (filter f s)) -> (choose (filter f s) = None -> Empty (filter f s)) -> exists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = truee:elt(forall x : elt, Some e = Some x -> In x (filter f s)) -> (Some e = None -> Empty (filter f s)) -> exists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = true(forall x : elt, None = Some x -> In x (filter f s)) -> (None = None -> Empty (filter f s)) -> exists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = truee:eltH0:forall x : elt, Some e = Some x -> In x (filter f s)Exists (fun x : elt => f x = true) sf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = true(forall x : elt, None = Some x -> In x (filter f s)) -> (None = None -> Empty (filter f s)) -> exists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = true(forall x : elt, None = Some x -> In x (filter f s)) -> (None = None -> Empty (filter f s)) -> exists_ f s = truerewrite (is_empty_1 (H0 Logic.eq_refl)) in H; auto; discriminate. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:negb (is_empty (filter f s)) = trueH0:None = None -> Empty (filter f s)exists_ f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, equal (fst (partition f s)) (filter f s) = trueauto with set. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, equal (fst (partition f s)) (filter f s) = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, equal (snd (partition f s)) (filter (fun x : elt => negb (f x)) s) = trueauto with set. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, equal (snd (partition f s)) (filter (fun x : elt => negb (f x)) s) = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), f x = true -> filter f (add x s) [=] add x (filter f s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), f x = true -> filter f (add x s) [=] add x (filter f s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:f x = truea:elt(E.eq x a \/ In a s) /\ f a = true <-> E.eq x a \/ In a s /\ f a = truerewrite <- H; apply Comp; auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:f x = truea:eltH1:E.eq x af a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), f x = false -> filter f (add x s) [=] filter f sf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), f x = false -> filter f (add x s) [=] filter f sf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:f x = falsea:elt(E.eq x a \/ In a s) /\ f a = true <-> In a s /\ f a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:f x = falsea:eltH2:f a = trueH0:E.eq x aIn a srewrite H in H1; rewrite H2 in H1; discriminate. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:f x = falsea:eltH2:f a = trueH0:E.eq x aH1:f x = f aIn a sf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s s' : t) (x : elt), f x = true -> Add x s s' -> Add x (filter f s) (filter f s')f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s s' : t) (x : elt), f x = true -> Add x s s' -> Add x (filter f s) (filter f s')f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = trueH0:forall y0 : elt, In y0 s' <-> E.eq x y0 \/ In y0 sy:eltIn y (filter f s') <-> E.eq x y \/ In y (filter f s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = trueH0:forall y0 : elt, In y0 s' <-> E.eq x y0 \/ In y0 sy:eltIn y s' /\ f y = true <-> E.eq x y \/ In y s /\ f y = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = truey:elt(E.eq x y \/ In y s) /\ f y = true <-> E.eq x y \/ In y s /\ f y = truetauto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = truey:eltH0:E.eq x y -> f y = true(E.eq x y \/ In y s) /\ f y = true <-> E.eq x y \/ In y s /\ f y = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s s' : t) (x : elt), f x = false -> Add x s s' -> filter f s [=] filter f s'f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s s' : t) (x : elt), f x = false -> Add x s s' -> filter f s [=] filter f s'f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falseH0:forall y : elt, In y s' <-> E.eq x y \/ In y sa:eltIn a (filter f s) <-> In a (filter f s')f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falseH0:forall y : elt, In y s' <-> E.eq x y \/ In y sa:eltIn a s /\ f a = true <-> In a s' /\ f a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltIn a s /\ f a = true <-> (E.eq x a \/ In a s) /\ f a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltf a = true -> ~ E.eq x af:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltH0:f a = true -> ~ E.eq x aIn a s /\ f a = true <-> (E.eq x a \/ In a s) /\ f a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltH0:f a = trueH1:E.eq x aFalsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltH0:f a = true -> ~ E.eq x aIn a s /\ f a = true <-> (E.eq x a \/ In a s) /\ f a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx, a:eltH:f a = falseH0:f a = trueH1:E.eq x aFalsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltH0:f a = true -> ~ E.eq x aIn a s /\ f a = true <-> (E.eq x a \/ In a s) /\ f a = truetauto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s, s':tx:eltH:f x = falsea:eltH0:f a = true -> ~ E.eq x aIn a s /\ f a = true <-> (E.eq x a \/ In a s) /\ f a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall f0 g : E.t -> bool, compat_bool E.eq f0 -> compat_bool E.eq g -> forall s : t, union (filter f0 s) (filter g s) [=] filter (fun x : elt => f0 x || g x) sf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall f0 g : E.t -> bool, compat_bool E.eq f0 -> compat_bool E.eq g -> forall s : t, union (filter f0 s) (filter g s) [=] filter (fun x : elt => f0 x || g x) sforall f g : E.t -> bool, compat_bool E.eq f -> compat_bool E.eq g -> forall s : t, union (filter f s) (filter g s) [=] filter (fun x : elt => f x || g x) sf, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tunion (filter f s) (filter g s) [=] filter (fun x : elt => f x || g x) sf, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tcompat_bool E.eq (fun x : E.t => f x || g x)f, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)union (filter f s) (filter g s) [=] filter (fun x : elt => f x || g x) sf, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tx, y:E.tH1:E.eq x yf x || g x = f y || g yf, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)union (filter f s) (filter g s) [=] filter (fun x : elt => f x || g x) sf, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)union (filter f s) (filter g s) [=] filter (fun x : elt => f x || g x) sf, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)a:eltIn a s /\ f a = true \/ In a s /\ g a = true <-> In a s /\ f a || g a = truef, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)a:eltf a || g a = true <-> f a = true \/ g a = truef, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)a:eltH2:f a || g a = true <-> f a = true \/ g a = trueIn a s /\ f a = true \/ In a s /\ g a = true <-> In a s /\ f a || g a = truef, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)a:eltf a || g a = true -> f a = true \/ g a = truef, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)a:eltH2:f a || g a = true <-> f a = true \/ g a = trueIn a s /\ f a = true \/ In a s /\ g a = true <-> In a s /\ f a || g a = truetauto. Qed.f, g:E.t -> boolH:compat_bool E.eq fH0:compat_bool E.eq gs:tH1:compat_bool E.eq (fun x : E.t => f x || g x)a:eltH2:f a || g a = true <-> f a = true \/ g a = trueIn a s /\ f a = true \/ In a s /\ g a = true <-> In a s /\ f a || g a = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s s' : t, filter f (union s s') [=] union (filter f s) (filter f s')unfold Equal; intros; set_iff; repeat rewrite filter_iff; auto; set_iff; tauto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s s' : t, filter f (union s s') [=] union (filter f s) (filter f s')
Properties of for_all
f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, (forall x : elt, mem x s = true -> f x = true) -> for_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, (forall x : elt, mem x s = true -> f x = true) -> for_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = truefor_all f s = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = trueis_empty (filter (fun x : elt => negb (f x)) s) = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = trueequal (filter (fun x : elt => negb (f x)) s) empty = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = truea:eltmem a (filter (fun x : elt => negb (f x)) s) = mem a emptyf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = truea:eltmem a s && negb (f a) = mem a emptyf:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = truea:eltmem a s && negb (f a) = falserewrite H0;auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = truea:eltH0:true = true -> f a = truetrue && negb (f a) = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, for_all f s = true -> forall x : elt, mem x s = true -> f x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, for_all f s = true -> forall x : elt, mem x s = true -> f x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:for_all f s = truex:eltH0:mem x s = truef x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = truex:eltH0:mem x s = truef x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truex:eltH0:mem x s = truef x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truex:eltH0:mem x s = truemem x (filter (fun x0 : elt => negb (f x0)) s) = mem x empty -> f x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truex:eltH0:mem x s = truemem x s && negb (f x) = mem x empty -> f x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truex:eltH0:mem x s = truemem x s && negb (f x) = false -> f x = truerewrite <- negb_false_iff; auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truex:eltH0:mem x s = trueH1:negb (f x) = falsef x = truef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), mem x s = true -> f x = false -> for_all f s = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall (s : t) (x : elt), mem x s = true -> f x = false -> for_all f s = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falsefor_all f s = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:for_all f s = truetrue = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:is_empty (filter (fun x0 : elt => negb (f x0)) s) = truetrue = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truetrue = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truemem x (filter (fun x0 : elt => negb (f x0)) s) = mem x empty -> true = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truemem x s && negb (f x) = mem x empty -> true = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truemem x s && negb (f x) = false -> true = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truetrue && negb (f x) = false -> true = falsesimpl;auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = falseH1:equal (filter (fun x0 : elt => negb (f x0)) s) empty = truetrue && negb false = false -> true = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, for_all f s = false -> {x : elt | mem x s = true /\ f x = false}f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, for_all f s = false -> {x : elt | mem x s = true /\ f x = false}f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:for_all f s = false{x : elt | mem x s = true /\ f x = false}f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:tH:is_empty (filter (fun x : elt => negb (f x)) s) = false{x : elt | mem x s = true /\ f x = false}f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = falsex:eltH0:choose (filter (fun x0 : elt => negb (f x0)) s) = Some xH1:mem x (filter (fun x0 : elt => negb (f x0)) s) = true{x0 : elt | mem x0 s = true /\ f x0 = false}f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = falsex:eltH0:choose (filter (fun x0 : elt => negb (f x0)) s) = Some xH1:mem x (filter (fun x0 : elt => negb (f x0)) s) = truemem x s = true /\ f x = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = falsex:eltH0:choose (filter (fun x0 : elt => negb (f x0)) s) = Some xH1:mem x s && negb (f x) = truemem x s = true /\ f x = falsef:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = falsex:eltH0:choose (filter (fun x0 : elt => negb (f x0)) s) = Some xH1:mem x s && negb (f x) = truemem x s = true -> negb (f x) = true -> mem x s = true /\ f x = falserewrite <- negb_true_iff; auto. Qed.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x0 : E.t => negb (f x0))s:tH:is_empty (filter (fun x0 : elt => negb (f x0)) s) = falsex:eltH0:choose (filter (fun x0 : elt => negb (f x0)) s) = Some xH1:mem x s && negb (f x) = trueH2:mem x s = trueH3:negb (f x) = truef x = false
Properties of ∃
f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, exists_ f s = negb (for_all (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))forall s : t, exists_ f s = negb (for_all (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:texists_ f s = negb (for_all (fun x : elt => negb (f x)) s)f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:texists_ f s = negb (forallb (fun x : elt => negb (f x)) (elements s))f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:texistsb f (elements s) = negb (forallb (fun x : elt => negb (f x)) (elements s))destruct (f a); simpl; auto. Qed. End Bool. Section Bool'. Variable f:elt->bool. Variable Comp: compat_bool E.eq f.f:elt -> boolComp:Proper (E.eq ==> Logic.eq) fComp':Proper (E.eq ==> Logic.eq) (fun x : E.t => negb (f x))s:ta:eltl:list eltIHl:existsb f l = negb (forallb (fun x : elt => negb (f x)) l)f a || existsb f l = negb (negb (f a) && forallb (fun x : elt => negb (f x)) l)f:elt -> boolComp:compat_bool E.eq fcompat_bool E.eq (fun x : E.t => negb (f x))unfold compat_bool, Proper, respectful in *; intros; f_equal; auto. Qed.f:elt -> boolComp:compat_bool E.eq fcompat_bool E.eq (fun x : E.t => negb (f x))f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall s : t, (forall x : elt, mem x s = true -> f x = false) -> exists_ f s = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall s : t, (forall x : elt, mem x s = true -> f x = false) -> exists_ f s = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = falseexists_ f s = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = falsenegb (for_all (fun x : elt => negb (f x)) s) = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))s:tH:forall x : elt, mem x s = true -> f x = falseforall x : elt, mem x s = true -> negb (f x) = truerewrite negb_true_iff; auto. Qed.f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:forall x0 : elt, mem x0 s = true -> f x0 = falsex:eltH0:mem x s = trueH1:f x = falsenegb (f x) = truef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall s : t, exists_ f s = false -> forall x : elt, mem x s = true -> f x = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall s : t, exists_ f s = false -> forall x : elt, mem x s = true -> f x = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:exists_ f s = falsex:eltH0:mem x s = truef x = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:negb (for_all (fun x0 : elt => negb (f x0)) s) = falsex:eltH0:mem x s = truef x = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:for_all (fun x0 : elt => negb (f x0)) s = truex:eltH0:mem x s = truef x = falseapply for_all_mem_2 with (2:=H); auto. Qed.f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:for_all (fun x0 : elt => negb (f x0)) s = truex:eltH0:mem x s = truenegb (f x) = truef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall (s : t) (x : elt), mem x s = true -> f x = true -> exists_ f s = truef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall (s : t) (x : elt), mem x s = true -> f x = true -> exists_ f s = truef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = trueexists_ f s = truef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = truenegb (for_all (fun x0 : elt => negb (f x0)) s) = truef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = truefor_all (fun x0 : elt => negb (f x0)) s = falserewrite negb_false_iff; auto. Qed.f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tx:eltH:mem x s = trueH0:f x = truenegb (f x) = falsef:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall s : t, exists_ f s = true -> {x : elt | mem x s = true /\ f x = true}f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))forall s : t, exists_ f s = true -> {x : elt | mem x s = true /\ f x = true}f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))s:tH:exists_ f s = true{x : elt | mem x s = true /\ f x = true}f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))s:tH:negb (for_all (fun x : elt => negb (f x)) s) = true{x : elt | mem x s = true /\ f x = true}f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x : E.t => negb (f x))s:tH:for_all (fun x : elt => negb (f x)) s = false{x : elt | mem x s = true /\ f x = true}f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:for_all (fun x0 : elt => negb (f x0)) s = falsex:eltp:mem x s = true /\ negb (f x) = false{x0 : elt | mem x0 s = true /\ f x0 = true}f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:for_all (fun x0 : elt => negb (f x0)) s = falsex:eltp:mem x s = true /\ negb (f x) = falseH0:mem x s = trueH1:negb (f x) = false{x0 : elt | mem x0 s = true /\ f x0 = true}rewrite <-negb_false_iff; auto. Qed. End Bool'. Section Sum.f:elt -> boolComp:compat_bool E.eq fComp':compat_bool E.eq (fun x0 : E.t => negb (f x0))s:tH:for_all (fun x0 : elt => negb (f x0)) s = falsex:eltp:mem x s = true /\ negb (f x) = falseH0:mem x s = trueH1:negb (f x) = falsef x = true
Adding a valuation function on all elements of a set.
Definition sum (f:elt -> nat)(s:t) := fold (fun x => plus (f x)) s 0. Notation compat_opL := (compat_op E.eq Logic.eq). Notation transposeL := (transpose Logic.eq).forall f g : E.t -> nat, Proper (E.eq ==> Logic.eq) f -> Proper (E.eq ==> Logic.eq) g -> forall s : t, sum (fun x : elt => f x + g x) s = sum f s + sum g sforall f g : E.t -> nat, Proper (E.eq ==> Logic.eq) f -> Proper (E.eq ==> Logic.eq) g -> forall s : t, sum (fun x : elt => f x + g x) s = sum f s + sum g sforall f g : E.t -> nat, Proper (E.eq ==> Logic.eq) f -> Proper (E.eq ==> Logic.eq) g -> forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gforall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gcompat_opL (fun x : elt => Init.Nat.add (f x))f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))transposeL (fun x : elt => Init.Nat.add (f x))f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))compat_opL (fun x : elt => Init.Nat.add (g x))f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))transposeL (fun x : elt => Init.Nat.add (g x))f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))compat_opL (fun x : elt => Init.Nat.add (f x + g x))f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))transposeL (fun x : elt => Init.Nat.add (f x + g x))f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))forall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqforall s : t, fold (fun x : elt => Init.Nat.add (f x + g x)) s 0 = fold (fun x : elt => Init.Nat.add (f x)) s 0 + fold (fun x : elt => Init.Nat.add (g x)) s 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tforall s0 s' : t, equal s0 s' = true -> fold (fun x : elt => Init.Nat.add (f x + g x)) s0 0 = fold (fun x : elt => Init.Nat.add (f x)) s0 0 + fold (fun x : elt => Init.Nat.add (g x)) s0 0 -> fold (fun x : elt => Init.Nat.add (f x + g x)) s' 0 = fold (fun x : elt => Init.Nat.add (f x)) s' 0 + fold (fun x : elt => Init.Nat.add (g x)) s' 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0 -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) (add x s0) 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) (add x s0) 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) (add x s0) 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs, s0, s':tH:equal s0 s' = trueH0:fold (fun x : elt => Init.Nat.add (f x + g x)) s0 0 = fold (fun x : elt => Init.Nat.add (f x)) s0 0 + fold (fun x : elt => Init.Nat.add (g x)) s0 0fold (fun x : elt => Init.Nat.add (f x + g x)) s' 0 = fold (fun x : elt => Init.Nat.add (f x)) s' 0 + fold (fun x : elt => Init.Nat.add (g x)) s' 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0 -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) (add x s0) 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) (add x s0) 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) (add x s0) 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs, s0, s':tH:equal s0 s' = trueH0:fold (fun x : elt => Init.Nat.add (f x + g x)) s0 0 = fold (fun x : elt => Init.Nat.add (f x)) s0 0 + fold (fun x : elt => Init.Nat.add (g x)) s0 0fold (fun x : elt => Init.Nat.add (f x + g x)) s' 0 = fold (fun x : elt => Init.Nat.add (f x)) s0 0 + fold (fun x : elt => Init.Nat.add (g x)) s' 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0 -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) (add x s0) 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) (add x s0) 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) (add x s0) 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs, s0, s':tH:equal s0 s' = trueH0:fold (fun x : elt => Init.Nat.add (f x + g x)) s0 0 = fold (fun x : elt => Init.Nat.add (f x)) s0 0 + fold (fun x : elt => Init.Nat.add (g x)) s0 0fold (fun x : elt => Init.Nat.add (f x + g x)) s' 0 = fold (fun x : elt => Init.Nat.add (f x)) s0 0 + fold (fun x : elt => Init.Nat.add (g x)) s0 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0 -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) (add x s0) 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) (add x s0) 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) (add x s0) 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0 -> fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) (add x s0) 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) (add x s0) 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) (add x s0) 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x0 : elt => Init.Nat.add (f x0))ft:transposeL (fun x0 : elt => Init.Nat.add (f x0))gc:compat_opL (fun x0 : elt => Init.Nat.add (g x0))gt:transposeL (fun x0 : elt => Init.Nat.add (g x0))fgc:compat_opL (fun x0 : elt => Init.Nat.add (f x0 + g x0))fgt:transposeL (fun x0 : elt => Init.Nat.add (f x0 + g x0))st:Equivalence Logic.eqs, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0f x + g x + fold (fun x0 : elt => Init.Nat.add (f x0 + g x0)) s0 0 = f x + fold (fun x0 : elt => Init.Nat.add (f x0)) s0 0 + (g x + fold (fun x0 : elt => Init.Nat.add (g x0)) s0 0)f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0do 3 rewrite fold_empty;auto. Qed.f, g:E.t -> natHf:Proper (E.eq ==> Logic.eq) fHg:Proper (E.eq ==> Logic.eq) gfc:compat_opL (fun x : elt => Init.Nat.add (f x))ft:transposeL (fun x : elt => Init.Nat.add (f x))gc:compat_opL (fun x : elt => Init.Nat.add (g x))gt:transposeL (fun x : elt => Init.Nat.add (g x))fgc:compat_opL (fun x : elt => Init.Nat.add (f x + g x))fgt:transposeL (fun x : elt => Init.Nat.add (f x + g x))st:Equivalence Logic.eqs:tfold (fun x : elt => Init.Nat.add (f x + g x)) empty 0 = fold (fun x : elt => Init.Nat.add (f x)) empty 0 + fold (fun x : elt => Init.Nat.add (g x)) empty 0forall f : E.t -> bool, compat_bool E.eq f -> forall s : t, sum (fun x : elt => if f x then 1 else 0) s = cardinal (filter f s)forall f : E.t -> bool, compat_bool E.eq f -> forall s : t, sum (fun x : elt => if f x then 1 else 0) s = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fforall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqforall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcompat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))forall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqx, y:E.tH:E.eq x yx0, y0:natH0:x0 = y0(if f x then 1 else 0) + x0 = (if f y then 1 else 0) + y0f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))forall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))forall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))forall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))forall s : t, fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s 0 = cardinal (filter f s)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tforall s0 s' : t, equal s0 s' = true -> fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s0 0 = cardinal (filter f s0) -> fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s' 0 = cardinal (filter f s')f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0) -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) (add x s0) 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s, s0, s':tH:equal s0 s' = trueH0:fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s0 0 = cardinal (filter f s0)fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s' 0 = cardinal (filter f s')f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0) -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) (add x s0) 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s, s0, s':tH:equal s0 s' = trueH0:fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s0 0 = cardinal (filter f s0)fold (fun x : E.t => Init.Nat.add (if f x then 1 else 0)) s' 0 = cardinal (filter f s')f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0) -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) (add x s0) 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s, s0, s':tH:equal s0 s' = trueH0:fold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) s0 0 = cardinal (filter f s0)fold (fun x : E.t => Init.Nat.add (if f x then 1 else 0)) s0 0 = cardinal (filter f s')f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0) -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) (add x s0) 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tforall (s0 : t) (x : elt), mem x s0 = false -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0) -> fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) (add x s0) 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)(if f x then 1 else 0) + fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)(f x = true -> Add x s0 (add x s0) -> Add x (filter f s0) (filter f (add x s0))) -> (f x = false -> Add x s0 (add x s0) -> filter f s0 [=] filter f (add x s0)) -> (if f x then 1 else 0) + fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)~ In x (filter f s0)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)H1:~ In x (filter f s0)(f x = true -> Add x s0 (add x s0) -> Add x (filter f s0) (filter f (add x s0))) -> (f x = false -> Add x s0 (add x s0) -> filter f s0 [=] filter f (add x s0)) -> (if f x then 1 else 0) + fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)H1:~ In x (filter f s0)(f x = true -> Add x s0 (add x s0) -> Add x (filter f s0) (filter f (add x s0))) -> (f x = false -> Add x s0 (add x s0) -> filter f s0 [=] filter f (add x s0)) -> (if f x then 1 else 0) + fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)H1:~ In x (filter f s0)H2:true = true -> Add x s0 (add x s0) -> Add x (filter f s0) (filter f (add x s0))H3:true = false -> Add x s0 (add x s0) -> filter f s0 [=] filter f (add x s0)S (fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0) = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)H1:~ In x (filter f s0)H2:false = true -> Add x s0 (add x s0) -> Add x (filter f s0) (filter f (add x s0))H3:false = false -> Add x s0 (add x s0) -> filter f s0 [=] filter f (add x s0)fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))ct:transposeL (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0))s, s0:tx:eltH:mem x s0 = falseH0:fold (fun x0 : elt => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f s0)H1:~ In x (filter f s0)H2:false = true -> Add x s0 (add x s0) -> Add x (filter f s0) (filter f (add x s0))H3:false = false -> Add x s0 (add x s0) -> filter f s0 [=] filter f (add x s0)fold (fun x0 : E.t => Init.Nat.add (if f x0 then 1 else 0)) s0 0 = cardinal (filter f (add x s0))f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tfold (fun x : elt => Init.Nat.add (if f x then 1 else 0)) empty 0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:t0 = cardinal (filter f empty)f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:tEmpty (filter f empty)rewrite filter_iff; auto; set_iff; tauto. Qed.f:E.t -> boolHf:compat_bool E.eq fst:Equivalence Logic.eqcc:compat_opL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))ct:transposeL (fun x : E.t => Init.Nat.add (if f x then 1 else 0))s:ta:elt~ In a (filter f empty)forall (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall f g : elt -> A -> A, compat_op E.eq eqA f -> transpose eqA f -> compat_op E.eq eqA g -> transpose eqA g -> forall (i : A) (s : t), (forall x : elt, In x s -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s i) (fold g s i)forall (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall f g : elt -> A -> A, compat_op E.eq eqA f -> transpose eqA f -> compat_op E.eq eqA g -> transpose eqA g -> forall (i : A) (s : t), (forall x : elt, In x s -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s i) (fold g s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:Aforall s : t, (forall x : elt, In x s -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s i) (fold g s i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold f s' i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold f s' i) (fold f s0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold f s0 i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)equal s' s0 = trueA:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold f s0 i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold f s0 i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold f s0 i) (fold g s0 i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold g s0 i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x0 : elt, In x0 s0 -> forall y0 : A, eqA (f x0 y0) (g x0 y0)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 s' -> forall y0 : A, eqA (f x0 y0) (g x0 y0)x:eltH2:In x s0y:AIn x s'A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold g s0 i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0, s':tH:equal s0 s' = trueH0:(forall x : elt, In x s0 -> forall y : A, eqA (f x y) (g x y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x : elt, In x s' -> forall y : A, eqA (f x y) (g x y)eqA (fold g s0 i) (fold g s' i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (fold f (add x s0) i) (f x (fold f s0 i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (f x (fold f s0 i)) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (f x (fold f s0 i)) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (g x (fold f s0 i)) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (g x (fold f s0 i)) (g x (fold g s0 i))A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (g x (fold g s0 i)) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As, s0:tx:eltH:mem x s0 = falseH0:(forall x0 : elt, In x0 s0 -> forall y : A, eqA (f x0 y) (g x0 y)) -> eqA (fold f s0 i) (fold g s0 i)H1:forall x0 : elt, In x0 (add x s0) -> forall y : A, eqA (f x0 y) (g x0 y)eqA (g x (fold g s0 i)) (fold g (add x s0) i)A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)do 2 rewrite fold_empty; reflexivity. Qed.A:TypeeqA:A -> A -> Propst:Equivalence eqAf, g:elt -> A -> Afc:compat_op E.eq eqA fft:transpose eqA fgc:compat_op E.eq eqA ggt:transpose eqA gi:As:tH:forall x : elt, In x empty -> forall y : A, eqA (f x y) (g x y)eqA (fold f empty i) (fold g empty i)forall f g : E.t -> nat, Proper (E.eq ==> Logic.eq) f -> Proper (E.eq ==> Logic.eq) g -> forall s : t, (forall x : elt, In x s -> f x = g x) -> sum f s = sum g sf, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x : elt, In x s -> f x = g xsum f s = sum g sf, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x : elt, In x s -> f x = g xcompat_opL (fun x : elt => Init.Nat.add (f x))f, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x : elt, In x s -> f x = g xcompat_opL (fun x : elt => Init.Nat.add (g x))f, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x0 : elt, In x0 s -> f x0 = g x0x, x':E.tHx:E.eq x x'y, y':natHy:y = y'f x + y = f x' + y'f, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x : elt, In x s -> f x = g xcompat_opL (fun x : elt => Init.Nat.add (g x))f, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x : elt, In x s -> f x = g xcompat_opL (fun x : elt => Init.Nat.add (g x))rewrite Hx, Hy; auto. Qed. End Sum. End WEqProperties_fun.f, g:E.t -> natH:Proper (E.eq ==> Logic.eq) fH0:Proper (E.eq ==> Logic.eq) gs:tH1:forall x0 : elt, In x0 s -> f x0 = g x0x, x':E.tHx:E.eq x x'y, y':natHy:y = y'g x + y = g x' + y'
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 EqProperties functor which is meant to be
used on modules (M:S) can simply be an alias of WEqProperties.
Module WEqProperties (M:WS) := WEqProperties_fun M.E M. Module EqProperties := WEqProperties.