File: Mathlib/Algebra/ContinuedFractions/ConvergentsEquiv.lean

full_name: GenContFract.squashSeq
code: /-- Given a sequence of `GenContFract.Pair`s `s = [(a₀, bₒ), (a₁, b₁), ...]`, `squashSeq s n`
combines `⟨aₙ, bₙ⟩` and `⟨aₙ₊₁, bₙ₊₁⟩` at position `n` to `⟨aₙ, bₙ + aₙ₊₁ / bₙ₊₁⟩`. For example,
`squashSeq s 0 = [(a₀, bₒ + a₁ / b₁), (a₁, b₁),...]`.
If `s.TerminatedAt (n + 1)`, then `squashSeq s n = s`.
-/
def squashSeq (s : Stream'.Seq <| Pair K) (n : ℕ) : Stream'.Seq (Pair K) 
goal: Stream'.Seq (GenContFract.Pair K)

full_name: GenContFract.squashSeq_eq_self_of_terminated
code: /-- If the sequence already terminated at position `n + 1`, nothing gets squashed. -/
theorem squashSeq_eq_self_of_terminated (terminatedAt_succ_n : s.TerminatedAt (n + 1)) :
    squashSeq s n = s 
goal: GenContFract.squashSeq s n = s

full_name: GenContFract.squashSeq_nth_of_not_terminated
code: /-- If the sequence has not terminated before position `n + 1`, the value at `n + 1` gets
squashed into position `n`. -/
theorem squashSeq_nth_of_not_terminated {gp_n gp_succ_n : Pair K} (s_nth_eq : s.get? n = some gp_n)
    (s_succ_nth_eq : s.get? (n + 1) = some gp_succ_n) :
    (squashSeq s n).get? n = some ⟨gp_n.a, gp_n.b + gp_succ_n.a / gp_succ_n.b⟩ 
goal: (GenContFract.squashSeq s n).get? n = some { a := gp_n.a, b := gp_n.b + gp_succ_n.a / gp_succ_n.b }

full_name: GenContFract.squashSeq_nth_of_lt
code: /-- The values before the squashed position stay the same. -/
theorem squashSeq_nth_of_lt {m : ℕ} (m_lt_n : m < n) : (squashSeq s n).get? m = s.get? m 
goal: (GenContFract.squashSeq s n).get? m = s.get? m

full_name: GenContFract.squashSeq_succ_n_tail_eq_squashSeq_tail_n
code: /-- Squashing at position `n + 1` and taking the tail is the same as squashing the tail of the
sequence at position `n`. -/
theorem squashSeq_succ_n_tail_eq_squashSeq_tail_n :
    (squashSeq s (n + 1)).tail = squashSeq s.tail n 
goal: (GenContFract.squashSeq s (n + 1)).tail = GenContFract.squashSeq s.tail n

full_name: GenContFract.succ_succ_nth_conv'Aux_eq_succ_nth_conv'Aux_squashSeq
code: /-- The auxiliary function `convs'Aux` returns the same value for a sequence and the
corresponding squashed sequence at the squashed position. -/
theorem succ_succ_nth_conv'Aux_eq_succ_nth_conv'Aux_squashSeq :
    convs'Aux s (n + 2) = convs'Aux (squashSeq s n) (n + 1) 
goal: GenContFract.convs'Aux s (n + 2) = GenContFract.convs'Aux (GenContFract.squashSeq s n) (n + 1)

full_name: GenContFract.squashGCF
code: /-- Given a gcf `g = [h; (a₀, bₒ), (a₁, b₁), ...]`, we have
- `squashGCF g 0 = [h + a₀ / b₀); (a₀, bₒ), ...]`,
- `squashGCF g (n + 1) = ⟨g.h, squashSeq g.s n⟩`
-/
def squashGCF (g : GenContFract K) : ℕ → GenContFract K
  
goal: ℕ → GenContFract K

full_name: GenContFract.squashGCF_eq_self_of_terminated
code: /-- If the gcf already terminated at position `n`, nothing gets squashed. -/
theorem squashGCF_eq_self_of_terminated (terminatedAt_n : TerminatedAt g n) :
    squashGCF g n = g 
goal: g.squashGCF n = g

full_name: GenContFract.squashGCF_nth_of_lt
code: /-- The values before the squashed position stay the same. -/
theorem squashGCF_nth_of_lt {m : ℕ} (m_lt_n : m < n) :
    (squashGCF g (n + 1)).s.get? m = g.s.get? m 
goal: (g.squashGCF (n + 1)).s.get? m = g.s.get? m

full_name: GenContFract.succ_nth_conv'_eq_squashGCF_nth_conv'
code: /-- `convs'` returns the same value for a gcf and the corresponding squashed gcf at the
squashed position. -/
theorem succ_nth_conv'_eq_squashGCF_nth_conv' :
    g.convs' (n + 1) = (squashGCF g n).convs' n 
goal: g.convs' (n + 1) = (g.squashGCF n).convs' n

full_name: GenContFract.contsAux_eq_contsAux_squashGCF_of_le
code: /-- The auxiliary continuants before the squashed position stay the same. -/
theorem contsAux_eq_contsAux_squashGCF_of_le {m : ℕ} :
    m ≤ n → contsAux g m = (squashGCF g n).contsAux m 
goal: m ≤ n → g.contsAux m = (g.squashGCF n).contsAux m

full_name: GenContFract.succ_nth_conv_eq_squashGCF_nth_conv
code: /-- The convergents coincide in the expected way at the squashed position if the partial denominator
at the squashed position is not zero. -/
theorem succ_nth_conv_eq_squashGCF_nth_conv [Field K]
    (nth_partDen_ne_zero : ∀ {b : K}, g.partDens.get? n = some b → b ≠ 0) :
    g.convs (n + 1) = (squashGCF g n).convs n 
goal: g.convs (n + 1) = (g.squashGCF n).convs n

full_name: GenContFract.convs_eq_convs'
code: /-- Shows that the recurrence relation (`convs`) and direct evaluation (`convs'`) of the
generalized continued fraction coincide at position `n` if the sequence of fractions contains
strictly positive values only.
Requiring positivity of all values is just one possible condition to obtain this result.
For example, the dual - sequences with strictly negative values only - would also work.

In practice, one most commonly deals with regular continued fractions, which satisfy the
positivity criterion required here. The analogous result for them
(see `ContFract.convs_eq_convs`) hence follows directly from this theorem.
-/
theorem convs_eq_convs' [LinearOrderedField K]
    (s_pos : ∀ {gp : Pair K} {m : ℕ}, m < n → g.s.get? m = some gp → 0 < gp.a ∧ 0 < gp.b) :
    g.convs n = g.convs' n 
goal: g.convs n = g.convs' n

full_name: ContFract.convs_eq_convs'
code: /-- Shows that the recurrence relation (`convs`) and direct evaluation (`convs'`) of a
(regular) continued fraction coincide. -/
nonrec theorem convs_eq_convs' [LinearOrderedField K] {c : ContFract K} :
    (↑c : GenContFract K).convs = (↑c : GenContFract K).convs' 
goal: (↑↑c).convs = (↑↑c).convs'