-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSum_of_arithmetic_progression.lean
124 lines (109 loc) · 3.63 KB
/
Sum_of_arithmetic_progression.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
-- Sum_of_arithmetic_progression.lean
-- Proofs of a+(a+d)+(a+2d)+···+(a+nd)=(n+1)(2a+nd)/2
-- José A. Alonso Jiménez <https://jaalonso.github.io>
-- Seville, September 7, 2024
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Prove that the sum of the terms of the arithmetic progression
-- a + (a + d) + (a + 2 × d) + ··· + (a + n × d)
-- is (n + 1) × (2 × a + n × d) / 2.
-- ---------------------------------------------------------------------
-- Proof in natural language
-- =========================
-- Let
-- s(a,d,n) = a + (a + d) + (a + 2d) + ··· + (a + nd)
-- We need to prove that
-- s(a,d,n) = (n + 1)(2a + nd) / 2
-- or, equivalently that
-- 2s(a,d,n) = (n + 1)(2a + nd)
-- We will do this by induction on n.
--
-- Base case: Let n = 0. Then,
-- 2s(a,d,n) = 2s(a,d,0)
-- = 2·a
-- = (0 + 1)(2a + 0.d)
-- = (n + 1)(2a + nd)
--
-- Induction step: Let n = m+1 and assume the induction hypothesis
-- (IH)
-- 2s(a,d,m) = (m + 1)(2a + md)
-- Then,
-- 2s(a,d,n) = 2s(a,d,m+1)
-- = 2(s(a,d,m) + (a + (m + 1)d))
-- = 2s(a,d,m) + 2(a + (m + 1)d)
-- = ((m + 1)(2a + md)) + 2(a + (m + 1)d) [by IH]
-- = (m + 2)(2a + (m + 1)d)
-- = (n + 1)(2a + nd)
-- Proof with Lean4
-- ================
import Mathlib.Data.Nat.Defs
import Mathlib.Tactic
open Nat
variable (n : ℕ)
variable (a d : ℝ)
set_option pp.fieldNotation false
def sumAP : ℝ → ℝ → ℕ → ℝ
| a, _, 0 => a
| a, d, n + 1 => sumAP a d n + (a + (n + 1) * d)
@[simp]
lemma sumAP_zero :
sumAP a d 0 = a :=
by simp only [sumAP]
@[simp]
lemma sumAP_succ :
sumAP a d (n + 1) = sumAP a d n + (a + (n + 1) * d) :=
by simp only [sumAP]
-- Proof 1
-- =======
example :
2 * sumAP a d n = (n + 1) * (2 * a + n * d) :=
by
induction n with
| zero =>
-- ⊢ 2 * sumAP a d 0 = (↑0 + 1) * (2 * a + ↑0 * d)
have h : 2 * sumAP a d 0 = (0 + 1) * (2 * a + 0 * d) :=
calc 2 * sumAP a d 0
= 2 * a
:= congrArg (2 * .) (sumAP_zero a d)
_ = (0 + 1) * (2 * a + 0 * d)
:= by ring_nf
exact_mod_cast h
| succ m IH =>
-- m : ℕ
-- IH : 2 * sumAP a d m = (↑m + 1) * (2 * a + ↑m * d)
-- ⊢ 2 * sumAP a d (m + 1) = (↑(m + 1) + 1) * (2 * a + ↑(m + 1) * d)
calc 2 * sumAP a d (succ m)
= 2 * (sumAP a d m + (a + (m + 1) * d))
:= congrArg (2 * .) (sumAP_succ m a d)
_ = 2 * sumAP a d m + 2 * (a + (m + 1) * d)
:= by ring_nf
_ = ((m + 1) * (2 * a + m * d)) + 2 * (a + (m + 1) * d)
:= congrArg (. + 2 * (a + (m + 1) * d)) IH
_ = (m + 2) * (2 * a + (m + 1) * d)
:= by ring_nf
_ = (succ m + 1) * (2 * a + succ m * d)
:= by norm_cast
-- Proof 2
-- =======
example :
2 * sumAP a d n = (n + 1) * (2 * a + n * d) :=
by
induction n with
| zero =>
-- ⊢ 2 * sumAP a d 0 = (↑0 + 1) * (2 * a + ↑0 * d)
simp
| succ m IH =>
-- m : ℕ
-- IH : 2 * sumAP a d m = (↑m + 1) * (2 * a + ↑m * d)
-- ⊢ 2 * sumAP a d (m + 1) = (↑(m + 1) + 1) * (2 * a + ↑(m + 1) * d)
calc 2 * sumAP a d (succ m)
= 2 * (sumAP a d m + (a + (m + 1) * d))
:= rfl
_ = 2 * sumAP a d m + 2 * (a + (m + 1) * d)
:= by ring_nf
_ = ((m + 1) * (2 * a + m * d)) + 2 * (a + (m + 1) * d)
:= congrArg (. + 2 * (a + (m + 1) * d)) IH
_ = (m + 2) * (2 * a + (m + 1) * d)
:= by ring_nf
_ = (succ m + 1) * (2 * a + succ m * d)
:= by norm_cast