Skip to content

Commit a95e78a

Browse files
jamesmckinnaMatthewDaggitt
authored andcommitted
Proof of the Binomial Theorem for (Commutative)Semiring [supersedes #1287] (#1928)
1 parent 53f4211 commit a95e78a

File tree

4 files changed

+271
-2
lines changed

4 files changed

+271
-2
lines changed

CHANGELOG.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -1804,6 +1804,12 @@ New modules
18041804
Algebra.Properties.Loop
18051805
```
18061806

1807+
* Properties of (Commutative)Semiring: the Binomial Theorem
1808+
```
1809+
Algebra.Properties.CommutativeSemiring.Binomial
1810+
Algebra.Properties.Semiring.Binomial
1811+
```
1812+
18071813
* Some n-ary functions manipulating lists
18081814
```
18091815
Data.List.Nary.NonDependent
@@ -2020,7 +2026,7 @@ Additions to existing modules
20202026

20212027
* Added new proof to `Algebra.Properties.Monoid.Sum`:
20222028
```agda
2023-
sum-init-last : ∀ {n} (t : Vector _ (suc n)) → sum t ≈ sum (init t) + last t
2029+
sum-init-last : (t : Vector _ (suc n)) → sum t ≈ sum (init t) + last t
20242030
```
20252031

20262032
* Added new proofs to `Algebra.Properties.Semigroup`:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- The Binomial Theorem for Commutative Semirings
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --cubical-compatible --safe #-}
8+
9+
open import Algebra.Bundles
10+
using (CommutativeSemiring)
11+
12+
module Algebra.Properties.CommutativeSemiring.Binomial {a ℓ} (S : CommutativeSemiring a ℓ) where
13+
14+
open CommutativeSemiring S
15+
open import Algebra.Properties.Semiring.Exp semiring using (_^_)
16+
import Algebra.Properties.Semiring.Binomial semiring as Binomial
17+
open Binomial public hiding (theorem)
18+
19+
------------------------------------------------------------------------
20+
-- Here it is
21+
22+
theorem : n x y (x + y) ^ n ≈ binomialExpansion x y n
23+
theorem n x y = Binomial.theorem x y (*-comm x y) n
24+

src/Algebra/Properties/Monoid/Sum.agda

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,17 @@ open import Algebra.Definitions.RawMonoid rawMonoid public
4242
------------------------------------------------------------------------
4343
-- An alternative mathematical-style syntax for sumₜ
4444

45-
infixl 10 sum-syntax
45+
infixl 10 sum-syntax sum⁺-syntax
4646

4747
sum-syntax : n Vector Carrier n Carrier
4848
sum-syntax _ = sum
4949

5050
syntax sum-syntax n (λ i x) = ∑[ i < n ] x
5151

52+
sum⁺-syntax = sum-syntax ∘ suc
53+
54+
syntax sum⁺-syntax n (λ i x) = ∑[ i ≤ n ] x
55+
5256
------------------------------------------------------------------------
5357
-- Properties
5458

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- The Binomial Theorem for *-commuting elements in a Semiring
5+
--
6+
-- Freely adapted from PR #1287 by Maciej Piechotka (@uzytkownik)
7+
------------------------------------------------------------------------
8+
9+
{-# OPTIONS --cubical-compatible --safe #-}
10+
11+
open import Algebra.Bundles using (Semiring)
12+
open import Data.Bool.Base using (true)
13+
open import Data.Nat.Base as Nat hiding (_+_; _*_; _^_)
14+
open import Data.Nat.Combinatorics
15+
using (_C_; nCn≡1; nC1≡n; nCk+nC[k+1]≡[n+1]C[k+1])
16+
open import Data.Nat.Properties as Nat
17+
using (<⇒<ᵇ; n<1+n; n∸n≡0; +-∸-assoc)
18+
open import Data.Fin.Base as Fin
19+
using (Fin; zero; suc; toℕ; fromℕ; inject₁)
20+
open import Data.Fin.Patterns using (0F)
21+
open import Data.Fin.Properties as Fin
22+
using (toℕ<n; toℕ-fromℕ; toℕ-inject₁)
23+
open import Data.Fin.Relation.Unary.Top
24+
using (view; ‵fromℕ; ‵inject₁; view-fromℕ; view-inject₁)
25+
open import Function.Base using (_∘_)
26+
open import Relation.Binary.PropositionalEquality.Core as ≡
27+
using (_≡_; _≢_; cong)
28+
29+
module Algebra.Properties.Semiring.Binomial
30+
{a ℓ} (S : Semiring a ℓ)
31+
(open Semiring S)
32+
(x y : Carrier)
33+
where
34+
35+
open import Algebra.Definitions _≈_
36+
open import Algebra.Properties.Semiring.Sum S
37+
open import Algebra.Properties.Semiring.Mult S
38+
open import Algebra.Properties.Semiring.Exp S
39+
open import Relation.Binary.Reasoning.Setoid setoid
40+
41+
------------------------------------------------------------------------
42+
-- Definitions
43+
44+
-- Note - `n` could be implicit in many of these definitions, but the
45+
-- code is more readable if left explicit.
46+
47+
binomial : (n : ℕ) Fin (suc n) Carrier
48+
binomial n k = (x ^ toℕ k) * (y ^ (n ∸ toℕ k))
49+
50+
binomialTerm : (n : ℕ) Fin (suc n) Carrier
51+
binomialTerm n k = (n C toℕ k) × binomial n k
52+
53+
binomialExpansion : Carrier
54+
binomialExpansion n = ∑[ k ≤ n ] (binomialTerm n k)
55+
56+
term₁ : (n : ℕ) Fin (suc (suc n)) Carrier
57+
term₁ n zero = 0#
58+
term₁ n (suc k) = x * (binomialTerm n k)
59+
60+
term₂ : (n : ℕ) Fin (suc (suc n)) Carrier
61+
term₂ n k with view k
62+
... | ‵fromℕ = 0#
63+
... | ‵inject₁ j = y * binomialTerm n j
64+
65+
sum₁ : Carrier
66+
sum₁ n = ∑[ k ≤ suc n ] term₁ n k
67+
68+
sum₂ : Carrier
69+
sum₂ n = ∑[ k ≤ suc n ] term₂ n k
70+
71+
------------------------------------------------------------------------
72+
-- Properties
73+
74+
term₂[n,n+1]≈0# : n term₂ n (fromℕ (suc n)) ≈ 0#
75+
term₂[n,n+1]≈0# n rewrite view-fromℕ (suc n) = refl
76+
77+
lemma₁ : n x * binomialExpansion n ≈ sum₁ n
78+
lemma₁ n = begin
79+
x * binomialExpansion n ≈⟨ *-distribˡ-sum x (binomialTerm n) ⟩
80+
∑[ i ≤ n ] (x * binomialTerm n i) ≈˘⟨ +-identityˡ _ ⟩
81+
0# + ∑[ i ≤ n ] (x * binomialTerm n i) ≡⟨⟩
82+
0# + ∑[ i ≤ n ] term₁ n (suc i) ≡⟨⟩
83+
sum₁ n ∎
84+
85+
lemma₂ : n y * binomialExpansion n ≈ sum₂ n
86+
lemma₂ n = begin
87+
y * binomialExpansion n ≈⟨ *-distribˡ-sum y (binomialTerm n) ⟩
88+
∑[ i ≤ n ] (y * binomialTerm n i) ≈˘⟨ +-identityʳ _ ⟩
89+
∑[ i ≤ n ] (y * binomialTerm n i) + 0# ≈⟨ +-cong (sum-cong-≋ lemma₂-inject₁) (sym (term₂[n,n+1]≈0# n)) ⟩
90+
(∑[ i ≤ n ] term₂-inject₁ i) + term₂ n [n+1] ≈˘⟨ sum-init-last (term₂ n) ⟩
91+
sum (term₂ n) ≡⟨⟩
92+
sum₂ n ∎
93+
where
94+
[n+1] = fromℕ (suc n)
95+
96+
term₂-inject₁ : (i : Fin (suc n)) Carrier
97+
term₂-inject₁ i = term₂ n (inject₁ i)
98+
99+
lemma₂-inject₁ : i y * binomialTerm n i ≈ term₂-inject₁ i
100+
lemma₂-inject₁ i rewrite view-inject₁ i = refl
101+
102+
------------------------------------------------------------------------
103+
-- Next, a lemma which is independent of commutativity
104+
105+
x*lemma : {n} (i : Fin (suc n))
106+
x * binomialTerm n i ≈ (n C toℕ i) × binomial (suc n) (suc i)
107+
x*lemma {n} i = begin
108+
x * binomialTerm n i ≡⟨⟩
109+
x * ((n C k) × (x ^ k * y ^ (n ∸ k))) ≈˘⟨ *-congˡ (×-assoc-* (n C k) _ _) ⟩
110+
x * ((n C k) × x ^ k * y ^ (n ∸ k)) ≈˘⟨ *-assoc x ((n C k) × x ^ k) _ ⟩
111+
(x * (n C k) × x ^ k) * y ^ (n ∸ k) ≈⟨ *-congʳ (×-comm-* (n C k) _ _) ⟩
112+
(n C k) × x ^ (suc k) * y ^ (n ∸ k) ≡⟨⟩
113+
(n C k) × x ^ (suc k) * y ^ (suc n ∸ suc k) ≈⟨ ×-assoc-* (n C k) _ _ ⟩
114+
(n C k) × binomial (suc n) (suc i) ∎
115+
where k = toℕ i
116+
117+
------------------------------------------------------------------------
118+
-- Next, a lemma which does require commutativity
119+
120+
y*lemma : x * y ≈ y * x {n : ℕ} (j : Fin n)
121+
y * binomialTerm n (suc j) ≈ (n C toℕ (suc j)) × binomial (suc n) (suc (inject₁ j))
122+
y*lemma x*y≈y*x {n} j = begin
123+
y * binomialTerm n (suc j)
124+
≈⟨ ×-comm-* nC[j+1] y (binomial n (suc j)) ⟩
125+
nC[j+1] × (y * binomial n (suc j))
126+
≈⟨ ×-congʳ nC[j+1] (y*x^m*y^n≈x^m*y^[n+1] x*y≈y*x [j+1] [n-j-1]) ⟩
127+
nC[j+1] × (x ^ [j+1] * y ^ [n-j])
128+
≈˘⟨ ×-congʳ nC[j+1] (*-congʳ (^-congʳ x (cong suc k≡j))) ⟩
129+
nC[j+1] × (x ^ [k+1] * y ^ [n-j])
130+
≈˘⟨ ×-congʳ nC[j+1] (*-congˡ (^-congʳ y [n-k]≡[n-j])) ⟩
131+
nC[j+1] × (x ^ [k+1] * y ^ [n-k])
132+
≡⟨⟩
133+
nC[j+1] × (x ^ [k+1] * y ^ [n+1]-[k+1])
134+
≡⟨⟩
135+
(n C toℕ (suc j)) × binomial (suc n) (suc i) ∎
136+
where
137+
i = inject₁ j
138+
k = toℕ i
139+
[k+1] = ℕ.suc k
140+
[j+1] = toℕ (suc j)
141+
[n-k] = n ∸ k
142+
[n+1]-[k+1] = [n-k]
143+
[n-j-1] = n ∸ [j+1]
144+
[n-j] = ℕ.suc [n-j-1]
145+
nC[j+1] = n C [j+1]
146+
147+
k≡j : k ≡ toℕ j
148+
k≡j = toℕ-inject₁ j
149+
150+
[n-k]≡[n-j] : [n-k] ≡ [n-j]
151+
[n-k]≡[n-j] = ≡.trans (cong (n ∸_) k≡j) (+-∸-assoc 1 (toℕ<n j))
152+
153+
------------------------------------------------------------------------
154+
-- Now, a lemma characterising the sum of the term₁ and term₂ expressions
155+
156+
private
157+
n<ᵇ1+n : n (n Nat.<ᵇ suc n) ≡ true
158+
n<ᵇ1+n n with true n Nat.<ᵇ suc n | _ <⇒<ᵇ (n<1+n n) = ≡.refl
159+
160+
term₁+term₂≈term : x * y ≈ y * x n i term₁ n i + term₂ n i ≈ binomialTerm (suc n) i
161+
162+
term₁+term₂≈term x*y≈y*x n 0F = begin
163+
term₁ n 0F + term₂ n 0F ≡⟨⟩
164+
0# + y * (1 × (1# * y ^ n)) ≈⟨ +-identityˡ _ ⟩
165+
y * (1 × (1# * y ^ n)) ≈⟨ *-congˡ (+-identityʳ (1# * y ^ n)) ⟩
166+
y * (1# * y ^ n) ≈⟨ *-congˡ (*-identityˡ (y ^ n)) ⟩
167+
y * y ^ n ≡⟨⟩
168+
y ^ suc n ≈˘⟨ *-identityˡ (y ^ suc n) ⟩
169+
1# * y ^ suc n ≈˘⟨ +-identityʳ (1# * y ^ suc n) ⟩
170+
1 × (1# * y ^ suc n) ≡⟨⟩
171+
binomialTerm (suc n) 0F ∎
172+
173+
term₁+term₂≈term x*y≈y*x n (suc i) with view i
174+
... | ‵fromℕ {n}
175+
{- remembering that i = fromℕ n, definitionally -}
176+
rewrite toℕ-fromℕ n
177+
| nCn≡1 n
178+
| n∸n≡0 n
179+
| n<ᵇ1+n n
180+
= begin
181+
x * ((x ^ n * 1#) + 0#) + 0# ≈⟨ +-identityʳ _ ⟩
182+
x * ((x ^ n * 1#) + 0#) ≈⟨ *-congˡ (+-identityʳ _) ⟩
183+
x * (x ^ n * 1#) ≈˘⟨ *-assoc _ _ _ ⟩
184+
x * x ^ n * 1# ≈˘⟨ +-identityʳ _ ⟩
185+
1 × (x * x ^ n * 1#) ∎
186+
187+
... | ‵inject₁ j
188+
{- remembering that i = inject₁ j, definitionally -}
189+
= begin
190+
(x * binomialTerm n i) + (y * binomialTerm n (suc j))
191+
≈⟨ +-cong (x*lemma i) (y*lemma x*y≈y*x j) ⟩
192+
(nCk × [x^k+1]*[y^n-k]) + (nC[j+1] × [x^k+1]*[y^n-k])
193+
≈˘⟨ +-congˡ (×-congˡ nC[k+1]≡nC[j+1]) ⟩
194+
(nCk × [x^k+1]*[y^n-k]) + (nC[k+1] × [x^k+1]*[y^n-k])
195+
≈˘⟨ ×-homo-+ [x^k+1]*[y^n-k] nCk nC[k+1] ⟩
196+
(nCk Nat.+ nC[k+1]) × [x^k+1]*[y^n-k]
197+
≡⟨ cong (_× [x^k+1]*[y^n-k]) (nCk+nC[k+1]≡[n+1]C[k+1] n k) ⟩
198+
((suc n) C (suc k)) × [x^k+1]*[y^n-k]
199+
≡⟨⟩
200+
binomialTerm (suc n) (suc i) ∎
201+
where
202+
k = toℕ i
203+
[k+1] = ℕ.suc k
204+
[j+1] = toℕ (suc j)
205+
nCk = n C k
206+
nC[k+1] = n C [k+1]
207+
nC[j+1] = n C [j+1]
208+
[x^k+1]*[y^n-k] = binomial (suc n) (suc i)
209+
210+
nC[k+1]≡nC[j+1] : nC[k+1] ≡ nC[j+1]
211+
nC[k+1]≡nC[j+1] = cong ((n C_) ∘ suc) (toℕ-inject₁ j)
212+
213+
------------------------------------------------------------------------
214+
-- Finally, the main result
215+
216+
theorem : x * y ≈ y * x n (x + y) ^ n ≈ binomialExpansion n
217+
theorem x*y≈y*x zero = begin
218+
(x + y) ^ 0 ≡⟨⟩
219+
1# ≈˘⟨ 1×-identityʳ 1# ⟩
220+
1 × 1# ≈˘⟨ *-identityʳ (1 × 1#) ⟩
221+
(1 × 1#) * 1# ≈⟨ ×-assoc-* 1 1# 1# ⟩
222+
1 × (1# * 1#) ≡⟨⟩
223+
1 × (x ^ 0 * y ^ 0) ≈˘⟨ +-identityʳ _ ⟩
224+
1 × (x ^ 0 * y ^ 0) + 0# ≡⟨⟩
225+
(0 C 0) × (x ^ 0 * y ^ 0) + 0# ≡⟨⟩
226+
binomialExpansion 0
227+
theorem x*y≈y*x n+1@(suc n) = begin
228+
(x + y) ^ n+1 ≡⟨⟩
229+
(x + y) * (x + y) ^ n ≈⟨ *-congˡ (theorem x*y≈y*x n) ⟩
230+
(x + y) * binomialExpansion n ≈⟨ distribʳ _ _ _ ⟩
231+
x * binomialExpansion n + y * binomialExpansion n ≈⟨ +-cong (lemma₁ n) (lemma₂ n) ⟩
232+
sum₁ n + sum₂ n ≈˘⟨ ∑-distrib-+ (term₁ n) (term₂ n) ⟩
233+
∑[ i ≤ n+1 ] (term₁ n i + term₂ n i) ≈⟨ sum-cong-≋ (term₁+term₂≈term x*y≈y*x n) ⟩
234+
∑[ i ≤ n+1 ] binomialTerm n+1 i ≡⟨⟩
235+
binomialExpansion n+1 ∎

0 commit comments

Comments
 (0)