Zulip Chat Archive

Stream: new members

Topic: Splitting a sum / series convergence


Nathan (Jan 05 2026 at 02:23):

I'm having trouble with these sorrys.

  • I have a sum over Finset 1 k and I just need to break out the k'th term.
  • Is there a theorem in mathlib I can use to show that b_k is eventually constant since it's bounded below and nonincreasing?
import Mathlib

theorem USAMO_2007_1 (n : ) (hn : n > 0) (a :   ) (ha₁ : a 1 = n)
    (ha₂ :  k, k > 1  0  a k  a k  k - 1  k   i : Finset.Icc 1 k, a i) :
     N l,  k, k > N  a k = l := by
  have ha₃ :  k : , k > 0  0  a k  k   i : Finset.Icc 1 k, a i := by
    intro k kh
    by_cases ko : k = 1
    · simp[ko, ha₁]; grind
    replace ko : k > 1 := by grind
    let t := ha₂ k ko; exact t.left, t.right.right
  replace ha₂ :  k, k > 1  a k  k - 1 := by
    intro k kh; exact (ha₂ k kh).right.left
  let b := fun k :  => ( i : Finset.Icc 1 k, a i) / k
  have hb :  k, k > 0  k * b k =  i : Finset.Icc 1 k, a i := by
    intro k kh; unfold b
    let ⟨_, j, jh⟩⟩ := ha₃ k kh
    rw[jh]; simp; by_cases c : k = 0
    · right; assumption
    · left; simp[c]

  have b_bound :  k, k > 0  0 < b k := by
    intro k kh; unfold b
    suffices suff : 0 < ( i : Finset.Icc 1 k, a i) from by
      let ⟨_, j, jh⟩⟩ := ha₃ k kh
      rw[jh] at suff
      exact calc
        0 < j := by
          rcases (pos_and_pos_or_neg_and_neg_of_mul_pos suff) with c1 | c2
          · exact c1.right
          · exfalso; grind
        _ = ( i : Finset.Icc 1 k, a i) / k := by
          rw[jh]
          refine Int.eq_ediv_of_mul_eq_right ?_ rfl
          exact Ne.symm (Int.ne_of_lt kh)
    refine Finset.sum_pos' ?_ ?_
    · intro i ih
      have := (Finset.mem_Icc.mp i.prop).left
      exact (ha₃ i this).left
    · have : 1  Finset.Icc 1 k := by simp; grind
      exists 1, this
      simp[ha₁, hn]
  have b_noninc :  k, k > 1  b k  b (k - 1) := by
    intro k kh
    have kh₂ : k > 0 := by grind
    have := calc (k-1) * b k
      _ < k * b k := by
        suffices suff : k - 1 < k from by
          refine Int.mul_lt_mul_of_pos_right suff ?_
          refine b_bound k ?_
          grind
        simp
      _ =  i : Finset.Icc 1 k, a i := hb k kh₂
      _ = ( i : Finset.Icc 1 (k-1), a i) + a k := sorry
      _ = (k-1) * b (k-1) + a k := by
        have : k-1 > 0 := by grind
        rw[hb (k-1) this]
      _  (k-1) * b (k-1) + (k - 1) := by simp[Int.add_le_add_left (ha₂ k kh)]
      _ = (k-1) * (b (k-1) + 1) := by linarith
    replace : b k < b (k-1) + 1 := by
      refine (Int.mul_lt_mul_left ?_).mp this
      simp[kh]
    exact (Int.add_le_add_iff_right 1).mp this
  have b_const :  N l,  k, k  N  b k = l := sorry
  let N, l, ch := b_const
  exists (if N  1 then N else 1), l; intro k kh
  exact calc a k
    _ = ( i : Finset.Icc 1 k, a i) - ( i : Finset.Icc 1 (k-1), a i) := sorry
    _ = k * b k - (k-1) * b (k-1) := by
      have : k > 1 := by
        by_cases c : N  1 <;> simp[c] at kh <;> grind
      have kh₁ : k > 0 := by grind
      have kh₂ : k - 1 > 0 := by grind
      rw[hb k kh₁, hb (k-1) kh₂]
    _ = k * l - (k-1) * l := by
      have kh₁ : k  N := by
        by_cases c : N  1 <;> simp[c] at kh <;> grind
      have kh₂ : k - 1  N := by
        by_cases c : N  1 <;> simp[c] at kh <;> grind
      rw[ch k kh₁, ch (k-1) kh₂]
    _ = l := by linarith

David Ledvinka (Jan 05 2026 at 02:42):

Being non-increasing and bounded below implies the sequence converges by monotone convergence (see tendsto_atTop_ciInf) it does not imply the sequence is eventually constant. Consider a_n = 1/n.

Aaron Liu (Jan 05 2026 at 02:57):

well if it's a sequence of integers then it's eventually constant

Aaron Liu (Jan 05 2026 at 02:57):

since the integers are discrete so all convergent sequences are eventually constant

David Ledvinka (Jan 05 2026 at 03:07):

oh my bad I was not paying close enough attention to see that b was a sequence of integers.

David Ledvinka (Jan 05 2026 at 03:18):

That gives you one proof strategy though. As far as I could tell the fact Aaron mentions is missing from mathlib (but should be in it).

Aaron Liu (Jan 05 2026 at 03:19):

here we go

  have b_const :  N l,  k, k  N  b k = l := by
    -- sequence indexed by nat so we can be globally antitone and bounded below
    let f' (n : Nat) : Int := b (n + 1)
    have anti : Antitone f' := antitone_nat_of_succ_le fun n => by
      refine (congrArg₂ (fun u v => b u  b v) ?_ ?_).mpr (b_noninc (n + 2) (by omega))
      · lia
      · lia
    have bdd : BddBelow (Set.range f') := by
      use 0
      intro z hz
      obtain n, rfl := hz
      exact (b_bound (n + 1) (by lia)).le
    -- monotone convergence
    have tendsto := tendsto_atTop_ciInf anti bdd
    rw [nhds_discrete] at tendsto
    have const := Filter.EventuallyConst.of_tendsto tendsto
    rw [Filter.eventuallyConst_atTop] at const
    obtain n, hn := const
    use n + 1, f' n
    intro k hk
    lift k to  using by lia
    obtain k, rfl :  k', k = k' + 1 := Nat.exists_eq_add_one.2 (by lia)
    exact mod_cast hn k (by lia)

Nathan (Jan 05 2026 at 03:28):

thanks, what is lia?

Aaron Liu (Jan 05 2026 at 03:39):

docs#Lean.Parser.Tactic.lia

`lia` solves linear integer arithmetic goals.

It is a implemented as a thin wrapper around the `grind` tactic, enabling only the `lia` solver.
Please use `grind` instead if you need additional capabilities.

Nathan (Jan 05 2026 at 06:03):

what about the sums? I can't seem to figure out how to do it

Nathan (Jan 05 2026 at 07:03):

ah nevermind, i figured it out


Last updated: Feb 28 2026 at 14:05 UTC