Skip to content

Commit 4b4c1a3

Browse files
committed
1 parent 6948057 commit 4b4c1a3

File tree

1 file changed

+36
-61
lines changed

1 file changed

+36
-61
lines changed

Archive/Wiedijk100Theorems/BallotProblem.lean

Lines changed: 36 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ throughout the count. The probability of this is `(p - q) / (p + q)`.
3333

3434

3535
open Set ProbabilityTheory MeasureTheory
36+
open scoped ENNReal
3637

3738
namespace Ballot
3839

@@ -46,20 +47,23 @@ theorem staysPositive_nil : [] ∈ staysPositive :=
4647
fun _ hl hl₁ => (hl (List.eq_nil_of_suffix_nil hl₁)).elim
4748
#align ballot.stays_positive_nil Ballot.staysPositive_nil
4849

50+
theorem staysPositive_suffix {l₁ l₂ : List ℤ} (hl₂ : l₂ ∈ staysPositive) (h : l₁ <:+ l₂) :
51+
l₁ ∈ staysPositive := fun l hne hl ↦ hl₂ l hne <| hl.trans h
52+
53+
theorem staysPositive_cons {x : ℤ} {l : List ℤ} :
54+
x::l ∈ staysPositive ↔ l ∈ staysPositive ∧ 0 < x + l.sum := by
55+
simp [staysPositive, List.suffix_cons_iff, or_imp, forall_and, @imp.swap _ (_ = _), and_comm]
56+
57+
theorem sum_nonneg_of_staysPositive : ∀ {l : List ℤ}, l ∈ staysPositive → 0 ≤ l.sum
58+
| [], _ => le_rfl
59+
| (_::_), h => (h _ (List.cons_ne_nil _ _) (List.suffix_refl _)).le
60+
4961
theorem staysPositive_cons_pos (x : ℤ) (hx : 0 < x) (l : List ℤ) :
5062
(x::l) ∈ staysPositive ↔ l ∈ staysPositive := by
51-
constructor
52-
· intro hl l₁ hl₁ hl₂
53-
apply hl l₁ hl₁ (hl₂.trans (List.suffix_cons _ _))
54-
· intro hl l₁ hl₁ hl₂
55-
rw [List.suffix_cons_iff] at hl₂
56-
rcases hl₂ with (rfl | hl₂)
57-
· rw [List.sum_cons]
58-
apply add_pos_of_pos_of_nonneg hx
59-
cases' l with hd tl
60-
· simp
61-
· apply le_of_lt (hl (hd::tl) (List.cons_ne_nil hd tl) (hd::tl).suffix_refl)
62-
· apply hl _ hl₁ hl₂
63+
rw [staysPositive_cons, and_iff_left_iff_imp]
64+
intro h
65+
have := sum_nonneg_of_staysPositive h
66+
positivity
6367
#align ballot.stays_positive_cons_pos Ballot.staysPositive_cons_pos
6468

6569
/-- `countedSequence p q` is the set of lists of integers for which every element is `+1` or `-1`,
@@ -262,16 +266,13 @@ theorem headI_mem_of_nonempty {α : Type*} [Inhabited α] : ∀ {l : List α} (_
262266

263267
theorem first_vote_neg (p q : ℕ) (h : 0 < p + q) :
264268
condCount (countedSequence p q) {l | l.headI = 1}ᶜ = q / (p + q) := by
269+
have h' : (p + q : ℝ≥0∞) ≠ 0 := mod_cast h.ne'
265270
have := condCount_compl
266271
{l : List ℤ | l.headI = 1}ᶜ (countedSequence_finite p q) (countedSequence_nonempty p q)
267272
rw [compl_compl, first_vote_pos _ _ h] at this
268-
rw [(_ : (q / (p + q) : ENNReal) = 1 - p / (p + q)), ← this, ENNReal.add_sub_cancel_right]
269-
· simp only [Ne.def, ENNReal.div_eq_top, Nat.cast_eq_zero, add_eq_zero_iff, ENNReal.nat_ne_top,
270-
false_and_iff, or_false_iff, not_and]
271-
intros
272-
contradiction
273-
rw [eq_comm, ENNReal.eq_div_iff, ENNReal.mul_sub, ENNReal.mul_div_cancel']
274-
all_goals simp; try rintro rfl; rw [zero_add] at h; exact h.ne.symm
273+
rw [← ENNReal.sub_eq_of_add_eq _ this, ENNReal.eq_div_iff, ENNReal.mul_sub, mul_one,
274+
ENNReal.mul_div_cancel', ENNReal.add_sub_cancel_left]
275+
all_goals simp_all [ENNReal.div_eq_top]
275276
#align ballot.first_vote_neg Ballot.first_vote_neg
276277

277278
theorem ballot_same (p : ℕ) : condCount (countedSequence (p + 1) (p + 1)) staysPositive = 0 := by
@@ -286,13 +287,10 @@ theorem ballot_same (p : ℕ) : condCount (countedSequence (p + 1) (p + 1)) stay
286287

287288
theorem ballot_edge (p : ℕ) : condCount (countedSequence (p + 1) 0) staysPositive = 1 := by
288289
rw [counted_right_zero]
289-
refine' condCount_eq_one_of (finite_singleton _) (singleton_nonempty _) _
290-
· intro l hl
291-
rw [mem_singleton_iff] at hl
292-
subst hl
293-
refine' fun l hl₁ hl₂ => List.sum_pos _ (fun x hx => _) hl₁
294-
rw [List.eq_of_mem_replicate (List.mem_of_mem_suffix hx hl₂)]
295-
norm_num
290+
refine condCount_eq_one_of (finite_singleton _) (singleton_nonempty _) ?_
291+
refine singleton_subset_iff.2 fun l hl₁ hl₂ => List.sum_pos _ (fun x hx => ?_) hl₁
292+
rw [List.eq_of_mem_replicate (List.mem_of_mem_suffix hx hl₂)]
293+
norm_num
296294
#align ballot.ballot_edge Ballot.ballot_edge
297295

298296
theorem countedSequence_int_pos_counted_succ_succ (p q : ℕ) :
@@ -313,24 +311,12 @@ theorem ballot_pos (p q : ℕ) :
313311
rw [countedSequence_int_pos_counted_succ_succ, condCount, condCount,
314312
cond_apply _ list_int_measurableSet, cond_apply _ list_int_measurableSet,
315313
count_injective_image List.cons_injective]
316-
all_goals try infer_instance
317314
congr 1
318-
have :
319-
(countedSequence p (q + 1)).image (List.cons 1) ∩ staysPositive =
320-
(countedSequence p (q + 1) ∩ staysPositive).image (List.cons 1) := by
321-
ext t
322-
simp only [mem_inter_iff, mem_image]
323-
constructor
324-
· simp only [and_imp, exists_imp]
325-
rintro l hl rfl t
326-
refine' ⟨l, ⟨hl, _⟩, rfl⟩
327-
rwa [staysPositive_cons_pos] at t
328-
norm_num
329-
· simp only [and_imp, exists_imp]
330-
rintro l hl₁ hl₂ rfl
331-
refine' ⟨⟨_, hl₁, rfl⟩, _⟩
332-
rwa [staysPositive_cons_pos]
333-
norm_num
315+
have : (1 :: ·) '' countedSequence p (q + 1) ∩ staysPositive =
316+
(1 :: ·) '' (countedSequence p (q + 1) ∩ staysPositive) := by
317+
simp only [image_inter List.cons_injective, Set.ext_iff, mem_inter_iff, and_congr_right_iff,
318+
ball_image_iff, List.cons_injective.mem_set_image, staysPositive_cons_pos _ one_pos]
319+
exact fun _ _ ↦ trivial
334320
rw [this, count_injective_image]
335321
exact List.cons_injective
336322
#align ballot.ballot_pos Ballot.ballot_pos
@@ -354,24 +340,13 @@ theorem ballot_neg (p q : ℕ) (qp : q < p) :
354340
rw [countedSequence_int_neg_counted_succ_succ, condCount, condCount,
355341
cond_apply _ list_int_measurableSet, cond_apply _ list_int_measurableSet,
356342
count_injective_image List.cons_injective]
357-
all_goals try infer_instance
358343
congr 1
359-
have :
360-
(countedSequence (p + 1) q).image (List.cons (-1)) ∩ staysPositive =
361-
(countedSequence (p + 1) q ∩ staysPositive).image (List.cons (-1)) := by
362-
ext t
363-
simp only [mem_inter_iff, mem_image]
364-
constructor
365-
· simp only [and_imp, exists_imp]
366-
rintro l hl rfl t
367-
exact ⟨_, ⟨hl, fun l₁ hl₁ hl₂ => t l₁ hl₁ (hl₂.trans (List.suffix_cons _ _))⟩, rfl⟩
368-
· simp only [and_imp, exists_imp]
369-
rintro l hl₁ hl₂ rfl
370-
refine' ⟨⟨l, hl₁, rfl⟩, fun l₁ hl₃ hl₄ => _⟩
371-
rw [List.suffix_cons_iff] at hl₄
372-
rcases hl₄ with (rfl | hl₄)
373-
· simp [List.sum_cons, sum_of_mem_countedSequence hl₁, sub_eq_add_neg, ← add_assoc, qp]
374-
exact hl₂ _ hl₃ hl₄
344+
have : List.cons (-1) '' countedSequence (p + 1) q ∩ staysPositive =
345+
List.cons (-1) '' (countedSequence (p + 1) q ∩ staysPositive) := by
346+
simp only [image_inter List.cons_injective, Set.ext_iff, mem_inter_iff, and_congr_right_iff,
347+
ball_image_iff, List.cons_injective.mem_set_image, staysPositive_cons, and_iff_left_iff_imp]
348+
intro l hl _
349+
simp [sum_of_mem_countedSequence hl, lt_sub_iff_add_lt', qp]
375350
rw [this, count_injective_image]
376351
exact List.cons_injective
377352
#align ballot.ballot_neg Ballot.ballot_neg
@@ -426,7 +401,7 @@ theorem ballot_problem :
426401
condCount_isProbabilityMeasure (countedSequence_finite p q) (countedSequence_nonempty _ _)
427402
have :
428403
(condCount (countedSequence p q) staysPositive).toReal =
429-
((p - q) / (p + q) : ENNReal).toReal := by
404+
((p - q) / (p + q) : ℝ≥0).toReal := by
430405
rw [ballot_problem' q p qp]
431406
rw [ENNReal.toReal_div, ← Nat.cast_add, ← Nat.cast_add, ENNReal.toReal_nat,
432407
ENNReal.toReal_sub_of_le, ENNReal.toReal_nat, ENNReal.toReal_nat]

0 commit comments

Comments
 (0)