Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 53d97e1

Browse files
puzzle(archive/oxford_invariants): Oxford Invariants Puzzle Challenges, Summer 2021, Week 3, Problem 1 (#8656)
This is a formalisation of a problem posed by the Oxford Invariants. Co-authored by @b-mehta Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>
1 parent 55b2e86 commit 53d97e1

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/-
2+
Copyright (c) 2021 Yaël Dillies, Bhavik Mehta. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yaël Dillies, Bhavik Mehta
5+
-/
6+
import algebra.big_operators.order
7+
import algebra.big_operators.ring
8+
9+
/-!
10+
# The Oxford Invariants Puzzle Challenges - Summer 2021, Week 3, Problem 1
11+
12+
## Original statement
13+
14+
Let `n ≥ 3`, `a₁, ..., aₙ` be strictly positive integers such that `aᵢ ∣ aᵢ₋₁ + aᵢ₊₁` for
15+
`i = 2, ..., n - 1`. Show that $\sum_{i=1}^{n-1}\dfrac{a_0a_n}{a_ia_{i+1}} ∈ \mathbb N$.
16+
17+
## Comments
18+
19+
Mathlib is based on type theory, so saying that a rational is a natural doesn't make sense. Instead,
20+
we ask that there exists `b : ℕ` whose cast to `α` is the sum we want.
21+
22+
In mathlib, `ℕ` starts at `0`. To make the indexing cleaner, we use `a₀, ..., aₙ₋₁` instead of
23+
`a₁, ..., aₙ`. Similarly, it's nicer to not use substraction of naturals, so we replace
24+
`aᵢ ∣ aᵢ₋₁ + aᵢ₊₁` by `aᵢ₊₁ ∣ aᵢ + aᵢ₊₂`.
25+
26+
We don't actually have to work in `ℚ` or `ℝ`. We can be even more general by stating the result for
27+
any linearly ordered field.
28+
29+
Instead of having `n` naturals, we use a function `a : ℕ → ℕ`.
30+
31+
In the proof itself, we replace `n : ℕ, 1 ≤ n` by `n + 1`.
32+
33+
The statement is actually true for `n = 0, 1` (`n = 1, 2` before the reindexing) as the sum is
34+
simply `0` and `1` respectively. So the version we prove is slightly more general.
35+
36+
Overall, the indexing is a bit of a mess to understand. But, trust Lean, it works.
37+
38+
## Formalised statement
39+
40+
Let `n : ℕ`, `a : ℕ → ℕ`, `∀ i ≤ n, 0 < a i`, `∀ i, i + 2 ≤ n → aᵢ₊₁ ∣ aᵢ + aᵢ₊₂` (read `→` as
41+
"implies"). Then there exists `b : ℕ` such that `b` as an element of any linearly ordered field
42+
equals $\sum_{i=0}^{n-1} (a_0 a_n) / (a_i a_{i+1})$.
43+
44+
## Proof outline
45+
46+
The case `n = 0` is trivial.
47+
48+
For `n + 1`, we prove the result by induction but by adding `aₙ₊₁ ∣ aₙ * b - a₀` to the induction
49+
hypothesis, where `b` is the previous sum, $\sum_{i=0}^{n-1} (a_0 a_n) / (a_i a_{i+1})$, as a
50+
natural.
51+
* Base case:
52+
* $\sum_{i=0}^0 (a_0 a_{0+1}) / (a_0 a_{0+1})$ is a natural:
53+
$\sum_{i=0}^0 (a_0 a_{0+1}) / (a_0 a_{0+1}) = (a_0 a_1) / (a_0 a_1) = 1$.
54+
* Divisibility condition:
55+
`a₀ * 1 - a₀ = 0` is clearly divisible by `a₁`.
56+
* Induction step:
57+
* $\sum_{i=0}^n (a_0 a_{n+1}) / (a_i a_{i+1})$ is a natural:
58+
$$\sum_{i=0}^{n+1} (a_0 a_{n+2}) / (a_i a_{i+1})
59+
= \sum_{i=0}^n\ (a_0 a_{n+2}) / (a_i a_{i+1}) + (a_0 a_{n+2}) / (a_{n+1} a_{n+2})
60+
= a_{n+2} / a_{n+1} × \sum_{i=0}^n (a_0 a_{n+1}) / (a_i a_{i+1}) + a_0 / a_{n+1}
61+
= a_{n+2} / a_{n+1} × b + a_0 / a_{n+1}
62+
= (a_n + a_{n+2}) / a_{n+1} × b - (a_n b - a_0)(a_{n+1})$$
63+
which is a natural because `(aₙ + aₙ₊₂)/aₙ₊₁`, `b` and `(aₙ * b - a₀)/aₙ₊₁` are (plus an
64+
annoying inequality, or the fact that the original sum is positive because its terms are).
65+
* Divisibility condition:
66+
`aₙ₊₁ * ((aₙ + aₙ₊₂)/aₙ₊₁ * b - (aₙ * b - a₀)/aₙ₊₁) - a₀ = aₙ₊₁aₙ₊₂b` is divisible by `aₙ₊₂`.
67+
-/
68+
69+
open_locale big_operators
70+
71+
variables {α : Type*} [linear_ordered_field α]
72+
73+
theorem week3_p1 (n : ℕ) (a : ℕ → ℕ) (a_pos : ∀ i ≤ n, 0 < a i)
74+
(ha : ∀ i, i + 2 ≤ n → a (i + 1) ∣ a i + a (i + 2)) :
75+
∃ b : ℕ, (b : α) = ∑ i in finset.range n, (a 0 * a n)/(a i * a (i + 1)) :=
76+
begin
77+
-- Treat separately `n = 0` and `n ≥ 1`
78+
cases n,
79+
/- Case `n = 0`
80+
The sum is trivially equal to `0` -/
81+
{ exact ⟨0, by rw [nat.cast_zero, finset.sum_range_zero]⟩ }, -- `⟨Claim it, Prove it⟩`
82+
/- Case `n ≥ 1`. We replace `n` by `n + 1` everywhere to make this inequality explicit
83+
Set up the stronger induction hypothesis -/
84+
suffices h : ∃ b : ℕ, (b : α) = ∑ i in finset.range (n + 1), (a 0 * a (n + 1))/(a i * a (i + 1))
85+
∧ a (n + 1) ∣ a n * b - a 0,
86+
{ obtain ⟨b, hb, -⟩ := h,
87+
exact ⟨b, hb⟩ },
88+
simp_rw ←@nat.cast_pos α at a_pos,
89+
/- Declare the induction
90+
`ih` will be the induction hypothesis -/
91+
induction n with n ih,
92+
/- Base case
93+
Claim that the sum equals `1`-/
94+
{ refine ⟨1, _, _⟩,
95+
-- Check that this indeed equals the sum
96+
{ rw [nat.cast_one, finset.sum_range_one, div_self],
97+
exact (mul_pos (a_pos 0 (nat.zero_le _)) (a_pos 1 (nat.zero_lt_succ _))).ne' },
98+
-- Check the divisibility condition
99+
{ rw [mul_one, nat.sub_self],
100+
exact dvd_zero _ } },
101+
/- Induction step
102+
`b` is the value of the previous sum as a natural, `hb` is the proof that it is indeed the value,
103+
and `han` is the divisibility condition -/
104+
obtain ⟨b, hb, han⟩ := ih (λ i hi, ha i $ nat.le_succ_of_le hi)
105+
(λ i hi, a_pos i $ nat.le_succ_of_le hi),
106+
specialize ha n le_rfl,
107+
have ha₀ : a 0 ≤ a n * b, -- Needing this is an artifact of `ℕ`-substraction.
108+
{ rw [←@nat.cast_le α, nat.cast_mul, hb, ←div_le_iff' (a_pos _ $ n.le_succ.trans $ nat.le_succ _),
109+
←mul_div_mul_right _ _ (a_pos _ $ nat.le_succ _).ne'],
110+
suffices h : ∀ i, i ∈ finset.range (n + 1) → 0 ≤ (a 0 : α) * a (n + 1) / (a i * a (i + 1)),
111+
{ exact finset.single_le_sum h (finset.self_mem_range_succ n) },
112+
refine (λ i _, div_nonneg _ _); refine mul_nonneg _ _; exact nat.cast_nonneg _ },
113+
-- Claim that the sum equals `(aₙ + aₙ₊₂)/aₙ₊₁ * b - (aₙ * b - a₀)/aₙ₊₁`
114+
refine ⟨(a n + a (n + 2))/ a (n + 1) * b - (a n * b - a 0) / a (n + 1), _, _⟩,
115+
-- Check that this indeed equals the sum
116+
{ calc
117+
(((a n + a (n + 2)) / a (n + 1) * b - (a n * b - a 0) / a (n + 1) : ℕ) : α)
118+
= (a n + a (n + 2)) / a (n + 1) * b - (a n * b - a 0) / a (n + 1) : begin
119+
norm_cast,
120+
rw nat.cast_sub (nat.div_le_of_le_mul _),
121+
rw [←mul_assoc, nat.mul_div_cancel' ha, add_mul],
122+
exact (nat.sub_le_self _ _).trans (nat.le_add_right _ _),
123+
end
124+
... = a (n + 2) / a (n + 1) * b + (a 0 * a (n + 2)) / (a (n + 1) * a (n + 2))
125+
: by rw [add_div, add_mul, sub_div, mul_div_right_comm, add_sub_sub_cancel,
126+
mul_div_mul_right _ _ (a_pos _ le_rfl).ne']
127+
... = ∑ (i : ℕ) in finset.range (n + 2), a 0 * a (n + 2) / (a i * a (i + 1))
128+
: begin
129+
rw [finset.sum_range_succ, hb, finset.mul_sum],
130+
congr, ext i,
131+
rw [←mul_div_assoc, ←mul_div_right_comm, mul_div_assoc, mul_div_cancel _
132+
(a_pos _ $ nat.le_succ _).ne', mul_comm],
133+
end },
134+
-- Check the divisibility condition
135+
{ rw [nat.mul_sub_left_distrib, ← mul_assoc, nat.mul_div_cancel' ha, add_mul,
136+
nat.mul_div_cancel' han, nat.add_sub_sub_cancel ha₀, nat.add_sub_cancel],
137+
exact dvd_mul_right _ _ }
138+
end

0 commit comments

Comments
 (0)