Built with Alectryon, running Coq+SerAPI v8.14.0+0.14.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.
Require Export prosa.util.notation.
Require Export prosa.util.nat.

Notation "[ rel _ _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ : _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ & _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "_ + _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ - _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ >= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ > _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ * _" was already used in scope nat_scope. [notation-overridden,parsing]
Section SumsOverSequences. (** 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. *) Section SumOfOneFunction. (** 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

all (fun x : I => F x == 0) r = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat

all (fun x : I => F x == 0) r = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: all (fun x : I => F x == 0) r = true

true = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: all (fun x : I => F x == 0) r = false
false = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: all (fun x : I => F x == 0) r = true

true = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: {in r, forall x : I, F x == 0}

true = (\sum_(i <- r) F i <= 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: {in r, forall x : I, F x == 0}

forall i : I, (i \in r) && true -> F i = 0
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: {in r, forall x : I, F x == 0}
i: I
IN: i \in r

F i = 0
I: eqType
r: seq I
P: pred I
F: I -> nat
i: I
IN: i \in r
ZERO: true -> F i == 0

F i = 0
by move: ZERO => /implyP ZERO; apply/eqP; apply ZERO.
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: all (fun x : I => F x == 0) r = false

false = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: all (fun x : I => F x == 0) r = false

false = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
ZERO: has (predC (fun x : I => F x == 0)) r

false = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
IN: x \in r
NEQ: predC (fun x : I => F x == 0) x

false = (\sum_(i <- r) F i == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
IN: x \in r
NEQ: predC (fun x : I => F x == 0) x

false = (F x + \sum_(y <- rem (T:=I) x r) F y == 0)
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
IN: x \in r
NEQ: predC (fun x : I => F x == 0) x

0 < F x + \sum_(y <- rem (T:=I) x r) F y
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
IN: x \in r
NEQ: predC (fun x : I => F x == 0) x

0 < F x
by rewrite lt0n. } 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

reflect (exists i : I, i \in r /\ 0 < F i) (0 < \sum_(i <- r) F i)
I: eqType
r: seq I
P: pred I
F: I -> nat

reflect (exists i : I, i \in r /\ 0 < F i) (0 < \sum_(i <- r) F i)
I: eqType
r: seq I
P: pred I
F: I -> nat
LT0: 0 < \sum_(i <- r) F i

exists i : I, i \in r /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
LT0: exists i : I, i \in r /\ 0 < F i
0 < \sum_(i <- r) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
LT0: 0 < \sum_(i <- r) F i

exists i : I, i \in r /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = true

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = false
exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = true

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = false
exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = true

a \in a :: l /\ 0 < F a
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = false
exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = false

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: (0 < F a) = false

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
LT0: 0 < \sum_(i <- (a :: l)) F i
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: F a = 0

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: F a = 0
LT0: 0 < \sum_(j <- l) F j

exists i : I, i \in a :: l /\ 0 < F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
IHl: 0 < \sum_(i <- l) F i -> exists i : I, i \in l /\ 0 < F i
POS: F a = 0
LT0: 0 < \sum_(j <- l) F j
i: I
IN: i \in l
POSi: 0 < F i

exists i : I, i \in a :: l /\ 0 < F i
by exists i; split => //; rewrite in_cons; apply /orP; right.
I: eqType
r: seq I
P: pred I
F: I -> nat
LT0: exists i : I, i \in r /\ 0 < F i

0 < \sum_(i <- r) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
LT0: exists i : I, i \in r /\ 0 < F i

0 < \sum_(i <- r) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
i: I
IN: i \in r
POS: 0 < F i

0 < \sum_(i <- r) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
i: I
IN: i \in r
POS: 0 < F i

0 < F i + \sum_(y <- rem (T:=I) i r) F y
by apply leq_trans with (F i); last by rewrite leq_addr. } 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

forall 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

forall 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
NOTIN: 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, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x

\sum_(x <- (a0 :: l) | P x && (x != a)) F x = \sum_(x <- (a0 :: l) | P x) F x
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x

(if P a0 && (a0 != a) then F a0 + \sum_(x <- l | P x) F x else \sum_(x <- l | P x) F x) = (if P a0 then F a0 + \sum_(j <- l | P j) F j else \sum_(j <- l | P j) F j)
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x
a \notin l
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x

(if P a0 && (a0 != a) then F a0 + \sum_(x <- l | P x) F x else \sum_(x <- l | P x) F x) = (if P a0 then F a0 + \sum_(j <- l | P j) F j else \sum_(j <- l | P j) F j)
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x
NOTIN: {in a0 :: l, forall y : I, y != a}

(if P a0 && (a0 != a) then F a0 + \sum_(x <- l | P x) F x else \sum_(x <- l | P x) F x) = (if P a0 then F a0 + \sum_(j <- l | P j) F j else \sum_(j <- l | P j) F j)
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x
NOTIN: {in a0 :: l, forall y : I, y != a}
NEQ: a0 \in a0 :: l -> a0 != a

(if P a0 && (a0 != a) then F a0 + \sum_(x <- l | P x) F x else \sum_(x <- l | P x) F x) = (if P a0 then F a0 + \sum_(j <- l | P j) F j else \sum_(j <- l | P j) F j)
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x
NOTIN: {in a0 :: l, forall y : I, y != a}
NEQ: a0 != a

(if P a0 && (a0 != a) then F a0 + \sum_(x <- l | P x) F x else \sum_(x <- l | P x) F x) = (if P a0 then F a0 + \sum_(j <- l | P j) F j else \sum_(j <- l | P j) F j)
by rewrite NEQ Bool.andb_true_r.
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x

a \notin l
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x

a \notin l
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
NOTIN: a \notin a0 :: l
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x
y: I
IN: y \in l

y != a
I: eqType
r: seq I
P: pred I
F: I -> nat
a, a0: I
l: seq I
IHl: a \notin l -> \sum_(x <- l | P x && (x != a)) F x = \sum_(x <- l | P x) F x
y: I
IN: y \in l
NOTIN: {in a0 :: l, forall y : I, y != a}

y != a
by apply NOTIN; rewrite in_cons; apply/orP; right. } 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

forall c : nat, (forall a : 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

forall c : nat, (forall a : 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
H: forall a : 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
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]

\sum_(j <- (a :: l) | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]

forall a : I, a \in l -> P a -> F a <= c
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
\sum_(j <- (a :: l) | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]

forall a : I, a \in l -> P a -> F a <= c
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
a0: I
H0: a0 \in l
H1: P a0

a0 \in a :: l
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
a0: I
H0: a0 \in l
H1: P a0
P a0
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
a0: I
H0: a0 \in l
H1: P a0

a0 \in a :: l
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
a0: I
H0: a0 \in l
H1: P a0
P a0
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
a0: I
H0: a0 \in l
H1: P a0

P a0
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: (forall a : I, a \in l -> P a -> F a <= c) -> \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
a0: I
H0: a0 \in l
H1: P a0

P a0
by done.
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]

\sum_(j <- (a :: l) | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]

(if P a then F a + \sum_(j <- l | P j) F j else \sum_(j <- l | P j) F j) <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = true

F a + \sum_(j <- l | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = false
\sum_(j <- l | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = true

F a + \sum_(j <- l | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = true

F a + \sum_(j <- l | P j) F j <= c * size [seq j <- [:: a] | P j] + c * size [seq j <- l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = true

F a <= c * size [seq j <- [:: a] | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = true

F a <= c
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = true

a \in a :: l
by rewrite in_cons; apply/orP; left.
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = false

\sum_(j <- l | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = false

\sum_(j <- l | P j) F j <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = false

c * size [seq j <- l | P j] <= c * size [seq j <- a :: l | P j]
I: eqType
r: seq I
P: pred I
F: I -> nat
c: nat
a: I
l: seq I
H: forall a0 : I, a0 \in a :: l -> P a0 -> F a0 <= c
IHl: \sum_(j <- l | P j) F j <= c * size [seq j <- l | P j]
EQ: P a = false

size [seq j <- l | P j] <= size [seq j <- a :: l | P j]
by rewrite -cat1s filter_cat size_cat leq_addl. } 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
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
IHl: \sum_(r <- l | P r) F r = \sum_(r <- l) F r - \sum_(r <- l | ~~ P r) F r

\sum_(r <- (a :: l) | P r) F r = \sum_(r <- (a :: l)) F r - \sum_(r <- (a :: l) | ~~ P r) F r
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I

(if P a then F a + (\sum_(r <- l) F r - \sum_(r <- l | ~~ P r) F r) else \sum_(r <- l) F r - \sum_(r <- l | ~~ P r) F r) = F a + \sum_(j <- l) F j - (if ~~ P a then F a + \sum_(j <- l | ~~ P j) F j else \sum_(j <- l | ~~ P j) F j)
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I

F a + (\sum_(r <- l) F r - \sum_(r <- l | ~~ P r) F r) = F a + \sum_(j <- l) F j - \sum_(j <- l | ~~ P j) F j
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I

\sum_(r <- l | ~~ P r) F r <= \sum_(r <- l) F r
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I

forall i : I, true -> (if ~~ P i then F i else 0) <= F i
I: eqType
r: seq I
P: pred I
F: I -> nat
a: I
l: seq I
t: I

(if ~~ P t then F t else 0) <= F t
by case (P t). Qed. (** Summing natural numbers over a superset can only yields a greater sum. 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
P: pred I
F: I -> nat

forall rs : seq I, uniq r -> {subset r <= rs} -> \sum_(i <- r) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat

forall rs : seq I, uniq r -> {subset r <= rs} -> \sum_(i <- r) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
UNIQ: uniq r

forall rs : seq I, {subset r <= rs} -> \sum_(i <- r) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
UNIQ: uniq (x :: r1')
IH: uniq r1' -> forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i

forall rs : seq I, {subset x :: r1' <= rs} -> \sum_(i <- (x :: r1')) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
UNIQ: uniq (x :: r1')
IH: uniq r1' -> forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
rs: seq I
SUB: {subset x :: r1' <= rs}

\sum_(i <- (x :: r1')) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
UNIQ: uniq (x :: r1')
IH: uniq r1' -> forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
rs: seq I
SUB: {subset x :: r1' <= rs}
IN: x \in rs

\sum_(i <- (x :: r1')) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
rs: seq I
SUB: {subset x :: r1' <= rs}
IN: x \in rs
NOTIN: x \notin r1'
UNIQ: uniq r1'

\sum_(i <- (x :: r1')) F i <= \sum_(i <- rs) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
SUB: {subset x :: r1' <= p1 ++ x :: p2}
IN: x \in p1 ++ x :: p2
NOTIN: x \notin r1'
UNIQ: uniq r1'

\sum_(i <- (x :: r1')) F i <= \sum_(i <- (p1 ++ x :: p2)) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
SUB: {subset x :: r1' <= p1 ++ x :: p2}
IN: x \in p1 ++ x :: p2
NOTIN: x \notin r1'
UNIQ: uniq r1'

\sum_(j <- r1') F j <= \sum_(i <- p1) F i + \sum_(j <- p2) F j
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
SUB: {subset x :: r1' <= p1 ++ x :: p2}
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]

\sum_(j <- r1') F j <= \sum_(i <- p1) F i + \sum_(j <- p2) F j
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
SUB: {subset x :: r1' <= p1 ++ x :: p2}
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]

\sum_(j <- r1') F j <= \sum_(i <- (p1 ++ p2)) F i
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
SUB: {subset x :: r1' <= p1 ++ x :: p2}
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]
x0: I
IN0: x0 \in r1'

x0 \in p1 ++ p2
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
SUB: {subset x :: r1' <= p1 ++ x :: p2}
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]
x0: I
IN0: x0 \in r1'

(x0 \in p1) || (x0 \in p2)
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
x0: I
SUB: x0 \in p1 ++ x :: p2
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]
IN0: x0 \in r1'

(x0 \in p1) || (x0 \in p2)
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
x0: I
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]
IN0: x0 \in r1'
SUB: [|| x0 \in p1, x0 == x | x0 \in p2]

(x0 \in p1) || (x0 \in p2)
I: eqType
r: seq I
P: pred I
F: I -> nat
x: I
r1': seq I
IH: forall rs : seq I, {subset r1' <= rs} -> \sum_(i <- r1') F i <= \sum_(i <- rs) F i
p1, p2: seq I
x0: I
NOTIN: x \notin r1'
UNIQ: uniq r1'
IN: [|| x \in p1, true | x \in p2]
IN0: x0 \in r1'
EQx: x0 = x

(x0 \in p1) || (x0 \in p2)
by rewrite -EQx IN0 in NOTIN. Qed. End SumOfOneFunction. (** In this section, we show some properties of the sum performed over two different functions. *) Section SumOfTwoFunctions. (** Consider three functions that yield natural numbers. *) Variable (E E1 E2 : I -> nat). (** Besides earlier introduced predicate [P], we add two additional predicates [P1] and [P2]. *) Variable (P1 P2 : 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

(forall i : 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

(forall i : 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: forall i : 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: forall i : 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
by apply leq_sum; move => j /andP [IN H]; apply 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

(forall i : 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

(forall i : 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
EQ: forall i : 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
EQ: forall i : 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
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
EQ: forall i : 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
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
EQ: forall i : I, i \in r -> P i -> E1 i == E2 i
\sum_(i <- r | (i \in r) && P i) E2 i <= \sum_(i <- r | (i \in r) && P i) E1 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
EQ: forall i : I, i \in r -> P i -> E1 i == E2 i
j: I
IN: j \in r
H: P j

E1 j <= E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
EQ: forall i : I, i \in r -> P i -> E1 i == E2 i
j: I
IN: j \in r
H: P j
E2 j <= E1 j
all: by move:(EQ j IN H) => LEQ; ssrlia. 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

(forall i : 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

(forall i : 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
LE: forall i : 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
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i

\sum_(i <- (a :: l) | P1 i) E i <= \sum_(i <- (a :: l) | P2 i) E i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i

(if P1 a then E a + \sum_(j <- l | P1 j) E j else \sum_(j <- l | P1 j) E j) <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a

E a + \sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
\sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a

E a + \sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
\sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a

E a + \sum_(j <- l | P1 j) E j <= E a + \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
\sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a

\sum_(j <- l | P1 j) E j <= \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
\sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false

\sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false

\sum_(j <- l | P1 j) E j <= (if P2 a then E a + \sum_(j <- l | P2 j) E j else \sum_(j <- l | P2 j) E j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
P2a: P2 a = true

\sum_(j <- l | P1 j) E j <= E a + \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
P2a: P2 a = false
\sum_(j <- l | P1 j) E j <= \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
P2a: P2 a = true

\sum_(j <- l | P1 j) E j <= E a + \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
P2a: P2 a = false
\sum_(j <- l | P1 j) E j <= \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
P2a: P2 a = false

\sum_(j <- l | P1 j) E j <= \sum_(j <- l | P2 j) E j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LE: forall i : I, i \in a :: l -> P1 i -> P2 i
IHl: (forall i : I, i \in l -> P1 i -> P2 i) -> \sum_(i <- l | P1 i) E i <= \sum_(i <- l | P2 i) E i
P1a: P1 a = false
P2a: P2 a = false

\sum_(j <- l | P1 j) E j <= \sum_(j <- l | P2 j) E j
by apply IHl; intros; apply LE => //; rewrite in_cons; apply/orP; right. Qed. (** Next, we prove that if for any element x of a set [xs] the following two statements hold (1) [F1 x] is less than or equal to [F2 x] and (2) the sum [F1 x_1, ..., F1 x_n] is equal to the sum of [F2 x_1, ..., F2 x_n], then [F1 x] is equal to [F2 x] for any element x of [xs]. *)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I

forall xs : seq_predType I, (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> forall x : I, x \in xs -> P x -> E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I

forall xs : seq_predType I, (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> forall x : I, x \in xs -> P x -> E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq_predType I
H1: forall x : I, x \in xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x
x: I
IN: x \in xs
PX: P x

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x

\sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x

\sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x

forall i : I, (i \in xs) && P i -> E1 i <= E2 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
y: I
INy: y \in xs
PY: P y

E1 y <= E2 y
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
y: I
INy: y \in xs
PY: P y

y \in a :: xs
by rewrite in_cons; apply/orP; right.
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j

forall x : I, x \in xs -> P x -> E1 x <= E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j

forall x : I, x \in xs -> P x -> E1 x <= E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
x': I
IN': x' \in xs
PX': P x'

E1 x' <= E2 x'
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: (forall x : I, x \in xs -> P x -> E1 x <= E2 x) -> \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
x': I
IN': x' \in xs
PX': P x'

x' \in a :: xs
by rewrite in_cons; apply/orP; right.
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
H2: \sum_(x <- (a :: xs) | P x) E1 x = \sum_(x <- (a :: xs) | P x) E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
IN: x \in a :: xs
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
EQ: x = a

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs
E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
EQ: x = a

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: forall x0 : I, x0 \in x :: xs -> P x0 -> E1 x0 <= E2 x0
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P x then E1 x + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P x then E2 x + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: forall x0 : I, x0 \in x :: xs -> P x0 -> E1 x0 <= E2 x0
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: x \in x :: xs -> P x -> E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j
Q: \sum_(j <- xs | P j) E2 j <= \sum_(j <- xs | P j) E1 j

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j
Q: \sum_(j <- xs | P j) E2 j <= \sum_(j <- xs | P j) E1 j

\sum_(j <- xs | P j) E1 j = \sum_(j <- xs | P j) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j
Q: \sum_(j <- xs | P j) E2 j <= \sum_(j <- xs | P j) E1 j
EQ: \sum_(j <- xs | P j) E1 j = \sum_(j <- xs | P j) E2 j
E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j
Q: \sum_(j <- xs | P j) E2 j <= \sum_(j <- xs | P j) E1 j

\sum_(j <- xs | P j) E1 j = \sum_(j <- xs | P j) E2 j
by apply /eqP; rewrite eqn_leq; apply/andP; split.
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
xs: seq I
x: I
H1: E1 x <= E2 x
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
H2: E1 x + \sum_(j <- xs | P j) E1 j = E2 x + \sum_(j <- xs | P j) E2 j
Q: \sum_(j <- xs | P j) E2 j <= \sum_(j <- xs | P j) E1 j
EQ: \sum_(j <- xs | P j) E1 j = \sum_(j <- xs | P j) E2 j

E1 x = E2 x
by move: H2 => /eqP; rewrite EQ eqn_add2r; move => /eqP EQ'.
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
H2: (if P a then E1 a + \sum_(j <- xs | P j) E1 j else \sum_(j <- xs | P j) E1 j) = (if P a then E2 a + \sum_(j <- xs | P j) E2 j else \sum_(j <- xs | P j) E2 j)
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
IHxs: \sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x -> x \in xs -> E1 x = E2 x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
PA: P a = true
H2: E1 a + \sum_(j <- xs | P j) E1 j = E2 a + \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs

E1 x = E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: forall x : I, x \in a :: xs -> P x -> E1 x <= E2 x
x: I
PX: P x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
PA: P a = true
H2: E1 a + \sum_(j <- xs | P j) E1 j = E2 a + \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs

\sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: a \in a :: xs -> P a -> E1 a <= E2 a
x: I
PX: P x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
PA: P a = true
H2: E1 a + \sum_(j <- xs | P j) E1 j = E2 a + \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs

\sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: E1 a <= E2 a
x: I
PX: P x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
PA: P a = true
H2: E1 a + \sum_(j <- xs | P j) E1 j = E2 a + \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs

\sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
xs: seq I
H1: E1 a <= E2 a
x: I
PX: P x
Fact: \sum_(j <- xs | P j) E1 j <= \sum_(j <- xs | P j) E2 j
PA: P a = true
H2: E1 a + \sum_(j <- xs | P j) E1 j = E2 a + \sum_(j <- xs | P j) E2 j
EqLeq: forall a b c d : nat, a + b = c + d -> a <= c -> d <= b
IN: x \in xs
Q: \sum_(j <- xs | P j) E2 j <= \sum_(j <- xs | P j) E1 j

\sum_(x <- xs | P x) E1 x = \sum_(x <- xs | P x) E2 x
by apply/eqP; rewrite eqn_leq; apply/andP; split. } Qed. (** Next, we prove that the summing over the difference of [E1] and [E2] is the same as the difference of the two sums performed separately. Since we are using natural numbers, we have to require that [E2] dominates [E1] over the summing points given by [r]. *)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I

(forall i : I, i \in r -> E1 i <= E2 i) -> \sum_(i <- r) (E2 i - E1 i) = \sum_(i <- r) E2 i - \sum_(i <- r) E1 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I

(forall i : I, i \in r -> E1 i <= E2 i) -> \sum_(i <- r) (E2 i - E1 i) = \sum_(i <- r) E2 i - \sum_(i <- r) E1 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
LEQ: forall i : I, i \in r -> E1 i <= E2 i

\sum_(i <- r) (E2 i - E1 i) = \sum_(i <- r) E2 i - \sum_(i <- r) E1 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

\sum_(i <- (a :: l)) (E2 i - E1 i) = \sum_(i <- (a :: l)) E2 i - \sum_(i <- (a :: l)) E1 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

E2 a - E1 a + \sum_(j <- l) (E2 j - E1 j) = E2 a - E1 a + (\sum_(j <- l) E2 j - \sum_(j <- l) E1 j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
E1 a <= E2 a
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

E2 a - E1 a + \sum_(j <- l) (E2 j - E1 j) = E2 a - E1 a + (\sum_(j <- l) E2 j - \sum_(j <- l) E1 j)
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
E1 a <= E2 a
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

forall i : I, i \in l -> E1 i <= E2 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
E1 a <= E2 a
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

E1 a <= E2 a
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

E1 a <= E2 a
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

\sum_(j <- l) E1 j <= \sum_(j <- l) E2 j
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i

\sum_(i <- l | (i \in l) && true) E1 i <= \sum_(i <- l | (i \in l) && true) E2 i
I: eqType
r: seq I
P: pred I
E, E1, E2: I -> nat
P1, P2: pred I
a: I
l: seq I
LEQ: forall i : I, i \in a :: l -> E1 i <= E2 i
IHl: (forall i : I, i \in l -> E1 i <= E2 i) -> \sum_(i <- l) (E2 i - E1 i) = \sum_(i <- l) E2 i - \sum_(i <- l) E1 i
i: I
IN: i \in l

E1 i <= E2 i
by apply LEQ; rewrite in_cons; apply/orP; right. Qed. End SumOfTwoFunctions. End SumsOverSequences. (** In this section, we prove a variety of properties of sums performed over ranges. *) Section SumsOverRanges. (** First, we show a trivial identity: any sum of zeros is zero. *)
m, n: nat

\sum_(m <= i < n) 0 = 0
m, n: nat

\sum_(m <= i < n) 0 = 0
by rewrite big_const_nat iter_addn mul0n addn0 //. Qed. (** In a similar way, we prove that the sum of Δ ones is equal to Δ. *)

forall t Δ : nat, \sum_(t <= x < t + Δ) 1 = Δ

forall t Δ : nat, \sum_(t <= x < t + Δ) 1 = Δ
t, Δ: nat

\sum_(t <= x < t + Δ) 1 = Δ
t, Δ: nat

1 * (t + Δ - t) = Δ
by ssrlia. 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 <-> (forall i : nat, m <= i < n -> F i = 0)
m, n: nat
F: nat -> nat

\sum_(m <= i < n) F i = 0 <-> (forall i : nat, m <= i < n -> F i = 0)
m, n: nat
F: nat -> nat

\sum_(m <= i < n) F i = 0 -> forall i : nat, m <= i < n -> F i = 0
m, n: nat
F: nat -> nat
(forall i : 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 -> forall i : nat, m <= i < n -> F i = 0
m, n: nat
F: nat -> nat
(forall i : nat, m <= i < n -> F i = 0) -> \sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat

\sum_(i <- iota m (n - m)) F i == 0 -> forall i : nat, m <= i < n -> F i = 0
m, n: nat
F: nat -> nat
(forall i : nat, m <= i < n -> F i = 0) -> \sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat
ZERO: {in iota m (n - m), forall x : nat_eqType, F x == 0}
i: nat

m <= i < n -> F i = 0
m, n: nat
F: nat -> nat
(forall i : nat, m <= i < n -> F i = 0) -> \sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat
ZERO: {in iota m (n - m), forall x : nat_eqType, F x == 0}
i: nat
IN: i \in iota m (n - m)

F i = 0
m, n: nat
F: nat -> nat
(forall i : nat, m <= i < n -> F i = 0) -> \sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat

(forall i : nat, m <= i < n -> F i = 0) -> \sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat

(forall i : nat, m <= i < n -> F i = 0) -> \sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat
ZERO: forall i : nat, m <= i < n -> F i = 0

\sum_(m <= i < n) F i = 0
m, n: nat
F: nat -> nat
ZERO: forall i : nat, m <= i < n -> F i = 0

\sum_(m <= i < n) 0 = 0
by apply sum0. 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 < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0

forall (f : nat -> nat) (t Δ : nat), \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1

exists x : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
EQ: f (t + Δ) = 0

exists x : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
n: nat
EQ: f (t + Δ) = n.+1
exists x : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
EQ: f (t + Δ) = 0

exists x : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
EQ: f (t + Δ) = 0

t <= t + Δ < t + Δ.+1
by apply/andP; split; [rewrite leq_addr | rewrite addnS ltnS].
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
n: nat
EQ: f (t + Δ) = n.+1

exists x : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
H: \sum_(t <= x < t + Δ.+1) f x < Δ.+1
n: nat
EQ: f (t + Δ) = n.+1

exists x : nat, t <= x < t + Δ.+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
n: nat
EQ: f (t + Δ) = n.+1
H: \sum_(t <= i < t + Δ) f i + n < Δ

exists x : nat, t <= x < (t + Δ).+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
n: nat
EQ: f (t + Δ) = n.+1
H: \sum_(t <= i < t + Δ) f i + n < Δ

\sum_(t <= x < t + Δ) f x < Δ
f: nat -> nat
t, Δ: nat
IHΔ: exists x : nat, t <= x < t + Δ /\ f x = 0
n: nat
EQ: f (t + Δ) = n.+1
H: \sum_(t <= i < t + Δ) f i + n < Δ
exists x : nat, t <= x < (t + Δ).+1 /\ f x = 0
f: nat -> nat
t, Δ: nat
IHΔ: \sum_(t <= x < t + Δ) f x < Δ -> exists x : nat, t <= x < t + Δ /\ f x = 0
n: nat
EQ: f (t + Δ) = n.+1
H: \sum_(t <= i < t + Δ) f i + n < Δ

\sum_(t <= x < t + Δ) f x < Δ
by apply leq_ltn_trans with (\sum_(t <= i < t + Δ) f i + n); first rewrite leq_addr.
f: nat -> nat
t, Δ: nat
IHΔ: exists x : nat, t <= x < t + Δ /\ f x = 0
n: nat
EQ: f (t + Δ) = n.+1
H: \sum_(t <= i < t + Δ) f i + n < Δ

exists x : nat, t <= x < (t + Δ).+1 /\ f x = 0
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

exists x : nat, t <= x < (t + Δ).+1 /\ f x = 0
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

t <= z < (t + Δ).+1
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

z < (t + Δ).+1
by rewrite 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. *)

forall (n : nat) (F G : nat -> nat), (forall i : nat, i < n -> G i <= F i) -> \sum_(0 <= i < n) (F i - G i) = \sum_(0 <= i < n) F i - \sum_(0 <= i < n) G i

forall (n : nat) (F G : nat -> nat), (forall i : nat, i < n -> G i <= F i) -> \sum_(0 <= i < n) (F i - G i) = \sum_(0 <= i < n) F i - \sum_(0 <= i < n) G i
n: nat
F, G: nat -> nat
ALL: forall i : nat, i < n -> G i <= F i

\sum_(0 <= i < n) (F i - G i) = \sum_(0 <= i < n) F i - \sum_(0 <= i < n) G i
n: nat
F, G: nat -> nat
ALL: forall i : nat, i < n -> G i <= F i

forall i : nat_eqType, i \in index_iota 0 n -> G i <= F i
n: nat
F, G: nat -> nat
ALL: forall i : nat, i < n -> G i <= F i
i: nat_eqType
LT: i < n

G i <= F i
by apply ALL. Qed. (** Given a sequence [r], function [F], and a predicate [P], we prove that the fact that the sum of [F] conditioned by [P] is greater than [0] is equivalent to the fact that there exists an element [i \in r] such that [F i > 0] and [P i] holds. *)

forall (T : eqType) (r : seq T) (P : T -> bool) (F : T -> nat), reflect (exists i : T, i \in r /\ P i /\ 0 < F i) (0 < \sum_(i <- r | P i) F i)

forall (T : eqType) (r : seq T) (P : T -> bool) (F : T -> nat), reflect (exists i : T, i \in r /\ P i /\ 0 < F i) (0 < \sum_(i <- r | P i) F i)
T: eqType
r: seq T
P: T -> bool
F: T -> nat
H: 0 < \sum_(i <- r | P i) F i

exists i : T, i \in r /\ P i /\ 0 < F i
T: eqType
r: seq T
P: T -> bool
F: T -> nat
H: exists i : T, i \in r /\ P i /\ 0 < F i
0 < \sum_(i <- r | P i) F i
T: eqType
r: seq T
P: T -> bool
F: T -> nat
H: 0 < \sum_(i <- r | P i) F i

exists i : T, i \in r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
H: 0 < \sum_(i <- (a :: r) | P i) F i
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
H: 0 < (if P a then F a + \sum_(j <- r | P j) F j else \sum_(j <- r | P j) F j)

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
H: 0 < F a + \sum_(j <- r | P j) F j
POS: (0 < F a) = true

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
H: 0 < F a + \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
H: 0 < F a + \sum_(j <- r | P j) F j
POS: (0 < F a) = true

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
H: 0 < F a + \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
H: 0 < F a + \sum_(j <- r | P j) F j
POS: (0 < F a) = false

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
H: 0 < F a + \sum_(j <- r | P j) F j
POS: (0 < F a) = false

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
Z: F a = 0
H: 0 < \sum_(j <- r | P j) F j

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = true
Z: F a = 0
i: T
IN: i \in r
Pi: P i
POS: 0 < F i

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = true

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
i: T
IN: i \in r
Pi: P i
POS: 0 < F i

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false
exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
H: 0 < \sum_(j <- r | P j) F j
POS: (0 < F a) = false

exists i : T, i \in a :: r /\ P i /\ 0 < F i
T: eqType
a: T
r: seq T
P: T -> bool
F: T -> nat
IHr: 0 < \sum_(i <- r | P i) F i -> exists i : T, i \in r /\ P i /\ 0 < F i
PA: P a = false
i: T
IN: i \in r
Pi: P i
POS: 0 < F i

exists i : T, i \in a :: r /\ P i /\ 0 < F i
by (exists i; repeat split; [rewrite in_cons;apply/orP;right | | ]).
T: eqType
r: seq T
P: T -> bool
F: T -> nat
H: exists i : T, i \in r /\ P i /\ 0 < F i

0 < \sum_(i <- r | P i) F i
T: eqType
r: seq T
P: T -> bool
F: T -> nat
H: exists i : T, i \in r /\ P i /\ 0 < F i

0 < \sum_(i <- r | P i) F i
T: eqType
r: seq T
P: T -> bool
F: T -> nat
i: T
IN: i \in r
Pi: P i
POS: 0 < F i

0 < \sum_(i <- r | P i) F i
T: eqType
r: seq T
P: T -> bool
F: T -> nat
i: T
IN: i \in r
Pi: P i
POS: 0 < F i

0 < F i + \sum_(y <- rem (T:=T) i r | P y) F y
by apply leq_trans with (F i); last rewrite leq_addr. } Qed. End SumsOverRanges. (** 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. *) Section SumOfTwoIntervals. (** Consider two equally-sized intervals <<[t1, t1+d)>> and <<[t2, t2+d)>>... *) Variable (t1 t2 : nat). Variable (d : nat). (** ...and two functions [F1] and [F2]. *) Variable (F1 F2 : nat -> nat). (** Assume that the two functions match point-wise with each other, with the points taken in their respective interval. *) Hypothesis equal_before_d: forall g, 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: forall g : 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: forall g : 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
n: nat
equal_before_d: forall g : nat, g < n.+1 -> F1 (t1 + g) = F2 (t2 + g)
IHn: (forall g : nat, g < n -> F1 (t1 + g) = F2 (t2 + g)) -> \sum_(t1 <= t < t1 + n) F1 t = \sum_(t2 <= t < t2 + n) F2 t

\sum_(t1 <= t < t1 + n.+1) F1 t = \sum_(t2 <= t < t2 + n.+1) F2 t
t1, t2, d: nat
F1, F2: nat -> nat
n: nat
equal_before_d: forall g : nat, g < n.+1 -> F1 (t1 + g) = F2 (t2 + g)
IHn: (forall g : nat, g < n -> F1 (t1 + g) = F2 (t2 + g)) -> \sum_(t1 <= t < t1 + n) F1 t = \sum_(t2 <= t < t2 + n) F2 t

addn_monoid (\big[addn_monoid/0]_(t1 <= i < t1 + n) F1 i) (F1 (t1 + n)) = addn_monoid (\big[addn_monoid/0]_(t2 <= i < t2 + n) F2 i) (F2 (t2 + n))
t1, t2, d: nat
F1, F2: nat -> nat
n: nat
equal_before_d: forall g : nat, g < n.+1 -> F1 (t1 + g) = F2 (t2 + g)
IHn: (forall g : nat, g < n -> F1 (t1 + g) = F2 (t2 + g)) -> \sum_(t1 <= t < t1 + n) F1 t = \sum_(t2 <= t < t2 + n) F2 t

\sum_(t2 <= t < t2 + n) F2 t + F1 (t1 + n) = \sum_(t2 <= i < t2 + n) F2 i + F2 (t2 + n)
by rewrite equal_before_d. Qed. End SumOfTwoIntervals. (** In this section, we relate the sum of items with the sum over partitions of those items. *) Section SumOverPartitions. (** Consider an item type [X] and a partition type [Y]. *) Variable X Y : eqType. (** [x_to_y] is the mapping from an item to the partition it is contained in. *) Variable x_to_y : X -> Y. (** Consider [f], a function from [X] to [nat]. *) Variable f : X -> nat. (** Consider an arbitrary predicate [P] on [X]. *) Variable P : pred X. (** Consider a sequence of items [xs] and a sequence of partitions [ys]. *) Variable xs : seq X. Variable ys : seq Y. (** We assume that any item in [xs] has its corresponding partition in the sequence of partitions [ys]. *) Hypothesis H_no_partition_missing : forall x, x \in xs -> x_to_y x \in ys. (** Consider the sum of [f x] over all [x] in a given partition [y]. *) Let sum_of_partition y := \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: forall x : X, x \in xs -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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

forall x : X, x \in xs' -> 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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: forall x : X, x \in xs' -> 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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

forall x : X, x \in xs' -> x_to_y x \in ys
by move=> ??; apply H_no_partition_missing => //; rewrite in_cons; apply /orP; right.
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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: forall x : X, x \in xs' -> 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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

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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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

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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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

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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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

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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : 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: forall x : X, x \in xs' -> x_to_y x \in ys
LE_TAIL: (forall x : X, x \in xs' -> 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

x_to_y x' \in ys
by apply H_no_partition_missing, mem_head. 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. *) Section Equality. (** 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. *) Hypothesis H_xs_unique : uniq xs. Hypothesis H_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: forall x : X, x \in xs -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- xs | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in xs -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- xs | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in xs -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- xs | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
H_xs_unique: uniq (x' :: xs')
H_ys_unique: uniq ys
LE_TAIL: (forall x : X, x \in xs' -> x_to_y x \in ys) -> let sum_of_partition := fun y : 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
H_xs_unique: uniq (x' :: xs')
H_ys_unique: uniq ys
LE_TAIL: (forall x : X, x \in xs' -> 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

forall x : X, x \in xs' -> 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
H_xs_unique: uniq (x' :: xs')
H_ys_unique: uniq ys
LE_TAIL: (forall x : X, x \in xs' -> 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

forall x : X, x \in xs' -> x_to_y x \in ys
by move => ??; apply H_no_partition_missing; rewrite in_cons; apply /orP; right.
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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'
by move: H_xs_unique; rewrite cons_uniq => /andP [??].
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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_(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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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
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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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_(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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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_(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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

[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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

[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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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
[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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

[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:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
H_xs_unique: uniq (x' :: xs')
H_ys_unique: uniq ys

[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:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
H_xs_unique: uniq (x' :: xs')
y': Y
ys': seq Y
H_ys_unique: uniq (y' :: ys')
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:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
H_xs_unique: uniq (x' :: xs')
y': Y
ys': seq Y
H_ys_unique: uniq (y' :: ys')
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']
by rewrite //= 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

[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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

x_to_y x' \in ys
by apply H_no_partition_missing; rewrite 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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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

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: forall x : X, x \in x' :: xs' -> x_to_y x \in ys
sum_of_partition:= fun y : Y => \sum_(x <- (x' :: xs') | P x && (x_to_y x == y)) f x: Y -> nat
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_(j <- xs' | P j) f j = \sum_(j <- xs' | P j) \sum_(i <- ys | P j && (x_to_y j == i)) f j
by rewrite LE_TAIL (exchange_big_dep P) //=; move=> ??? /andP[??]. Qed. End Equality. End SumOverPartitions.