-
Notifications
You must be signed in to change notification settings - Fork 0
/
imo_1986_q1.lean
343 lines (333 loc) · 9.39 KB
/
imo_1986_q1.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
import algebra.ring.basic
import data.real.basic
import data.nat.parity
open nat
--helper theorems
theorem num_odd_square_odd (a : ℕ): odd a ↔ odd (a^2) :=
begin
split,
{
intro h,
rw pow_two,
have h₁ : odd (a * a) ↔ odd a ∧ odd a, from nat.odd_mul,
rw h₁,
split,
{exact h},
{exact h}
},
{
rw pow_two,
intro h,
have h₁ : odd (a * a) ↔ (odd a ∧ odd a), from nat.odd_mul,
have h₂ : odd a ∧ odd a, by {
have h₃ : odd (a * a) → (odd a ∧ odd a), from iff.mp h₁,
show odd a ∧ odd a, from h₃ (h)
},
have h₄ : odd a, from and.left h₂,
exact h₄
}
end
-- the same but for even numbers
-- such wow trick
theorem num_even_square_even (a : ℕ) : even a ↔ even (a^2) :=
begin
repeat {rw nat.even_iff_not_odd},
rw not_iff_not_of_iff,
rw num_odd_square_odd,
end
-- another helper theorem for casing the even difference
theorem even_diff_same_parity (a b : ℕ) (h₀ : a ≥ b) :
even (a - b) ↔ odd a ∧ odd b ∨ even a ∧ even b :=
begin
split,
{
intro h,
cases even_or_odd a with even_a odd_a,
{
have h₁ : even a ↔ even b, by {
rw ←nat.even_sub,
exact h,
exact h₀,
},
have even_b : even b, by {rw ←h₁, exact even_a},
have even_a_b : even a ∧ even b, by {
exact ⟨even_a, even_b⟩,
},
exact or.inr even_a_b,
},
{
have h₁ : odd a ↔ odd b, by {
rw ←nat.even_sub',
exact h,
exact h₀,
},
have odd_b : odd b, by {rw ←h₁, exact odd_a},
have odd_a_b : odd a ∧ odd b, by {
exact ⟨odd_a, odd_b⟩,
},
exact or.inl odd_a_b,
},
},
{
intro h,
cases h with odd_a_b even_a_b,
{
rw nat.even_sub',
{
cases odd_a_b with odd_a odd_b,
exact iff_of_true odd_a odd_b,
},
{exact h₀},
},
{
rw nat.even_sub,
{
cases even_a_b with even_a even_b,
exact iff_of_true even_a even_b,
},
{exact h₀},
}
}
end
-- definitions of a square number
def is_square (n : ℕ) :=
∃ k : ℕ, k^2 = n
-- useful theorem to rewrite the definition
theorem is_square_def {n : ℕ} :
is_square n ↔ ∃ k : ℕ, k^2 = n :=
begin
refl
end
-- couple of cases to test how squaring of numbers works
-- case 1: 9 is a square, just using a substitution by definition
theorem nine_is_square : is_square 9 :=
begin
rw is_square_def,
use 3,
ring
end
-- case 2: 10 is not a square, here we have to use parity contradictions
theorem ten_is_not_square : ¬ is_square 10 :=
begin
rw is_square_def,
by_contradiction,
cases h with k h,
have h₁ : even 10, by {rw even, use 5, ring},
have h₂ : even k, by {rw num_even_square_even, rw h, exact h₁},
unfold even at h₂,
cases h₂ with m h₃,
have h₄ : (2 * m) ^ 2 = 10, by {rw ←h₃, exact h},
have h₅ : 4 * m ^ 2 = 10, by {rw ←h₄, ring},
have h₆ : 2 * m ^ 2 = 5, by linarith,
have h₇ : even (2 * m ^ 2), by {rw even, use (m ^ 2)},
have h₈ : even 5, by {rw ←h₆, exact h₇},
have h₉ : ¬ even 5, by {
rw nat.even_iff_not_odd, rw decidable.not_not_iff,
rw odd, use 2, ring
},
exact h₉ h₈,
end
-- trivial proof by substitution that 4 is not an odd number
theorem four_is_not_odd (n : ℕ) : ¬ odd 4 :=
begin
rw nat.odd_iff_not_even,
rw decidable.not_not_iff,
rw even,
use 2,
ring,
end
-- solving the original task
theorem IMO1986P1
(d : ℕ)
(h₀ : d > 1)
(h₁ : is_square (2 * d - 1))
(h₂ : is_square (5 * d - 1))
(h₃ : is_square (13 * d - 1)):
false :=
begin
-- step 1, proving that a is odd
unfold is_square at h₁,
cases h₁ with a ha,
have a_odd : odd a, by {
rw [num_odd_square_odd, ha, nat.odd_sub'],
{
have one_odd : odd 1, by {rw odd, use 0, ring},
have even_2d : even (2 * d), by {rw even, use d},
exact iff_of_true one_odd even_2d
},
{
linarith
},
},
-- step 2, proving that d is odd
unfold odd at a_odd,
cases a_odd with x hx,
have d_odd : odd d, by {
have h₄ : (2*x + 1)^2 = 2*d - 1, by {rw ←hx, exact ha},
have h₅ : 4*x*x + 4*x + 1 = 2*d - 1, by linarith,
have h₆ : 2*d - 1 = 4*x*x + 4*x + 1, by exact eq.symm h₅,
have h₇ : 2*d - 1 + 1 = 4*x*x + 4*x + 1 + 1, by linarith,
have h₈ : 2*d = 4*x*x + 4*x + 1 + 1, by {
rw ←h₇, induction d, linarith, ring_nf,
},
have h₉ : 2*d = 4*x*x + 4*x + 2, by linarith,
have hh₁ : 2*d = 2*(2*x*x + 2*x + 1), by linarith,
have hh₂ : d = 2*x*x + 2*x + 1, by linarith,
rw odd,
use (x*x + x),
rw [mul_add, ←mul_assoc],
exact hh₂,
},
-- step 3, proving that b is even
unfold odd at d_odd,
cases d_odd with d' hd',
unfold is_square at h₂,
cases h₂ with b hb,
have b_even : even b, by {
rw [num_even_square_even, hb, hd', even],
use (5*d' + 2),
repeat {rw mul_add, rw ←mul_assoc},
simp,
refl,
},
-- step 4, proving that c is even
unfold is_square at h₃,
cases h₃ with c hc,
have c_even : even c, by {
rw [num_even_square_even, hc, hd', even],
use (13*d' + 6),
repeat {rw mul_add, rw ←mul_assoc},
simp,
refl,
},
-- step 5, introducing new parity facts about d
unfold even at b_even,
cases b_even with y hy,
unfold even at c_even,
cases c_even with z hz,
have hdp : (z + y) * (z - y) = 2*d, by {
have h₁ : c^2 - b^2 = (13*d-1) - (5*d-1), by rw [hc, hb],
have h₂ : c^2 - b^2 = 8*d, by {
rw h₁,
have h₃ : 13 = 8 + 5, by refl,
rw h₃,
rw add_mul,
have h₄ : (∃ t₁ : ℕ, t₁ = 8*d), by use (8*d),
cases h₄ with t₁ ht₁,
have h₅ : (∃ t₂ : ℕ, t₂ = 5*d), by use (5*d),
cases h₅ with t₂ ht₂,
repeat {rw [←ht₁, ←ht₂]},
have h₆ : 1 ≤ t₂, by {rw ht₂, linarith},
have h₇ : t₁ + t₂ - 1 = t₁ + (t₂ - 1), by {
rw nat.add_sub_assoc,
exact h₆,
},
rw h₇,
have h₈ : (∃ t₃ : ℕ, t₃ = t₂ - 1), by use (t₂-1),
cases h₈ with t₃ ht₃,
repeat {rw ←ht₃},
simp,
},
have h₃ : (2*z)^2 - (2*y)^2 = 8*d, by {rw [←hz, ←hy], exact h₂},
have h₄ : 4*z*z - 4*y*y = 8*d, by {
rw ←h₃,
repeat {rw [pow_two, ←mul_assoc]},
ring_nf,
},
have h₅ : 4*(z*z - y*y) = 4*(2*d), by {
have eight_eq : 4 * 2 = 8, by refl,
rw [←mul_assoc, eight_eq, ←h₄, mul_assoc, mul_assoc],
have h₆ : (∃ t₁ : ℕ, t₁ = z * z), by use (z*z),
cases h₆ with t₁ ht₁,
have h₇ : (∃ t₂ : ℕ, t₂ = y * y), by use (y*y),
cases h₇ with t₂ ht₂,
rw [←ht₁, ←ht₂],
rw nat.mul_sub_left_distrib,
},
have h₆ : z*z - y*y = 2*d, by linarith,
rw [←h₆, nat.mul_self_sub_mul_self_eq],
},
-- step 6, proving the possible cases of new parity facts
have h : odd (z + y) ∧ odd (z - y) ∨ even (z + y) ∧ even (z - y), by {
rw ←even_diff_same_parity,
{
rw even,
use y,
have z_ge_y : z ≥ y, by {
have y_2_le_z_2 : 2 * y ≤ 2 * z, by {
rw [←hy, ←hz],
have b2_le_c2 : b ^ 2 ≤ c ^ 2, by {
rw [hb, hc],
have d5_le_d13 : 5 * d ≤ 13 * d, by linarith,
exact tsub_le_tsub_right d5_le_d13 1,
},
repeat {rw pow_two at b2_le_c2},
exact nat.mul_self_le_mul_self_iff.mpr b2_le_c2,
},
linarith,
},
have h₁ : (∃ t₁ : ℕ, t₁ = z + y), by use (z + y),
cases h₁ with t₁ ht₁,
have h₂ : (∃ t₂ : ℕ, t₂ = z - y), by use (z - y),
cases h₂ with t₂ ht₂,
have h₃ : (∃ t₃ : ℕ, t₃ = 2 * y), by use (2 * y),
cases h₃ with t₃ ht₃,
rw [←ht₁, ←ht₂, ←ht₃],
have h₁ : t₁ ≥ t₂, by {
rw [ht₁, ht₂],
norm_num,
induction y,
{ring_nf},
{
ring_nf,
exact le_self_add,
},
},
rw nat.sub_eq_iff_eq_add,
{
rw [ht₂, ←nat.add_sub_assoc],
{
rw nat.sub_add_comm,
{
rw [ht₃, ←nat.one_mul y, ←mul_assoc, ←nat.mul_sub_right_distrib],
norm_num,
rw ht₁,
exact add_comm z y,
},
{rw ht₃, linarith},
},
{exact z_ge_y},
},
{exact h₁},
},
{
have ht : z - y + y ≤ z + y + y, by {simp, linarith},
exact (add_le_add_iff_right y).mp ht,
},
},
cases h with mul_odd mul_even,
{
cases mul_odd with h₁ h₂,
have even_2d : even (2 * d), by {rw even, use d},
have odd_2d : odd (2 * d), by {rw ←hdp, exact odd.mul h₁ h₂},
have not_odd_2d : ¬odd (2 * d), by {rw ←even_iff_not_odd, exact even_2d},
exact not_odd_2d odd_2d,
},
{
cases mul_even with h₁ h₂,
unfold even at h₁ h₂,
cases h₁ with t₁ ht₁,
cases h₂ with t₂ ht₂,
have d_odd : odd d, by {rw odd, use d', exact hd'},
have d_even : even d, by {
have h₁ : (2 * t₁) * (2 * t₂) = 2 * d, by {rw [←ht₁, ←ht₂], exact hdp},
have h₂ : 2 * t₁ * t₂ = d, by linarith,
rw even,
use (t₁ * t₂),
rw ←h₂,
exact mul_assoc 2 t₁ t₂,
},
have d_not_odd : ¬odd d, by {rw ←even_iff_not_odd, exact d_even},
exact d_not_odd d_odd,
},
end