2015-05-16 12:26:59 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
Author: Jeremy Avigad
|
|
|
|
|
|
|
|
|
|
Finite products and sums on the natural numbers.
|
|
|
|
|
-/
|
2015-08-08 20:50:22 +00:00
|
|
|
|
import data.nat.basic data.nat.order algebra.group_bigops algebra.group_set_bigops
|
|
|
|
|
open list
|
2015-05-16 12:26:59 +00:00
|
|
|
|
|
|
|
|
|
namespace nat
|
2015-05-17 05:24:37 +00:00
|
|
|
|
open [classes] algebra
|
|
|
|
|
local attribute nat.comm_semiring [instance]
|
|
|
|
|
variables {A : Type} [deceqA : decidable_eq A]
|
|
|
|
|
|
|
|
|
|
/- Prodl -/
|
|
|
|
|
|
|
|
|
|
definition Prodl (l : list A) (f : A → nat) : nat := algebra.Prodl l f
|
|
|
|
|
notation `∏` binders `←` l, r:(scoped f, Prodl l f) := r
|
|
|
|
|
|
|
|
|
|
theorem Prodl_nil (f : A → nat) : Prodl [] f = 1 := algebra.Prodl_nil f
|
|
|
|
|
theorem Prodl_cons (f : A → nat) (a : A) (l : list A) : Prodl (a::l) f = f a * Prodl l f :=
|
|
|
|
|
algebra.Prodl_cons f a l
|
|
|
|
|
theorem Prodl_append (l₁ l₂ : list A) (f : A → nat) : Prodl (l₁++l₂) f = Prodl l₁ f * Prodl l₂ f :=
|
|
|
|
|
algebra.Prodl_append l₁ l₂ f
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Prodl_mul (l : list A) (f g : A → nat) :
|
|
|
|
|
Prodl l (λx, f x * g x) = Prodl l f * Prodl l g := algebra.Prodl_mul l f g
|
2015-05-17 05:24:37 +00:00
|
|
|
|
section deceqA
|
|
|
|
|
include deceqA
|
|
|
|
|
theorem Prodl_insert_of_mem (f : A → nat) {a : A} {l : list A} (H : a ∈ l) :
|
|
|
|
|
Prodl (insert a l) f = Prodl l f := algebra.Prodl_insert_of_mem f H
|
|
|
|
|
theorem Prodl_insert_of_not_mem (f : A → nat) {a : A} {l : list A} (H : a ∉ l) :
|
|
|
|
|
Prodl (insert a l) f = f a * Prodl l f := algebra.Prodl_insert_of_not_mem f H
|
|
|
|
|
theorem Prodl_union {l₁ l₂ : list A} (f : A → nat) (d : disjoint l₁ l₂) :
|
|
|
|
|
Prodl (union l₁ l₂) f = Prodl l₁ f * Prodl l₂ f := algebra.Prodl_union f d
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Prodl_one (l : list A) : Prodl l (λ x, nat.succ 0) = 1 := algebra.Prodl_one l
|
2015-05-17 05:24:37 +00:00
|
|
|
|
end deceqA
|
|
|
|
|
|
2015-08-08 20:50:22 +00:00
|
|
|
|
/- Prod over finset -/
|
2015-05-17 05:24:37 +00:00
|
|
|
|
|
2015-08-08 00:53:30 +00:00
|
|
|
|
namespace finset
|
2015-08-08 20:50:22 +00:00
|
|
|
|
open finset
|
2015-08-08 00:53:30 +00:00
|
|
|
|
|
|
|
|
|
definition Prod (s : finset A) (f : A → nat) : nat := algebra.finset.Prod s f
|
2015-05-17 05:24:37 +00:00
|
|
|
|
notation `∏` binders `∈` s, r:(scoped f, Prod s f) := r
|
|
|
|
|
|
2015-08-08 00:53:30 +00:00
|
|
|
|
theorem Prod_empty (f : A → nat) : Prod ∅ f = 1 := algebra.finset.Prod_empty f
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Prod_mul (s : finset A) (f g : A → nat) : Prod s (λx, f x * g x) = Prod s f * Prod s g :=
|
2015-08-08 00:53:30 +00:00
|
|
|
|
algebra.finset.Prod_mul s f g
|
2015-05-17 05:24:37 +00:00
|
|
|
|
section deceqA
|
|
|
|
|
include deceqA
|
|
|
|
|
theorem Prod_insert_of_mem (f : A → nat) {a : A} {s : finset A} (H : a ∈ s) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Prod (insert a s) f = Prod s f := algebra.finset.Prod_insert_of_mem f H
|
2015-05-17 05:24:37 +00:00
|
|
|
|
theorem Prod_insert_of_not_mem (f : A → nat) {a : A} {s : finset A} (H : a ∉ s) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Prod (insert a s) f = f a * Prod s f := algebra.finset.Prod_insert_of_not_mem f H
|
2015-05-17 05:24:37 +00:00
|
|
|
|
theorem Prod_union (f : A → nat) {s₁ s₂ : finset A} (disj : s₁ ∩ s₂ = ∅) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Prod (s₁ ∪ s₂) f = Prod s₁ f * Prod s₂ f := algebra.finset.Prod_union f disj
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Prod_ext {s : finset A} {f g : A → nat} (H : ∀x, x ∈ s → f x = g x) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Prod s f = Prod s g := algebra.finset.Prod_ext H
|
|
|
|
|
theorem Prod_one (s : finset A) : Prod s (λ x, nat.succ 0) = 1 := algebra.finset.Prod_one s
|
2015-05-17 05:24:37 +00:00
|
|
|
|
end deceqA
|
|
|
|
|
|
2015-08-08 00:53:30 +00:00
|
|
|
|
end finset
|
|
|
|
|
|
2015-08-08 20:50:22 +00:00
|
|
|
|
/- Prod over set -/
|
|
|
|
|
|
|
|
|
|
namespace set
|
|
|
|
|
open set
|
|
|
|
|
|
|
|
|
|
noncomputable definition Prod (s : set A) (f : A → nat) : nat := algebra.set.Prod s f
|
|
|
|
|
notation `∏` binders `∈` s, r:(scoped f, Prod s f) := r
|
|
|
|
|
|
|
|
|
|
theorem Prod_empty (f : A → nat) : Prod ∅ f = 1 := algebra.set.Prod_empty f
|
|
|
|
|
theorem Prod_of_not_finite {s : set A} (nfins : ¬ finite s) (f : A → nat) : Prod s f = 1 :=
|
|
|
|
|
algebra.set.Prod_of_not_finite nfins f
|
|
|
|
|
theorem Prod_mul (s : set A) (f g : A → nat) : Prod s (λx, f x * g x) = Prod s f * Prod s g :=
|
|
|
|
|
algebra.set.Prod_mul s f g
|
|
|
|
|
theorem Prod_insert_of_mem (f : A → nat) {a : A} {s : set A} (H : a ∈ s) :
|
|
|
|
|
Prod (insert a s) f = Prod s f := algebra.set.Prod_insert_of_mem f H
|
|
|
|
|
theorem Prod_insert_of_not_mem (f : A → nat) {a : A} {s : set A} [fins : finite s] (H : a ∉ s) :
|
|
|
|
|
Prod (insert a s) f = f a * Prod s f := algebra.set.Prod_insert_of_not_mem f H
|
|
|
|
|
theorem Prod_union (f : A → nat) {s₁ s₂ : set A} [fins₁ : finite s₁] [fins₂ : finite s₂]
|
|
|
|
|
(disj : s₁ ∩ s₂ = ∅) :
|
|
|
|
|
Prod (s₁ ∪ s₂) f = Prod s₁ f * Prod s₂ f := algebra.set.Prod_union f disj
|
|
|
|
|
theorem Prod_ext {s : set A} {f g : A → nat} (H : ∀x, x ∈ s → f x = g x) :
|
|
|
|
|
Prod s f = Prod s g := algebra.set.Prod_ext H
|
|
|
|
|
theorem Prod_one (s : set A) : Prod s (λ x, nat.succ 0) = 1 := algebra.set.Prod_one s
|
|
|
|
|
|
|
|
|
|
end set
|
|
|
|
|
|
2015-05-17 05:24:37 +00:00
|
|
|
|
/- Suml -/
|
|
|
|
|
|
|
|
|
|
definition Suml (l : list A) (f : A → nat) : nat := algebra.Suml l f
|
|
|
|
|
notation `∑` binders `←` l, r:(scoped f, Suml l f) := r
|
|
|
|
|
|
|
|
|
|
theorem Suml_nil (f : A → nat) : Suml [] f = 0 := algebra.Suml_nil f
|
|
|
|
|
theorem Suml_cons (f : A → nat) (a : A) (l : list A) : Suml (a::l) f = f a + Suml l f :=
|
|
|
|
|
algebra.Suml_cons f a l
|
|
|
|
|
theorem Suml_append (l₁ l₂ : list A) (f : A → nat) : Suml (l₁++l₂) f = Suml l₁ f + Suml l₂ f :=
|
|
|
|
|
algebra.Suml_append l₁ l₂ f
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Suml_add (l : list A) (f g : A → nat) : Suml l (λx, f x + g x) = Suml l f + Suml l g :=
|
|
|
|
|
algebra.Suml_add l f g
|
2015-05-17 05:24:37 +00:00
|
|
|
|
section deceqA
|
|
|
|
|
include deceqA
|
|
|
|
|
theorem Suml_insert_of_mem (f : A → nat) {a : A} {l : list A} (H : a ∈ l) :
|
|
|
|
|
Suml (insert a l) f = Suml l f := algebra.Suml_insert_of_mem f H
|
|
|
|
|
theorem Suml_insert_of_not_mem (f : A → nat) {a : A} {l : list A} (H : a ∉ l) :
|
|
|
|
|
Suml (insert a l) f = f a + Suml l f := algebra.Suml_insert_of_not_mem f H
|
|
|
|
|
theorem Suml_union {l₁ l₂ : list A} (f : A → nat) (d : disjoint l₁ l₂) :
|
|
|
|
|
Suml (union l₁ l₂) f = Suml l₁ f + Suml l₂ f := algebra.Suml_union f d
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Suml_zero (l : list A) : Suml l (λ x, zero) = 0 := algebra.Suml_zero l
|
2015-05-17 05:24:37 +00:00
|
|
|
|
end deceqA
|
|
|
|
|
|
2015-08-08 20:50:22 +00:00
|
|
|
|
/- Sum over a finset -/
|
2015-05-17 05:24:37 +00:00
|
|
|
|
|
2015-08-08 00:53:30 +00:00
|
|
|
|
namespace finset
|
2015-08-08 20:50:22 +00:00
|
|
|
|
open finset
|
2015-08-08 00:53:30 +00:00
|
|
|
|
definition Sum (s : finset A) (f : A → nat) : nat := algebra.finset.Sum s f
|
2015-05-17 05:24:37 +00:00
|
|
|
|
notation `∑` binders `∈` s, r:(scoped f, Sum s f) := r
|
|
|
|
|
|
2015-08-08 00:53:30 +00:00
|
|
|
|
theorem Sum_empty (f : A → nat) : Sum ∅ f = 0 := algebra.finset.Sum_empty f
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Sum_add (s : finset A) (f g : A → nat) : Sum s (λx, f x + g x) = Sum s f + Sum s g :=
|
2015-08-08 00:53:30 +00:00
|
|
|
|
algebra.finset.Sum_add s f g
|
2015-05-17 05:24:37 +00:00
|
|
|
|
section deceqA
|
|
|
|
|
include deceqA
|
|
|
|
|
theorem Sum_insert_of_mem (f : A → nat) {a : A} {s : finset A} (H : a ∈ s) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Sum (insert a s) f = Sum s f := algebra.finset.Sum_insert_of_mem f H
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Sum_insert_of_not_mem (f : A → nat) {a : A} {s : finset A} (H : a ∉ s) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Sum (insert a s) f = f a + Sum s f := algebra.finset.Sum_insert_of_not_mem f H
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Sum_union (f : A → nat) {s₁ s₂ : finset A} (disj : s₁ ∩ s₂ = ∅) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Sum (s₁ ∪ s₂) f = Sum s₁ f + Sum s₂ f := algebra.finset.Sum_union f disj
|
2015-05-17 06:00:38 +00:00
|
|
|
|
theorem Sum_ext {s : finset A} {f g : A → nat} (H : ∀x, x ∈ s → f x = g x) :
|
2015-08-08 00:53:30 +00:00
|
|
|
|
Sum s f = Sum s g := algebra.finset.Sum_ext H
|
|
|
|
|
theorem Sum_zero (s : finset A) : Sum s (λ x, zero) = 0 := algebra.finset.Sum_zero s
|
2015-05-17 05:24:37 +00:00
|
|
|
|
end deceqA
|
|
|
|
|
|
2015-08-08 00:53:30 +00:00
|
|
|
|
end finset
|
|
|
|
|
|
2015-08-08 20:50:22 +00:00
|
|
|
|
/- Sum over a set -/
|
|
|
|
|
|
|
|
|
|
namespace set
|
|
|
|
|
open set
|
|
|
|
|
|
|
|
|
|
noncomputable definition Sum (s : set A) (f : A → nat) : nat := algebra.set.Sum s f
|
|
|
|
|
notation `∏` binders `∈` s, r:(scoped f, Sum s f) := r
|
|
|
|
|
|
|
|
|
|
theorem Sum_empty (f : A → nat) : Sum ∅ f = 0 := algebra.set.Sum_empty f
|
|
|
|
|
theorem Sum_of_not_finite {s : set A} (nfins : ¬ finite s) (f : A → nat) : Sum s f = 0 :=
|
|
|
|
|
algebra.set.Sum_of_not_finite nfins f
|
|
|
|
|
theorem Sum_add (s : set A) (f g : A → nat) : Sum s (λx, f x + g x) = Sum s f + Sum s g :=
|
|
|
|
|
algebra.set.Sum_add s f g
|
|
|
|
|
theorem Sum_insert_of_mem (f : A → nat) {a : A} {s : set A} (H : a ∈ s) :
|
|
|
|
|
Sum (insert a s) f = Sum s f := algebra.set.Sum_insert_of_mem f H
|
|
|
|
|
theorem Sum_insert_of_not_mem (f : A → nat) {a : A} {s : set A} [fins : finite s] (H : a ∉ s) :
|
|
|
|
|
Sum (insert a s) f = f a + Sum s f := algebra.set.Sum_insert_of_not_mem f H
|
|
|
|
|
theorem Sum_union (f : A → nat) {s₁ s₂ : set A} [fins₁ : finite s₁] [fins₂ : finite s₂]
|
|
|
|
|
(disj : s₁ ∩ s₂ = ∅) :
|
|
|
|
|
Sum (s₁ ∪ s₂) f = Sum s₁ f + Sum s₂ f := algebra.set.Sum_union f disj
|
|
|
|
|
theorem Sum_ext {s : set A} {f g : A → nat} (H : ∀x, x ∈ s → f x = g x) :
|
|
|
|
|
Sum s f = Sum s g := algebra.set.Sum_ext H
|
|
|
|
|
theorem Sum_zero (s : set A) : Sum s (λ x, 0) = 0 := algebra.set.Sum_zero s
|
|
|
|
|
|
|
|
|
|
end set
|
|
|
|
|
|
2015-05-16 12:26:59 +00:00
|
|
|
|
end nat
|