Built with Alectryon, running Coq+SerAPI v8.20.0+0.20.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file ssrmatching_plugin.cmxs (using legacy method) ... done]
[Loading ML file ssreflect_plugin.cmxs (using legacy method) ... done]
[Loading ML file ring_plugin.cmxs (using legacy method) ... done]
Serlib plugin: coq-elpi.elpi is not available: serlib support is missing.
Incremental checking for commands in this plugin will be impacted.
[Loading ML file coq-elpi.elpi ... done]
Notation"_ + _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ - _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ <= _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ < _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ >= _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ > _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ <= _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ < _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ <= _ < _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ < _ < _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ * _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
[Loading ML file zify_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_core_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_plugin.cmxs (using legacy method) ... done]
[Loading ML file btauto_plugin.cmxs (using legacy method) ... done]
SectionSumsOverSequences.(** Consider any type [I] with a decidable equality ... *)Variable (I : eqType).(** ... and assume we are given a sequence ... *)Variable (r : seq I).(** ... and a predicate [P]. *)Variable (P : pred I).(** First, we will show some properties of the sum performed over a single function yielding natural numbers. *)SectionSumOfOneFunction.(** Consider any function that yields natural numbers. *)Variable (F : I -> nat).(** We start showing that having every member of [r] equal to zero is equivalent to having the sum of all the elements of [r] equal to zero, and vice-versa. *)
I: eqType r: seq I P: pred I F: I -> nat
(\sum_(i <- r | P i) F i == 0) =
all (funx : I => F x == 0) [seq x <- r | P x]
I: eqType r: seq I P: pred I F: I -> nat
(\sum_(i <- r | P i) F i == 0) =
all (funx : I => F x == 0) [seq x <- r | P x]
I: eqType r: seq I P: pred I F: I -> nat x: I r': seq I IH: (\sum_(i <- r' | P i) F i == 0) =
all (funx : I => F x == 0) [seq x <- r' | P x]
((if P x
then F x + \sum_(j <- r' | P j) F j
else \sum_(j <- r' | P j) F j) == 0) =
all (funx : I => F x == 0)
(if P x
then x :: [seq x <- r' | P x]
else [seq x <- r' | P x])
bycase: ifP; rewrite?addn_eq0 IH.Qed.(** In the same way, if at least one element of [r] is not zero, then the sum of all elements of [r] must be strictly positive, and vice-versa. *)
I: eqType r: seq I P: pred I F: I -> nat
(0 < \sum_(i <- r | P i) F i) =
has (funx : I => 0 < F x) [seq x <- r | P x]
I: eqType r: seq I P: pred I F: I -> nat
(0 < \sum_(i <- r | P i) F i) =
has (funx : I => 0 < F x) [seq x <- r | P x]
I: eqType r: seq I P: pred I F: I -> nat
all (funx : I => F x == 0) [seq x <- r | P x] =
all (predC (funx : I => 0 < F x)) [seq x <- r | P x]
byapply/eq_all => ?; rewrite /= lt0n negbK.Qed.(** Next, we show that if a number [a] is not contained in [r], then filtering or not filtering [a] when summing leads to the same result. *)
I: eqType r: seq I P: pred I F: I -> nat a: I
a \notin r ->
\sum_(x <- r | P x && (x != a)) F x =
\sum_(x <- r | P x) F x
I: eqType r: seq I P: pred I F: I -> nat a: I
a \notin r ->
\sum_(x <- r | P x && (x != a)) F x =
\sum_(x <- r | P x) F x
I: eqType r: seq I P: pred I F: I -> nat a: I a_notin_r: a \notin r
\sum_(i <- r | [&& i \in r, P i & i != a]) F i =
\sum_(i <- r | (i \in r) && P i) F i
I: eqType r: seq I P: pred I F: I -> nat a: I a_notin_r: a \notin r x: I xinr: (x \in r) = true
P x && (x != a) = P x
I: eqType r: seq I P: pred I F: I -> nat a: I a_notin_r: a \notin r x: I xinr: (x \in r) = true xa: x = a
P x && ~~ true = P x
bymove: xinr a_notin_r; rewrite xa => ->.Qed.(** We prove that if any element of [r] is bounded by constant [c], then the sum of the whole set is bounded by [c * size r]. *)
I: eqType r: seq I P: pred I F: I -> nat c: nat
(foralla : I, a \in r -> P a -> F a <= c) ->
\sum_(j <- r | P j) F j <= c * size [seq j <- r | P j]
I: eqType r: seq I P: pred I F: I -> nat c: nat
(foralla : I, a \in r -> P a -> F a <= c) ->
\sum_(j <- r | P j) F j <= c * size [seq j <- r | P j]
I: eqType r: seq I P: pred I F: I -> nat c: nat Fa_le_c: foralla : I, a \in r -> P a -> F a <= c
\sum_(j <- r | P j) F j <= c * size [seq j <- r | P j]
I: eqType r: seq I P: pred I F: I -> nat c: nat Fa_le_c: foralla : I, a \in r -> P a -> F a <= c
\sum_(j <- r | P j) F j <= \sum_(i <- r | P i) c
I: eqType r: seq I P: pred I F: I -> nat c: nat Fa_le_c: foralla : I, a \in r -> P a -> F a <= c
\sum_(i <- r | (i \in r) && P i) F i <=
\sum_(i <- r | (i \in r) && P i) c
apply: leq_sum => i /andP[ir Pi]; exact: Fa_le_c.Qed.(** Next, we show that the sum of the elements in [r] respecting [P] can be obtained by removing from the total sum over [r] the sum of the elements in [r] not respecting [P]. *)
I: eqType r: seq I P: pred I F: I -> nat
\sum_(r <- r | P r) F r =
\sum_(r <- r) F r - \sum_(r <- r | ~~ P r) F r
I: eqType r: seq I P: pred I F: I -> nat
\sum_(r <- r | P r) F r =
\sum_(r <- r) F r - \sum_(r <- r | ~~ P r) F r
byrewrite [X in X - _](bigID P)/= addnK.Qed.(** Next, we show that if the predicate [P] is a disjunction of the predicates [Q] and [R], and [Q] and [R] can never be simultaneously satisfied by any element, then the sum of elements in [r] respecting [P] can be obtained by adding the sum of elements in [r] respecting [Q] and the elements in [r] respecting [R]. *)
I: eqType r: seq I P: pred I F: I -> nat
forallQR : I -> bool,
(forallx : I, P x = Q x || R x) ->
(forallx : I, ~~ (Q x && R x)) ->
\sum_(r <- r | P r) F r =
\sum_(r <- r | Q r) F r + \sum_(r <- r | R r) F r
I: eqType r: seq I P: pred I F: I -> nat
forallQR : I -> bool,
(forallx : I, P x = Q x || R x) ->
(forallx : I, ~~ (Q x && R x)) ->
\sum_(r <- r | P r) F r =
\sum_(r <- r | Q r) F r + \sum_(r <- r | R r) F r
I: eqType r: seq I P: pred I F: I -> nat Q, R: I -> bool XOR: forallx : I, P x = Q x || R x nAnd: forallx : I, ~~ (Q x && R x)
\sum_(r <- r | P r) F r =
\sum_(r <- r | Q r) F r + \sum_(r <- r | R r) F r
rewrite (bigID Q) /=; congr (_ + _); apply eq_bigl=> i;
specialize (XOR i); rewrite XOR; specialize (nAnd i);
bycase: (Q i) nAnd; case : (R i).Qed.(** We also prove that the maximum value taken by a function over elements of a range [r] satisfying any predicate [P] is always smaller than the sum of the function over the elements. *)
I: eqType r: seq I P: pred I F: I -> nat
\max_(i <- r | P i) F i <= \sum_(i <- r | P i) F i
I: eqType r: seq I P: pred I F: I -> nat
\max_(i <- r | P i) F i <= \sum_(i <- r | P i) F i
I: eqType r: seq I P: pred I F: I -> nat m1, n1, m2, n2: nat le1: m1 <= n1 le2: m2 <= n2
maxn m1 m2 <= n1 + n2
byrewrite (leq_trans (max_leq_add m1 m2)) ?leq_add.Qed.(** We show that if [r1] is a subsequence of [r2], then the sum of function [F] over elements satisfying predicate [P] in [r1] is less than or equal to the sum over elements satisfying [P] in [r2]. *)
I: eqType r: seq I P: pred I F: I -> nat
forallr1r2 : seq I,
subseq r1 r2 ->
\sum_(x <- r1 | P x) F x <= \sum_(x <- r2 | P x) F x
I: eqType r: seq I P: pred I F: I -> nat
forallr1r2 : seq I,
subseq r1 r2 ->
\sum_(x <- r1 | P x) F x <= \sum_(x <- r2 | P x) F x
I: eqType r: seq I P: pred I F: I -> nat r1, r2: seq I SUB: subseq r1 r2
\sum_(x <- r1 | P x) F x <= \sum_(x <- r2 | P x) F x
I: eqType r: seq I P: pred I F: I -> nat r1, r2: seq I SUB: subseq r1 r2
foralli : I, count_mem i r1 <= count_mem i r2
I: eqType r: seq I P: pred I F: I -> nat r1, r2: seq I SUB: subseq r1 r2
exists2 s : seq I, subseq s r2 & perm_eq r1 s
byexistsr1.Qed.EndSumOfOneFunction.(** In this section, we show some properties of the sum performed over two different functions. *)SectionSumOfTwoFunctions.(** Consider three functions that yield natural numbers. *)Variable (EE1E2 : I -> nat).(** Besides earlier introduced predicate [P], we add two additional predicates [P1] and [P2]. *)Variable (P1P2 : pred I).(** Assume that [E2] dominates [E1] in all the points contained in the set [r] and respecting the predicate [P]. We prove that, if we sum both function over those points, then the sum of [E2] will dominate the sum of [E1]. *)
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I
(foralli : I, i \in r -> P i -> E1 i <= E2 i) ->
\sum_(i <- r | P i) E1 i <= \sum_(i <- r | P i) E2 i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I
(foralli : I, i \in r -> P i -> E1 i <= E2 i) ->
\sum_(i <- r | P i) E1 i <= \sum_(i <- r | P i) E2 i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I le: foralli : I, i \in r -> P i -> E1 i <= E2 i
\sum_(i <- r | (i \in r) && P i) E1 i <=
\sum_(i <- r | (i \in r) && P i) E2 i
apply: leq_sum => i /andP[]; exact: le.Qed.(** In the same way, if [E1] equals [E2] in all the points considered above, then also the two sums will be identical. *)
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I
(foralli : I, i \in r -> P i -> E1 i == E2 i) ->
\sum_(i <- r | P i) E1 i = \sum_(i <- r | P i) E2 i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I
(foralli : I, i \in r -> P i -> E1 i == E2 i) ->
\sum_(i <- r | P i) E1 i = \sum_(i <- r | P i) E2 i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I eqE: foralli : I, i \in r -> P i -> E1 i == E2 i
\sum_(i <- [seq x <- r | P x]) E1 i =
\sum_(i <- [seq x <- r | P x]) E2 i
byapply: eq_big_seq => x; rewrite mem_filter => /andP[Px xr]; exact/eqP.Qed.(** Assume that [P1] implies [P2] in all the points contained in the set [r]. We prove that, if we sum both functions over those points, then the sum of [E] conditioned by [P2] will dominate the sum of [E] conditioned by [P1]. *)
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I
(foralli : I, i \in r -> P1 i -> P2 i) ->
\sum_(i <- r | P1 i) E i <= \sum_(i <- r | P2 i) E i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I
(foralli : I, i \in r -> P1 i -> P2 i) ->
\sum_(i <- r | P1 i) E i <= \sum_(i <- r | P2 i) E i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I imp: foralli : I, i \in r -> P1 i -> P2 i
\sum_(i <- r | P1 i) E i <=
\sum_(i <- r | P2 i && P1 i) E i +
\sum_(i <- r | P2 i && ~~ P1 i) E i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I imp: foralli : I, i \in r -> P1 i -> P2 i
\sum_(i <- r | (i \in r) && P1 i) E i <=
\sum_(i <- r | [&& i \in r, P2 i & P1 i]) E i +
\sum_(i <- r | P2 i && ~~ P1 i) E i
I: eqType r: seq I P: pred I E, E1, E2: I -> nat P1, P2: pred I imp: foralli : I, i \in r -> P1 i -> P2 i i: I
(i \in r) && P1 i = [&& i \in r, P2 i & P1 i]
bycase ir: (i \in r); case P1i: (P1 i); rewrite?andbF //= (imp i).Qed.EndSumOfTwoFunctions.EndSumsOverSequences.(** For technical (and temporary) reasons related to the proof style, the next two lemmas are stated outside of the section, but conceptually make use of a similar context. First, we observe that summing over a subset of a given sequence, if all summands are natural numbers, cannot yield a larger sum. *)
I: eqType r, r': seq I P: pred I F: I -> nat
subseq r r' ->
\sum_(i <- r | P i) F i <= \sum_(i <- r' | P i) F i
I: eqType r, r': seq I P: pred I F: I -> nat
subseq r r' ->
\sum_(i <- r | P i) F i <= \sum_(i <- r' | P i) F i
I: eqType P: pred I F: I -> nat x: I r: seq I IH: forallr' : seq I,
subseq r r' ->
\sum_(i <- r | P i) F i <=
\sum_(i <- r' | P i) F i r': seq I
subseq (x :: r) r' ->
\sum_(i <- (x :: r) | P i) F i <=
\sum_(i <- r' | P i) F i
I: eqType P: pred I F: I -> nat x: I r: seq I x': I r': seq I IH': subseq (x :: r) r' ->
\sum_(i <- (x :: r) | P i) F i <= \sum_(i <- r' | P i) F i IH: \sum_(i <- r | P i) F i <=
\sum_(i <- r' | P i) F i
\sum_(i <- (x :: r) | P i) F i <=
\sum_(i <- (x :: r') | P i) F i
I: eqType P: pred I F: I -> nat x: I r: seq I IH: forallr' : seq I,
subseq r r' ->
\sum_(i <- r | P i) F i <=
\sum_(i <- r' | P i) F i x': I r': seq I IH': \sum_(i <- (x :: r) | P i) F i <= \sum_(i <- r' | P i) F i
\sum_(i <- (x :: r) | P i) F i <=
\sum_(i <- (x' :: r') | P i) F i
I: eqType P: pred I F: I -> nat x: I r: seq I x': I r': seq I IH': subseq (x :: r) r' ->
\sum_(i <- (x :: r) | P i) F i <= \sum_(i <- r' | P i) F i IH: \sum_(i <- r | P i) F i <=
\sum_(i <- r' | P i) F i
\sum_(i <- (x :: r) | P i) F i <=
\sum_(i <- (x :: r') | P i) F i
I: eqType P: pred I F: I -> nat x: I r: seq I IH: forallr' : seq I,
subseq r r' ->
\sum_(i <- r | P i) F i <=
\sum_(i <- r' | P i) F i x': I r': seq I IH': \sum_(i <- (x :: r) | P i) F i <= \sum_(i <- r' | P i) F i
\sum_(i <- (x :: r) | P i) F i <=
\sum_(i <- (x' :: r') | P i) F i
I: eqType P: pred I F: I -> nat x: I r: seq I IH: forallr' : seq I,
subseq r r' ->
\sum_(i <- r | P i) F i <=
\sum_(i <- r' | P i) F i x': I r': seq I IH': \sum_(i <- (x :: r) | P i) F i <= \sum_(i <- r' | P i) F i
\sum_(i <- (x :: r) | P i) F i <=
F x' + \sum_(j <- r' | P j) F j
exact: leq_trans (leq_addl _ _).Qed.(** Second, we repeat the above observation that summing a superset of natural numbers cannot yield a lesser sum, but phrase the claim differently. Requiring the absence of duplicate in [r] is a simple way to guarantee that the set inclusion [r <= rs] implies the actually required multiset inclusion. *)
I: eqType r: seq I F: I -> nat rs: seq I
uniq r ->
{subset r <= rs} ->
\sum_(i <- r) F i <= \sum_(i <- rs) F i
I: eqType r: seq I F: I -> nat rs: seq I
uniq r ->
{subset r <= rs} ->
\sum_(i <- r) F i <= \sum_(i <- rs) F i
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
\sum_(i <- r) F i <= \sum_(i <- rs) F i
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
\sum_(i <- r) F i <=
\sum_(i <- rs | i \in r) F i +
\sum_(i <- rs | i \notin r) F i
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
\sum_(i <- r) F i <= \sum_(i <- rs | i \in r) F i
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
\big[ssrnat_addn__canonical__SemiGroup_ComLaw/0]_(i <-
undup [seq x <- rs | x \in r]) F i <=
\sum_(i <- rs | i \in r) F i
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
perm_eq r (undup [seq x <- rs | x \in r])
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
\big[ssrnat_addn__canonical__SemiGroup_ComLaw/0]_(i <-
undup [seq x <- rs | x \in r]) F i <=
\sum_(i <- rs | i \in r) F i
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
\sum_(i <- undup rs | (i \in r) && true) F i <=
\sum_(i <- rs | i \in r) F i
under eq_bigl => ? dorewrite andbT; exact/leq_sum_subseq/undup_subseq.
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs}
perm_eq r (undup [seq x <- rs | x \in r])
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs} x: I
(x \in r) = (x \in undup [seq x <- rs | x \in r])
I: eqType r: seq I F: I -> nat rs: seq I uniq_r: uniq r sub_r_rs: {subset r <= rs} x: I
(x \in r) = (x \in r) && (x \in rs)
bycase xinr: (x \in r); rewrite // (sub_r_rs _ xinr).Qed.(** We continue establishing properties of sums over sequences, but start a new section here because some of the below proofs depend lemmas in the preceding section in their full generality. *)SectionSumsOverSequences.(** Consider any type [I] with a decidable equality ... *)Variable (I : eqType).(** ... and assume we are given a sequence ... *)Variable (r : seq I).(** ... and a predicate [P]. *)Variable (P : pred I).(** Consider two functions that yield natural numbers. *)Variable (E1E2 : I -> nat).(** First, as an auxiliary lemma, we observe that, if [E1 j] is less than [E2 j] for some element [j] involved in a summation (filtered by [P]), then the corresponding totals are not equal. *)
I: eqType r: seq I P: pred I E1, E2: I -> nat j: I
j \in r ->
P j ->
E1 j < E2 j ->
(foralli : I, i \in r -> P i -> E1 i <= E2 i) ->
\sum_(x <- r | P x) E1 x < \sum_(x <- r | P x) E2 x
I: eqType r: seq I P: pred I E1, E2: I -> nat j: I
j \in r ->
P j ->
E1 j < E2 j ->
(foralli : I, i \in r -> P i -> E1 i <= E2 i) ->
\sum_(x <- r | P x) E1 x < \sum_(x <- r | P x) E2 x
I: eqType r: seq I P: pred I E1, E2: I -> nat j: I jr: j \in r Pj: P j ltj: E1 j < E2 j le: foralli : I, i \in r -> P i -> E1 i <= E2 i
\sum_(x <- r | P x) E1 x < \sum_(x <- r | P x) E2 x
I: eqType r: seq I P: pred I E1, E2: I -> nat j: I jr: j \in r Pj: P j ltj: E1 j < E2 j le: foralli : I, i \in r -> P i -> E1 i <= E2 i
\sum_(y <- rem (T:=I) j r | P y) E1 y <=
\sum_(y <- rem (T:=I) j r | P y) E2 y
apply: leq_sum_seq => i /mem_rem; exact: le.Qed.(** Next, we prove that if for any element i of a set [r] the following two statements hold (1) [E1 i] is less than or equal to [E2 i] and (2) the sum [E1 x_1, ..., E1 x_n] is equal to the sum of [E2 x_1, ..., E2 x_n], then [E1 x] is equal to [E2 x] for any element x of [xs]. *)
I: eqType r: seq I P: pred I E1, E2: I -> nat
(foralli : I, i \in r -> P i -> E1 i <= E2 i) ->
(\sum_(x <- r | P x) E1 x == \sum_(x <- r | P x) E2 x) =
all (funx : I => E1 x == E2 x) [seq x <- r | P x]
I: eqType r: seq I P: pred I E1, E2: I -> nat
(foralli : I, i \in r -> P i -> E1 i <= E2 i) ->
(\sum_(x <- r | P x) E1 x == \sum_(x <- r | P x) E2 x) =
all (funx : I => E1 x == E2 x) [seq x <- r | P x]
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false
(\sum_(x <- r | P x) E1 x == \sum_(x <- r | P x) E2 x) =
false
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false
exists2 j : I, (j \in r) && P j & E1 j < E2 j
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false j: I jr: j \in r Pj: P j ltj: E1 j < E2 j
(\sum_(x <- r | P x) E1 x == \sum_(x <- r | P x) E2 x) =
false
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false
exists2 j : I, (j \in r) && P j & E1 j < E2 j
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false j: I jr: j \in r
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false j: I jr: j \in r Pj: P j neq: E1 j != E2 j
exists2 j : I, (j \in r) && P j & E1 j < E2 j
byexistsj; firstexact/andP; rewrite ltn_neqAle neq le.
I: eqType r: seq I P: pred I E1, E2: I -> nat le: foralli : I, i \in r -> P i -> E1 i <= E2 i aE: all [pred i | P i ==> (E1 i == E2 i)] r = false j: I jr: j \in r Pj: P j ltj: E1 j < E2 j
(\sum_(x <- r | P x) E1 x == \sum_(x <- r | P x) E2 x) =
false
byapply/negbTE; rewrite neq_ltn (ltn_sum_leq_seq j).Qed.EndSumsOverSequences.(** In this section, we prove a variety of properties of sums performed over ranges. *)SectionSumsOverRanges.(** First, we prove that the sum of Δ ones is equal to Δ . *)
foralltΔ : nat, \sum_(t <= x < t + Δ) 1 = Δ
foralltΔ : nat, \sum_(t <= x < t + Δ) 1 = Δ
bymove=> t Δ; rewrite big_const_nat iter_addn_0 mul1n addKn.Qed.(** Next, we show that a sum of natural numbers equals zero if and only if all terms are zero. *)
m, n: nat F: nat -> nat
\sum_(m <= i < n) F i = 0 <->
(foralli : nat, m <= i < n -> F i = 0)
m, n: nat F: nat -> nat
\sum_(m <= i < n) F i = 0 <->
(foralli : nat, m <= i < n -> F i = 0)
m, n: nat F: nat -> nat
\sum_(m <= i < n) F i = 0 ->
foralli : nat, m <= i < n -> F i = 0
m, n: nat F: nat -> nat
(foralli : nat, m <= i < n -> F i = 0) ->
\sum_(m <= i < n) F i = 0
m, n: nat F: nat -> nat
\sum_(m <= i < n) F i = 0 ->
foralli : nat, m <= i < n -> F i = 0
m, n: nat F: nat -> nat
\sum_(i <- iota m (n - m)) F i == 0 ->
foralli : nat, m <= i < n -> F i = 0
m, n: nat F: nat -> nat ZERO: {in iota m (n - m),
forallx : Datatypes_nat__canonical__eqtype_Equality,
F x == 0} i: nat
m <= i < n -> F i = 0
m, n: nat F: nat -> nat ZERO: {in iota m (n - m),
forallx : Datatypes_nat__canonical__eqtype_Equality,
F x == 0} i: nat IN: i \in iota m (n - m)
F i = 0
byapply/eqP; apply ZERO.
m, n: nat F: nat -> nat
(foralli : nat, m <= i < n -> F i = 0) ->
\sum_(m <= i < n) F i = 0
m, n: nat F: nat -> nat ZERO: foralli : nat, m <= i < n -> F i = 0
\sum_(m <= i < n) F i = 0
m, n: nat F: nat -> nat ZERO: foralli : nat, m <= i < n -> F i = 0
\sum_(m <= i < n) 0 = 0
exact: big1_eq.Qed.(** Moreover, the fact that the sum is smaller than the range of the summation implies the existence of a zero element. *)
forall (f : nat -> nat) (tΔ : nat),
\sum_(t <= x < t + Δ) f x < Δ ->
existsx : nat, t <= x < t + Δ /\ f x = 0
forall (f : nat -> nat) (tΔ : nat),
\sum_(t <= x < t + Δ) f x < Δ ->
existsx : nat, t <= x < t + Δ /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
existsx : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1 EQ: f (t + Δ) = 0
existsx : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1 n: nat EQ: f (t + Δ) = n.+1
existsx : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1 EQ: f (t + Δ) = 0
existsx : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1 EQ: f (t + Δ) = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1 n: nat EQ: f (t + Δ) = n.+1
existsx : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1 n: nat EQ: f (t + Δ) = n.+1
existsx : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 n: nat EQ: f (t + Δ) = n.+1 H: \sum_(t <= i < t + Δ) f i + n < Δ
existsx : nat, t <= x < (t + Δ).+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 n: nat EQ: f (t + Δ) = n.+1 H: \sum_(t <= i < t + Δ) f i + n < Δ
\sum_(t <= t' < t + Δ) f t' < Δ
f: nat -> nat t, Δ, n: nat EQ: f (t + Δ) = n.+1 H: \sum_(t <= i < t + Δ) f i + n < Δ z: nat LE: t <= z GE: z < t + Δ ZERO: f z = 0
existsx : nat, t <= x < (t + Δ).+1 /\ f x = 0
f: nat -> nat t, Δ: nat IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> existsx : nat, t <= x < t + Δ /\ f x = 0 n: nat EQ: f (t + Δ) = n.+1 H: \sum_(t <= i < t + Δ) f i + n < Δ
\sum_(t <= t' < t + Δ) f t' < Δ
byapply leq_ltn_trans with (\sum_(t <= i < t + Δ) f i + n); firstrewrite leq_addr.
f: nat -> nat t, Δ, n: nat EQ: f (t + Δ) = n.+1 H: \sum_(t <= i < t + Δ) f i + n < Δ z: nat LE: t <= z GE: z < t + Δ ZERO: f z = 0
existsx : nat, t <= x < (t + Δ).+1 /\ f x = 0
byexistsz; split=> //; rewrite LE/= ltnS ltnW.}Qed.(** Next, we prove that the summing over the difference of two functions is the same as summing over the two functions separately, and then taking the difference of the two sums. Since we are using natural numbers, we have to require that one function dominates the other in the summing range. *)
m, n: nat F, G: nat -> nat
(foralli : nat, m <= i < n -> G i <= F i) ->
\sum_(m <= i < n) (F i - G i) =
\sum_(m <= i < n) F i - \sum_(m <= i < n) G i
m, n: nat F, G: nat -> nat
(foralli : nat, m <= i < n -> G i <= F i) ->
\sum_(m <= i < n) (F i - G i) =
\sum_(m <= i < n) F i - \sum_(m <= i < n) G i
m, n: nat F, G: nat -> nat le: foralli : nat, m <= i < n -> G i <= F i
\sum_(m <= i < n) (F i - G i) =
\sum_(m <= i < n) F i - \sum_(m <= i < n) G i
m, n: nat F, G: nat -> nat le: foralli : nat, m <= i < n -> G i <= F i
\sum_(m <= i < n | (m <= i < n) && true) (F i - G i) =
\sum_(m <= i < n | (m <= i < n) && true) F i -
\sum_(m <= i < n | (m <= i < n) && true) G i
rewrite sumnB// => i; rewrite andbT; exact: le.Qed.EndSumsOverRanges.(** In this section, we show how it is possible to equate the result of two sums performed on two different functions and on different intervals, provided that the two functions match point-wise. *)SectionSumOfTwoIntervals.(** Consider two equally-sized intervals <<[t1, t1+d)>> and <<[t2, t2+d)>>... *)Variable (t1t2 : nat).Variable (d : nat).(** ...and two functions [F1] and [F2]. *)Variable (F1F2 : nat -> nat).(** Assume that the two functions match point-wise with each other, with the points taken in their respective interval. *)Hypothesisequal_before_d: forallg, g < d -> F1 (t1 + g) = F2 (t2 + g).(** The then summations of [F1] over <<[t1, t1 + d)>> and [F2] over <<[t2, t2 + d)>> are equal. *)
t1, t2, d: nat F1, F2: nat -> nat equal_before_d: forallg : nat,
g < d -> F1 (t1 + g) = F2 (t2 + g)
\sum_(t1 <= t < t1 + d) F1 t =
\sum_(t2 <= t < t2 + d) F2 t
t1, t2, d: nat F1, F2: nat -> nat equal_before_d: forallg : nat,
g < d -> F1 (t1 + g) = F2 (t2 + g)
\sum_(t1 <= t < t1 + d) F1 t =
\sum_(t2 <= t < t2 + d) F2 t
t1, t2, d: nat F1, F2: nat -> nat equal_before_d: forallg : nat,
g < d -> F1 (t1 + g) = F2 (t2 + g) n: nat IHn: (forallg : nat,
g < n -> F1 (t1 + g) = F2 (t2 + g)) ->
\sum_(t1 <= t < t1 + n) F1 t =
\sum_(t2 <= t < t2 + n) F2 t eq: forallg : nat,
g < n.+1 -> F1 (t1 + g) = F2 (t2 + g)
\sum_(t1 <= t < t1 + n.+1) F1 t =
\sum_(t2 <= t < t2 + n.+1) F2 t
t1, t2, d: nat F1, F2: nat -> nat equal_before_d: forallg : nat,
g < d -> F1 (t1 + g) = F2 (t2 + g) n: nat IHn: (forallg : nat,
g < n -> F1 (t1 + g) = F2 (t2 + g)) ->
\sum_(t1 <= t < t1 + n) F1 t =
\sum_(t2 <= t < t2 + n) F2 t eq: forallg : nat,
g < n.+1 -> F1 (t1 + g) = F2 (t2 + g)
ssrnat_addn__canonical__Monoid_Law
(\big[ssrnat_addn__canonical__Monoid_Law/0]_(t1 <= i <
t1 + n) F1 i) (F1 (t1 + n)) =
ssrnat_addn__canonical__Monoid_Law
(\big[ssrnat_addn__canonical__Monoid_Law/0]_(t2 <= i <
t2 + n) F2 i) (F2 (t2 + n))
byrewrite IHn.Qed.EndSumOfTwoIntervals.(** In this section, we relate the sum of items with the sum over partitions of those items. *)SectionSumOverPartitions.(** Consider an item type [X] and a partition type [Y]. *)VariableXY : eqType.(** [x_to_y] is the mapping from an item to the partition it is contained in. *)Variablex_to_y : X -> Y.(** Consider [f], a function from [X] to [nat]. *)Variablef : X -> nat.(** Consider an arbitrary predicate [P] on [X]. *)VariableP : pred X.(** Consider a sequence of items [xs] and a sequence of partitions [ys]. *)Variablexs : seq X.Variableys : seq Y.(** We assume that any item in [xs] has its corresponding partition in the sequence of partitions [ys]. *)HypothesisH_no_partition_missing : forallx, x \in xs -> P x -> x_to_y x \in ys.(** Consider the sum of [f x] over all [x] in a given partition [y]. *)Letsum_of_partitiony := \sum_(x <- xs | P x && (x_to_y x == y)) f x.(** We prove that summation of [f x] over all [x] is less than or equal to the summation of [sum_of_partition] over all partitions. *)
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat
\sum_(x <- xs | P x) f x <=
\sum_(y <- ys) sum_of_partition y
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat
\sum_(x <- xs | P x) f x <=
\sum_(y <- ys) sum_of_partition y
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat
\sum_(x <- xs | P x) f x <=
\sum_(y <- ys)
\sum_(x <- xs | P x && (x_to_y x == y)) f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
letsum_of_partition :=
funy : Y =>
\sum_(x <- xs' | P x && (x_to_y x == y))
f x in
\sum_(x <- xs' | P x) f x <=
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
\sum_(x <- (x' :: xs') | P x) f x <=
\sum_(y <- ys)
\sum_(x <- (x' :: xs') | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
letsum_of_partition :=
funy : Y =>
\sum_(x <- xs' | P x && (x_to_y x == y))
f x in
\sum_(x <- xs' | P x) f x <=
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j
\sum_(x <- (x' :: xs') | P x) f x <=
\sum_(y <- ys)
\sum_(x <- (x' :: xs') | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
letsum_of_partition :=
funy : Y =>
\sum_(x <- xs' | P x && (x_to_y x == y))
f x in
\sum_(x <- xs' | P x) f x <=
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys
\sum_(x <- (x' :: xs') | P x) f x <=
\sum_(y <- ys)
\sum_(x <- (x' :: xs') | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j
\sum_(x <- (x' :: xs') | P x) f x <=
\sum_(y <- ys)
\sum_(x <- (x' :: xs') | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j
(if P x'
then f x' + \sum_(j <- xs' | P j) f j
else \sum_(j <- xs' | P j) f j) <=
(if P x'
then
\sum_(i <- ys | P x' && (x_to_y x' == i)) f x' +
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
else
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j)
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j PX: P x' = true
f x' + \sum_(j <- xs' | P j) f j <=
\sum_(i <- ys | x_to_y x' == i) f x' +
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j PX: P x' = true
f x' <= \sum_(i <- ys | x_to_y x' == i) f x'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j PX: P x' = true
f x' <= f x' * count (eq_op (x_to_y x')) ys
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j PX: P x' = true
has (eq_op (x_to_y x')) ys
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j PX: P x' = true
x_to_y x' \in ys
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat P_HOLDS: forall (i : Y) (j : X),
true -> P j && (x_to_y j == i) -> P j IN_ys: forallx : X,
x \in xs' -> P x -> x_to_y x \in ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
\sum_(x <- xs' | P x) f x <=
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i))
f j PX: P x' = true
x' \in x' :: xs'
exact: mem_head.Qed.(** Consider a partition [y']. *)Variabley' : Y.(** We prove that the sum of items excluding all items from a partition [y'] is less-than-or-equal to the sum over all partitions except [y']. *)
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
\sum_(x <- xs | P x && (x_to_y x != y')) f x <=
\sum_(y <- ys | y != y') sum_of_partition y
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
\sum_(x <- xs | P x && (x_to_y x != y')) f x <=
\sum_(y <- ys | y != y') sum_of_partition y
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
\sum_(x <- xs | P x && (x_to_y x != y')) f x <=
\sum_(j <- xs | P j && (x_to_y j != y'))
\sum_(i <- ys | [&& i != y', P j & x_to_y j == i])
f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
forall (i : Y) (j : X),
i != y' ->
P j && (x_to_y j == i) -> P j && (x_to_y j != y')
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
\sum_(x <- xs | P x && (x_to_y x != y')) f x <=
\sum_(j <- xs | P j && (x_to_y j != y'))
\sum_(i <- ys | [&& i != y', P j & x_to_y j == i])
f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
\sum_(i <- xs | [&& i \in xs, P i & x_to_y i != y'])
f i <=
\sum_(i <- xs | [&& i \in xs, P i & x_to_y i != y'])
\sum_(i0 <- ys | [&& i0 != y', P i
& x_to_y i == i0]) f i
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y x': X ARRo: x' \in xs Px': P x' NEQ: x_to_y x' != y'
f x' <=
\sum_(i <- ys | [&& i != y', P x' & x_to_y x' == i])
f x'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y x': X ARRo: x' \in xs Px': P x' NEQ: x_to_y x' != y'
f x' <=
(if
[&& x_to_y x' != y', P x' & x_to_y x' == x_to_y x']
then f x'
else0) +
\sum_(y <- rem (T:=Y) (x_to_y x') ys | [&& y != y',
P x'
& x_to_y x' ==
y]) f x'
byrewrite Px' eq_refl NEQ andTb andTb leq_addr.
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y
forall (i : Y) (j : X),
i != y' ->
P j && (x_to_y j == i) -> P j && (x_to_y j != y')
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y', y_of_x': Y x': X NEQ: ~ y_of_x' == y' EQ1: P x' EQ2: x_to_y x' = y_of_x'
P x' && (x_to_y x' != y')
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y', y_of_x': Y x': X NEQ: ~ y_of_x' == y' EQ1: P x' EQ2: x_to_y x' = y_of_x' CONTR: x_to_y x' == y'
False
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y', y_of_x': Y x': X EQ2: x_to_y x' = y_of_x' CONTR: x_to_y x' == y'
y_of_x' == y'
byrewrite -EQ2.Qed.(** In this section, we prove a stronger result about the equality between the sum over all items and the sum over all partitions of those items. *)SectionEquality.(** In order to prove the stronger result of equality, we additionally assume that the sequences [xs] and [ys] are sets, i.e., that each element is contained at most once. *)HypothesisH_xs_unique : uniq xs.HypothesisH_ys_unique : uniq ys.(** We prove that summation of [f x] over all [x] is equal to the summation of [sum_of_partition] over all partitions. *)
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq xs H_ys_unique: uniq ys
\sum_(x <- xs | P x) f x =
\sum_(y <- ys) sum_of_partition y
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq xs H_ys_unique: uniq ys
\sum_(x <- xs | P x) f x =
\sum_(y <- ys) sum_of_partition y
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y H_no_partition_missing: forallx : X,
x \in xs ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- xs | P x &&
(x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq xs H_ys_unique: uniq ys
\sum_(x <- xs | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs | P x && (x_to_y x == y)) f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
letsum_of_partition :=
funy : Y =>
\sum_(x <- xs' | P x && (x_to_y x == y))
f x in
uniq xs' ->
\sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
\sum_(x <- (x' :: xs') | P x) f x =
\sum_(y <- ys)
\sum_(x <- (x' :: xs') | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
uniq xs' ->
\sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
forallx : X, x \in xs' -> P x -> x_to_y x \in ys
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: uniq xs' ->
\sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
uniq xs'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
\sum_(x <- (x' :: xs') | P x) f x =
\sum_(y <- ys)
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: (forallx : X,
x \in xs' -> P x -> x_to_y x \in ys) ->
uniq xs' ->
\sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: uniq xs' ->
\sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
uniq xs'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
\sum_(x <- (x' :: xs') | P x) f x =
\sum_(y <- ys)
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: uniq xs' ->
\sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
\sum_(x <- (x' :: xs') | P x) f x =
\sum_(y <- ys)
\sum_(x <- (x' :: xs') | P x && (x_to_y x == y))
f x
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
\sum_(x <- (x' :: xs') | P x) f x =
\sum_(j <- (x' :: xs') | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x
(if P x'
then f x' + \sum_(j <- xs' | P j) f j
else \sum_(j <- xs' | P j) f j) =
(if P x'
then
\sum_(i <- ys | P x' && (x_to_y x' == i)) f x' +
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
else
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j)
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
f x' + \sum_(j <- xs' | P j) f j =
\sum_(i <- ys | true && (x_to_y x' == i)) f x' +
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
\sum_(i <- ys | true && (x_to_y x' == i)) f x' = f x'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
f x' + \sum_(j <- xs' | P j) f j =
f x' +
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
\sum_(i <- ys | true && (x_to_y x' == i)) f x' = f x'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
\sum_(i <- [seq x <- ys | x_to_y x' == x]) f x' = f x'
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
[seq i <- ys | x_to_y x' == i] = [:: x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
[seq i <- ys | x_to_y x' == i] =
[seq i <- ys | i == x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
[seq i <- ys | i == x_to_y x'] = [:: x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
[seq i <- ys | x_to_y x' == i] =
[seq i <- ys | i == x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys PX: P x' = true
[seq i <- ys | x_to_y x' == i] =
[seq i <- ys | i == x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') y'': Y ys': seq Y H_ys_unique: uniq (y'' :: ys') PX: P x' = true LE_TAILy: uniq ys' ->
[seq i <- ys' | x_to_y x' == i] =
[seq i <- ys' | i == x_to_y x']
[seq i <- y'' :: ys' | x_to_y x' == i] =
[seq i <- y'' :: ys' | i == x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') y'': Y ys': seq Y H_ys_unique: uniq (y'' :: ys') PX: P x' = true LE_TAILy: [seq i <- ys' | x_to_y x' == i] =
[seq i <- ys' | i == x_to_y x']
[seq i <- y'' :: ys' | x_to_y x' == i] =
[seq i <- y'' :: ys' | i == x_to_y x']
byrewrite //= LE_TAILy //= eq_sym.
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
[seq i <- ys | i == x_to_y x'] = [:: x_to_y x']
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
x_to_y x' \in ys
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
x' \in x' :: xs'
byrewrite in_cons; apply /orP; left.
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
f x' + \sum_(j <- xs' | P j) f j =
f x' +
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
X, Y: eqType x_to_y: X -> Y f: X -> nat P: pred X xs: seq X ys: seq Y x': X xs': seq X H_no_partition_missing: forallx : X,
x \in x' :: xs' ->
P x -> x_to_y x \in ys sum_of_partition:= funy : Y =>
\sum_(x <- (x' :: xs') |
P x && (x_to_y x == y))
f x: Y -> nat y': Y H_xs_unique: uniq (x' :: xs') H_ys_unique: uniq ys LE_TAIL: \sum_(x <- xs' | P x) f x =
\sum_(y <- ys)
\sum_(x <- xs' | P x && (x_to_y x == y))
f x PX: P x' = true
\sum_(j <- xs' | P j) f j =
\sum_(j <- xs' | P j)
\sum_(i <- ys | P j && (x_to_y j == i)) f j
byrewrite LE_TAIL (exchange_big_dep P) //=; move=> ??? /andP[??].Qed.EndEquality.EndSumOverPartitions.(** We observe a trivial monotonicity-preserving property with regard to [leq]. *)SectionMonotonicity.(** Consider any type of indices, any predicate, ... *)Variables (I : eqType) (P : pred I).(** ... and any function that maps each index to a [nat -> nat] function. *)VariableF : I -> nat -> nat.(** Consider any set of indices ... *)Variabler : seq I.(** ... and suppose that [F i] is monotonic with regard to [leq] for every index in [r]. *)HypothesisH_mono : foralli, i \in r -> monotone leq (F i).(** Consider the sum of [F] over [r], for any given [x]. *)Letfx := \sum_(i <- r | P i) F i x.(** We note that this sum [f] is monotonic with regard to [leq] in [x]. *)
I: eqType P: pred I F: I -> nat -> nat r: seq I H_mono: foralli : I, i \in r -> monotone leq (F i) f:= funx : nat => \sum_(i <- r | P i) F i x: nat -> nat
monotone leq f
I: eqType P: pred I F: I -> nat -> nat r: seq I H_mono: foralli : I, i \in r -> monotone leq (F i) f:= funx : nat => \sum_(i <- r | P i) F i x: nat -> nat
monotone leq f
I: eqType P: pred I F: I -> nat -> nat r: seq I H_mono: foralli : I, i \in r -> monotone leq (F i) f:= funx : nat => \sum_(i <- r | P i) F i x: nat -> nat x, y: nat LEQ: x <= y
f x <= f y
I: eqType P: pred I F: I -> nat -> nat r: seq I H_mono: foralli : I, i \in r -> monotone leq (F i) f:= funx : nat => \sum_(i <- r | P i) F i x: nat -> nat x, y: nat LEQ: x <= y
\sum_(i <- r | (i \in r) && P i) F i x <=
\sum_(i <- r | (i \in r) && P i) F i y
I: eqType P: pred I F: I -> nat -> nat r: seq I H_mono: foralli : I, i \in r -> monotone leq (F i) f:= funx : nat => \sum_(i <- r | P i) F i x: nat -> nat x, y: nat LEQ: x <= y i: I IN: i \in r
F i x <= F i y
byapply: H_mono.Qed.EndMonotonicity.(** As a rewriting aid, it is useful to note that summing over "all" elements of [unit : finType] is a no-op. *)