-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.toSeq (L79-L83)
def toSeq {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Seq (ℝ × MultiseriesExpansion basis_tl) :=
ms

/-- The empty multiseries. -/

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.nil (L84-L86)
def nil {basis_hd basis_tl} : Multiseries basis_hd basis_tl := Seq.nil
/-- Prepend a monomial to a multiseries. -/

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_nil (L203-L207)
theorem destruct_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
    destruct (nil : Multiseries basis_hd basis_tl) = none := by
simp [destruct, nil]

set_option backward.isDefEq.respectTransparency false in

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head_nil (L228-L231)
theorem head_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
    (nil : Multiseries basis_hd basis_tl).head = none := by
simp [head, nil]

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.Stream' (L95-L100)
theorem Stream'.dist_le_one (s t : Stream' α) : dist s t ≤ 1 := by
by_cases h : s = t
  · simp [h]
  rw [PiNat.dist_eq_of_ne h]
  bound

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.of_append_right (L56-L59)
theorem of_append_right {left right : Basis} (h : WellFormedBasis (left ++ right)) :
    WellFormedBasis right :=
h.of_sublist (by simp)

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tail (L52-L55)
theorem tail {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h : WellFormedBasis (basis_hd :: basis_tl)) : WellFormedBasis basis_tl :=
h.of_sublist (by simp)

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.single (L44-L46)
theorem single (f : ℝ → ℝ) (hf : Tendsto f atTop atTop) : WellFormedBasis [f] := by
simpa [WellFormedBasis]

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_nil (L157-L160)
theorem dist_cons_nil (x : α) (s : Seq α) : dist (cons x s) nil = 1 := by
apply dist_eq_one_of_head
  simp

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.nil (L42-L43)
theorem nil : WellFormedBasis [] := by simp [WellFormedBasis]

-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsGT_of_tendsto_atTop (L42-L45)
theorem tendsto_nhdsGT_of_tendsto_atTop (h : Tendsto (fun x ↦ f (c + x⁻¹)) atTop l) :
    Tendsto f (𝓝[>] c) l := by
simpa [← Function.comp_def, Tendsto, ← Filter.map_map] using h

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.FriendlyOperationClass (L188-L191)
theorem FriendlyOperationClass.comp (F : γ → Seq α → Seq α) (g : γ' → γ)
    [h : FriendlyOperationClass F] : FriendlyOperationClass (fun c ↦ F (g c)) := by
grind [FriendlyOperationClass]

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.zero (L85-L88)
theorem zero : Majorized 0 b exp :=
fun _ _ ↦ Asymptotics.isLittleO_zero _ _

/-- `c • f` is majorized with the same exponent as `f` for any constant `c`. -/

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_cons_eq_one (L151-L155)
theorem dist_cons_cons_eq_one {x y : α} {s t : Seq α} (h : x ≠ y) :
    dist (cons x s) (cons y t) = 1 := by
apply dist_eq_one_of_head
  simpa

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.WellFormedBasis (L36-L41)
def WellFormedBasis (basis : Basis) : Prop :=
basis.Pairwise (fun x y => (Real.log ∘ y) =o[atTop] (Real.log ∘ x)) ∧
  ∀ f ∈ basis, Tendsto f atTop atTop

namespace WellFormedBasis

-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.getBasis (L177-L182)
def getBasis {basis : Basis} (ex : BasisExtension basis) : Basis :=
match ex with
  | nil => []
  | keep basis_hd ex => basis_hd :: ex.getBasis
  | insert f ex => f :: ex.getBasis

-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigO_of_div_tendsto_atTop (L76-L80)
theorem isBigO_of_div_tendsto_atTop {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atTop) :
    f =O[l] g :=
Asymptotics.IsLittleO.isBigO (.of_tendsto_div_atTop h)

theorem tail_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    (cons exp coef tl).tail = tl

[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
theorem tail_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    (cons exp coef tl).tail = tl
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.Basis (L44-L53)
abbrev Basis := List (ℝ → ℝ)
/-- Multiseries representing a given function `f : ℝ → ℝ`.
`MultiseriesExpansion []` is just `ℝ`: multiseries representing constant functions.
Otherwise it is a pair of a `Multiseries basis_hd basis_tl` and a function `ℝ → ℝ`. We call
the former an expansion of the latter.

Note: most of the theory can be formulated in terms of `Multiseries`, but we need to explicitly
store the approximated function to be able to use the eventual zeroness oracle at the trimming step.
-/
```

-- snippet 2
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.MultiseriesExpansion (L54-L71)
def MultiseriesExpansion (basis : Basis) : Type :=
match basis with
  | [] => ℝ
  | .cons _ basis_tl => Seq (ℝ × MultiseriesExpansion basis_tl) × (ℝ → ℝ)

namespace MultiseriesExpansion

set_option linter.unusedVariables false in
/-- Multiseries in a basis `basis_hd :: basis_tl`. It is a generalisation of asymptotic expansions.
A multiseries in a basis `[b₁, ..., bₙ]` is a formal series made from monomials
`b₁ ^ e₁ * ... * bₙ ^ eₙ` where `e₁, ..., eₙ` are real numbers. We treat multivariate series in
a basis `[b₁, ..., bₙ]` as a univariate series in the variable `b₁` (`basis_hd`) with coefficients
being multiseries in the basis `[b₂, ..., bₙ]` (`basis_tl`). We represent such a series as a lazy
list (`Seq`) of pairs `(exp, coef)` where `exp` is the exponent of `b₁` and `coef` is the
coefficient (a multiseries in `basis_tl`).

`MultiseriesExpansion` is a `Multiseries` with an attached real function.
-/
```

-- snippet 3
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.Multiseries (L73-L78)
def Multiseries (basis_hd : ℝ → ℝ) (basis_tl : Basis) : Type :=
Seq (ℝ × MultiseriesExpansion basis_tl)

namespace Multiseries

/-- Converts a `Multiseries basis_hd basis_tl` to a `Seq (ℝ × MultiseriesExpansion basis_tl)`. -/
```

-- snippet 4
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.toSeq (L79-L83)
def toSeq {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Seq (ℝ × MultiseriesExpansion basis_tl) :=
ms

/-- The empty multiseries. -/
```

-- snippet 5
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.nil (L84-L86)
def nil {basis_hd basis_tl} : Multiseries basis_hd basis_tl := Seq.nil
/-- Prepend a monomial to a multiseries. -/
```

-- snippet 6
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.cons (L87-L93)
def cons {basis_hd basis_tl} (exp : ℝ) (coef : MultiseriesExpansion basis_tl)
    (tl : Multiseries basis_hd basis_tl) :
    Multiseries basis_hd basis_tl :=
Seq.cons (exp, coef) tl

/-- Recursion principle for `Multiseries basis_hd basis_tl`. It is equivalent to
`Stream'.Seq.recOn` but provides some convenience. -/
```

-- snippet 7
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.recOn (L95-L101)
def recOn {basis_hd basis_tl} {motive : Multiseries basis_hd basis_tl → Sort*}
    (ms : Multiseries basis_hd basis_tl) (nil : motive nil)
    (cons : ∀ exp coef (tl : Multiseries basis_hd basis_tl), motive (cons exp coef tl)) :
    motive ms := Stream'.Seq.recOn _ nil fun _ _ ↦ cons _ _ _
/-- Destruct a multiseries into a triple `(exp, coef, tl)`, where `exp` is the leading exponent,
`coef` is the leading coefficient, and `tl` is the tail. -/
```

-- snippet 8
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct (L102-L106)
def destruct {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Option (ℝ × MultiseriesExpansion basis_tl × Multiseries basis_hd basis_tl) :=
(Seq.destruct ms).map (fun ((exp, coef), tl) => (exp, coef, tl))

/-- The head of a multiseries, i.e. the first two entries of the tuple returned by `destruct`. -/
```

-- snippet 9
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head (L107-L111)
def head {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Option (ℝ × MultiseriesExpansion basis_tl) :=
Seq.head ms

/-- The tail of a multiseries, i.e. the last entry of the tuple returned by `destruct`. -/
```

-- snippet 10
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.tail (L112-L117)
def tail {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) : Multiseries basis_hd basis_tl :=
Seq.tail ms

/-- Given two functions `f : ℝ → ℝ` and
`g : MultiseriesExpansion basis_tl → MultiseriesExpansion basis_tl'`, apply them to exponents and
coefficients of a multiseries. -/
```

-- snippet 11
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.map (L118-L124)
def map {basis_hd basis_tl basis_hd' basis_tl'} (f : ℝ → ℝ)
    (g : MultiseriesExpansion basis_tl → MultiseriesExpansion basis_tl')
    (ms : Multiseries basis_hd basis_tl) :
    Multiseries basis_hd' basis_tl' :=
Seq.map (fun (exp, coef) ↦ (f exp, g coef)) ms

/-- Corecursor for `Multiseries basis_hd basis_tl`. -/
```

-- snippet 12
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.corec (L125-L136)
def corec {β : Type*} {basis_hd} {basis_tl}
    (f : β → Option (ℝ × MultiseriesExpansion basis_tl × β)) (b : β) :
    Multiseries basis_hd basis_tl :=
Seq.corec (fun a => (f a).map (fun (exp, coef, next) => ((exp, coef), next))) b

private lemma destruct_eq_destruct_map {basis_hd basis_tl}
    (s : Stream'.Seq (ℝ × MultiseriesExpansion basis_tl)) :
    s.destruct = (Multiseries.destruct (basis_hd := basis_hd) s).map
      (fun (exp, coef, tl) => ((exp, coef), tl)) := by
  simp only [destruct, Option.map_map]
  exact Option.map_id_apply.symm
```

-- snippet 13
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.eq_of_bisim (L144-L151)
theorem eq_of_bisim {basis_hd : ℝ → ℝ} {basis_tl : Basis} {x y : Multiseries basis_hd basis_tl}
    (motive : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl → Prop)
    (base : motive x y)
    (step : ∀ x y, motive x y → (x = .nil ∧ y = .nil) ∨ ∃ exp coef,
      ∃ (x' y' : Multiseries basis_hd basis_tl),
      x = cons exp coef x' ∧ y = cons exp coef y' ∧ motive x' y') :
    x = y := Seq.eq_of_bisim' motive base (by grind [nil, cons])
```

-- snippet 14
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.eq_of_bisim_strong (L152-L162)
theorem eq_of_bisim_strong {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    {x y : Multiseries basis_hd basis_tl}
    (motive : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl → Prop)
    (base : motive x y)
    (step : ∀ x y, motive x y → (x = y) ∨ ∃ exp coef,
      ∃ (x' y' : Multiseries basis_hd basis_tl),
      x = cons exp coef x' ∧ y = cons exp coef y' ∧ motive x' y') :
    x = y := Seq.eq_of_bisim_strong motive base (by grind [nil, cons])
section simp
```

-- snippet 15
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.cons_ne_nil (L164-L171)
theorem cons_ne_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    cons exp coef tl ≠ .nil := by
intro h
  simp only [cons, nil] at h
  apply Seq.cons_ne_nil h
```

-- snippet 16
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.nil_ne_cons (L173-L178)
theorem nil_ne_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    .nil ≠ cons exp coef tl := cons_ne_nil.symm
set_option backward.isDefEq.respectTransparency false in
```

-- snippet 17
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.cons_eq_cons (L180-L185)
theorem cons_eq_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp1 exp2 : ℝ}
    {coef1 coef2 : MultiseriesExpansion basis_tl} {tl1 tl2 : Multiseries basis_hd basis_tl} :
    cons exp1 coef1 tl1 = cons exp2 coef2 tl2 ↔ exp1 = exp2 ∧ coef1 = coef2 ∧ tl1 = tl2 := by
rw [cons, cons, Seq.cons_eq_cons]
  grind
```

-- snippet 18
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.corec_nil (L186-L192)
theorem corec_nil {β : Type*} {basis_hd} {basis_tl}
    {f : β → Option (ℝ × MultiseriesExpansion basis_tl × β)} {b : β} (h : f b = none) :
    corec f b = (nil : Multiseries basis_hd basis_tl) := by
simp only [corec, nil]
  rw [Seq.corec_nil]
  simpa
```

-- snippet 19
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.corec_cons (L193-L201)
theorem corec_cons {β : Type*} {basis_hd} {basis_tl} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl} {next : β}
    {f : β → Option (ℝ × MultiseriesExpansion basis_tl × β)} {b : β}
    (h : f b = some (exp, coef, next)) :
    (corec f b : Multiseries basis_hd basis_tl) = cons exp coef (corec f next) := by
simp only [corec, cons]
  rw [Seq.corec_cons]
  simpa
```

-- snippet 20
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_nil (L203-L207)
theorem destruct_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
    destruct (nil : Multiseries basis_hd basis_tl) = none := by
simp [destruct, nil]

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 21
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_cons (L209-L214)
theorem destruct_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    destruct (cons exp coef tl) = some (exp, coef, tl) := by
simp [destruct, cons]
```

-- snippet 22
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_eq_none (L215-L219)
theorem destruct_eq_none {basis_hd : ℝ → ℝ} {basis_tl : Basis} {ms : Multiseries basis_hd basis_tl}
    (h : destruct ms = none) : ms = nil := by
apply Stream'.Seq.destruct_eq_none
  simpa [destruct] using h
```

-- snippet 23
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_eq_cons (L220-L226)
theorem destruct_eq_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {ms : Multiseries basis_hd basis_tl}
    {exp : ℝ} {coef : MultiseriesExpansion basis_tl} {tl : Multiseries basis_hd basis_tl}
    (h : destruct ms = some (exp, coef, tl)) : ms = cons exp coef tl := by
apply Stream'.Seq.destruct_eq_cons
  simp [destruct] at h
  grind
```

-- snippet 24
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head_nil (L228-L231)
theorem head_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
    (nil : Multiseries basis_hd basis_tl).head = none := by
simp [head, nil]
```

-- snippet 25
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head_cons (L233-L238)
theorem head_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    (cons exp coef tl).head = some (exp, coef) := by
simp [head, cons]
```

-- snippet 26
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.eventually_pos (L128-L137)
theorem eventually_pos {basis : Basis} (h : WellFormedBasis basis) :
    ∀ᶠ x in atTop, ∀ f ∈ basis, 0 < f x := by
induction basis with
  | nil => simp
  | cons hd tl ih =>
    simp only [WellFormedBasis, List.pairwise_cons, List.mem_cons, forall_eq_or_imp] at h
    simp only [List.mem_cons, forall_eq_or_imp]
    exact (h.right.left.eventually <| eventually_gt_atTop 0).and (ih (by tauto))

/-- The first function in a well-formed basis is eventually positive. -/
```

-- snippet 27
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.exists_fixed_point_of_contractible (L207-L218)
theorem exists_fixed_point_of_contractible (F : (β →ᵤ Seq α) → (β →ᵤ Seq α))
    (h : LipschitzWith 2⁻¹ F) :
    ∃ f : β → Seq α, Function.IsFixedPt F f := by
have hF : ContractingWith 2⁻¹ F := by
    constructor
    · norm_num
    · exact h
  let f := hF.fixedPoint _
  use f
  exact hF.fixedPoint_isFixedPt

/-- Main theorem of this file. It shows that there exists a function satisfying the corecursive
```

-- snippet 28
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigOWith_of_tendsto_top (L66-L70)
theorem isBigOWith_of_tendsto_top {C : ℝ} {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atTop) (hC : 0 < C) :
    IsBigOWith C l f g :=
Asymptotics.IsLittleO.forall_isBigOWith (.of_tendsto_div_atTop h) hC
```

-- snippet 29
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_cons (L117-L134)
theorem dist_cons_cons (x : α) (s t : Seq α) : dist (cons x s) (cons x t) = 2⁻¹ * dist s t := by
by_cases! h : s = t
  · simp [h]
  have h' : cons x s ≠ cons x t := by
    simpa
  rw [Subtype.dist_eq, Subtype.dist_eq, PiNat.dist_eq_of_ne (Subtype.coe_ne_coe.mpr h),
    PiNat.dist_eq_of_ne (Subtype.coe_ne_coe.mpr h')]
  simp only [show (1 / 2 : ℝ) = 2⁻¹ by simp, ← pow_succ']
  congr
  simp only [val_cons, PiNat.firstDiff, ne_eq, Classical.dite_not, Subtype.coe_ne_coe.mpr h,
    not_false_eq_true, ↓reduceDIte, val_eq_get]
  split_ifs with h_if
  · contrapose! h'
    apply_fun Subtype.val using Subtype.val_injective
    simpa
  · convert Nat.find_comp_succ _ _ _
    simp [Stream'.cons]
```

-- snippet 30
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.Stream' (L95-L100)
theorem Stream'.dist_le_one (s t : Stream' α) : dist s t ≤ 1 := by
by_cases h : s = t
  · simp [h]
  rw [PiNat.dist_eq_of_ne h]
  bound
```

-- snippet 31
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.of_append_right (L56-L59)
theorem of_append_right {left right : Basis} (h : WellFormedBasis (left ++ right)) :
    WellFormedBasis right :=
h.of_sublist (by simp)
```

-- snippet 32
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.const (L76-L84)
theorem const (h_tendsto : Tendsto b atTop atTop) {c : ℝ} :
    Majorized (fun _ ↦ c) b 0 := by
intro exp h_exp
  apply Asymptotics.isLittleO_const_left.mpr
  right
  apply tendsto_norm_atTop_atTop.comp
  exact (tendsto_rpow_atTop h_exp).comp h_tendsto

/-- The zero function is majorized with any exponent. -/
```

-- snippet 33
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsNE_of_tendsto_atTop (L53-L58)
theorem tendsto_nhdsNE_of_tendsto_atTop (h_neg : Tendsto (fun x ↦ f (c - x⁻¹)) atTop l)
    (h_pos : Tendsto (fun x ↦ f (c + x⁻¹)) atTop l) :
    Tendsto f (𝓝[≠] c) l := by
simpa [Tendsto, ← nhdsLT_sup_nhdsGT] using
    ⟨tendsto_nhdsLT_of_tendsto_atTop _ _ h_neg, tendsto_nhdsGT_of_tendsto_atTop _ _ h_pos⟩
```

-- snippet 34
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.gcorec_some (L286-L294)
theorem gcorec_some {F : β → Option (α × γ × β)} {op : γ → Seq α → Seq α}
    [FriendlyOperationClass op] {b : β}
    {a : α} {c : γ} {b' : β}
    (h : F b = some (a, c, b')) :
    gcorec F op b = Seq.cons a (op c (gcorec F op b')) := by
have := (FriendlyOperation.exists_fixed_point F op).choose_spec b
  simpa [h] using this

end Tactic.ComputeAsymptotics.Seq
```

-- snippet 35
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.foo (L19-L33)
def foo (x : X) := hd x :: foo (tlArg x)
```
(where hd and tlArg are arbitrary functions) can be encoded via the corecursor `Seq.corec`.

It is not enough, however, to define multiplication and `powser` operation for multiseries.

This file implements a more general form of corecursion in the spirit of [blanchette2015].
This is a bare minimum that needed for the tactic, it justifies a weaker class of
corecursive definitions than [blanchette2015] does, and only works for `Seq`.

A function `f : Seq α → Seq α` is called *friendly* if for all `n : ℕ` the `n`-prefix of its result
`f s` depends only on the `n`-prefix of its input `s`.

In this file we develop a theory that justifies corecursive definitions of the form
```
```

-- snippet 36
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tendsto_atTop (L123-L127)
theorem tendsto_atTop {basis : Basis} (h : WellFormedBasis basis) {f : ℝ → ℝ}
    (hf : f ∈ basis) :
    Tendsto f atTop atTop := h.right f hf
/-- Eventually all functions from a well-formed basis are positive. -/
```

-- snippet 37
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.Majorized (L32-L39)
def Majorized (f b : ℝ → ℝ) (exp : ℝ) : Prop :=
∀ exp' > exp, f =o[atTop] (b ^ exp')

namespace Majorized

variable {f g b : ℝ → ℝ} {exp : ℝ}

/-- Replacing the first argument of `Majorized` by an eventually equal function preserves it. -/
```

-- snippet 38
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tail (L52-L55)
theorem tail {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h : WellFormedBasis (basis_hd :: basis_tl)) : WellFormedBasis basis_tl :=
h.of_sublist (by simp)
```

-- snippet 39
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.mul_bounded (L118-L128)
theorem mul_bounded {f g basis_hd : ℝ → ℝ} {exp : ℝ} (hf : Majorized f basis_hd exp)
    (hg : g =O[atTop] (fun _ ↦ (1 : ℝ))) :
    Majorized (f * g) basis_hd exp := by
intro exp h_exp
  convert IsLittleO.mul_isBigO (hf _ h_exp) hg using 1
  simp
  rfl

end Majorized

end Tactic.ComputeAsymptotics
```

-- snippet 40
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_eq_one_of_head (L140-L150)
theorem dist_eq_one_of_head {s t : Seq α} (h : s.head ≠ t.head) : dist s t = 1 := by
rw [Subtype.dist_eq, PiNat.dist_eq_of_ne]
  · convert pow_zero _
    simp only [PiNat.firstDiff, ne_eq, Classical.dite_not, dite_eq_left_iff,
      Nat.find_eq_zero]
    intro h'
    simpa [Stream'.cons]
  · rw [Subtype.coe_ne_coe]
    contrapose! h
    simp [h]
```

-- snippet 41
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.single (L44-L46)
theorem single (f : ℝ → ℝ) (hf : Tendsto f atTop atTop) : WellFormedBasis [f] := by
simpa [WellFormedBasis]
```

-- snippet 42
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigOWith_of_tendsto_bot (L71-L75)
theorem isBigOWith_of_tendsto_bot {C : ℝ} {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atBot) (hC : 0 < C) :
    IsBigOWith C l f g :=
Asymptotics.IsLittleO.forall_isBigOWith (.of_tendsto_div_atBot h) hC
```

-- snippet 43
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsLT_of_tendsto_atTop (L46-L52)
theorem tendsto_nhdsLT_of_tendsto_atTop (h : Tendsto (fun x ↦ f (c - x⁻¹)) atTop l) :
    Tendsto f (𝓝[<] c) l := by
convert_to Tendsto (f ∘ (fun x ↦ c + x) ∘ Neg.neg ∘ Inv.inv) atTop l at h
  · ext
    simp [AddGroupWithOne.sub_eq_add_neg]
  simpa [Tendsto, ← Filter.map_map] using h
```

-- snippet 44
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.mul (L104-L117)
theorem mul {f_exp g_exp : ℝ} (hf : Majorized f b f_exp)
    (hg : Majorized g b g_exp) (h_pos : ∀ᶠ t in atTop, 0 < b t) :
    Majorized (f * g) b (f_exp + g_exp) := by
simp only [Majorized] at *
  intro exp h_exp
  let ε := (exp - f_exp - g_exp) / 2
  specialize hf (f_exp + ε) (by dsimp [ε]; linarith)
  specialize hg (g_exp + ε) (by dsimp [ε]; linarith)
  apply (hf.mul hg).trans_eventuallyEq (g₁ := fun t ↦ b t ^ (f_exp + ε) * b t ^ (g_exp + ε))
  apply h_pos.mono
  intro t hx
  simp only [Pi.pow_apply]
  conv_rhs => rw [show exp = (f_exp + ε) + (g_exp + ε) by dsimp [ε]; ring_nf, Real.rpow_add hx]
```

-- snippet 45
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.of_le (L65-L70)
theorem of_le {exp1 exp2 : ℝ} (h_lt : exp1 ≤ exp2) (h : Majorized f b exp1) :
    Majorized f b exp2 := by
simp only [Majorized] at *
  exact fun exp' h_exp ↦ h _ (by linarith)

/-- If `f` is majorized with a negative exponent, then it tends to zero. -/
```

-- snippet 46
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_le_one (L102-L110)
theorem dist_le_one (s t : Seq α) : dist s t ≤ 1 := PiNat.dist_le_one _ _
local instance : BoundedSpace (Stream' α) :=
  @PiNat.boundedSpace _ (fun _ ↦ ⊥) (fun _ ↦ discreteTopology_bot _)

local instance : BoundedSpace (Seq α) :=
  instBoundedSpaceSubtype

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 47
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.cons (L98-L104)
theorem cons {basis : Basis} {f : ℝ → ℝ} (h_basis : WellFormedBasis basis)
    (hf_tendsto : Tendsto f atTop atTop)
    (hf : ∀ g ∈ basis, (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    WellFormedBasis (f :: basis) := by
change WellFormedBasis ([f] ++ basis)
  exact append (by simpa [WellFormedBasis]) h_basis (by simpa)
```

-- snippet 48
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_nil (L157-L160)
theorem dist_cons_nil (x : α) (s : Seq α) : dist (cons x s) nil = 1 := by
apply dist_eq_one_of_head
  simp
```

-- snippet 49
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tail_isLittleO_head (L143-L148)
theorem tail_isLittleO_head {hd : ℝ → ℝ} {tl : Basis}
    (h : WellFormedBasis (hd :: tl)) {f : ℝ → ℝ} (hf : f ∈ tl) :
    (Real.log ∘ f) =o[atTop] (Real.log ∘ hd) := by
rw [WellFormedBasis, List.pairwise_cons] at h
  exact h.left.left _ hf
```

-- snippet 50
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.nil (L42-L43)
theorem nil : WellFormedBasis [] := by simp [WellFormedBasis]
```

-- snippet 51
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsGT_of_tendsto_atTop (L42-L45)
theorem tendsto_nhdsGT_of_tendsto_atTop (h : Tendsto (fun x ↦ f (c + x⁻¹)) atTop l) :
    Tendsto f (𝓝[>] c) l := by
simpa [← Function.comp_def, Tendsto, ← Filter.map_map] using h
```

-- snippet 52
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsNE_of_tendsto_atTop_nhds_of_eq (L59-L65)
theorem tendsto_nhdsNE_of_tendsto_atTop_nhds_of_eq [TopologicalSpace α] {a b : α}
    (h_neg : Tendsto (fun x ↦ f (c - x⁻¹)) atTop (𝓝 a))
    (h_pos : Tendsto (fun x ↦ f (c + x⁻¹)) atTop (𝓝 b)) (h_eq : a = b) :
    Tendsto f (𝓝[≠] c) (𝓝 a) := by
apply tendsto_nhdsNE_of_tendsto_atTop _ _ h_neg
  convert h_pos
```

-- snippet 53
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.of_eventuallyEq (L40-L46)
theorem of_eventuallyEq (h_eq : g =ᶠ[atTop] f) (h : Majorized f b exp) :
    Majorized g b exp := by
simp only [Majorized] at *
  intro exp' h_exp
  exact EventuallyEq.trans_isLittleO h_eq (h exp' h_exp)

/-- For any function `f` tending to infinity, `f ^ exp` is majorized by `f` with exponent `exp`. -/
```

-- snippet 54
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.FriendlyOperationClass (L188-L191)
theorem FriendlyOperationClass.comp (F : γ → Seq α → Seq α) (g : γ' → γ)
    [h : FriendlyOperationClass F] : FriendlyOperationClass (fun c ↦ F (g c)) := by
grind [FriendlyOperationClass]
```

-- snippet 55
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.zero (L85-L88)
theorem zero : Majorized 0 b exp :=
fun _ _ ↦ Asymptotics.isLittleO_zero _ _

/-- `c • f` is majorized with the same exponent as `f` for any constant `c`. -/
```

-- snippet 56
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_nil_cons (L162-L167)
theorem dist_nil_cons (x : α) (s : Seq α) : dist nil (cons x s) = 1 := by
rw [dist_comm]
  simp

/-- A function on sequences is called a "friend" if any `n`-prefix of its output depends only on
the `n`-prefix of the input. Such functions can be used in the tail of (non-primitive) corecursive
```

-- snippet 57
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.compare_right_aux (L75-L88)
theorem compare_right_aux {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
    (h_comp : ∀ g, basis.head? = .some g → (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    ∀ g ∈ basis, (Real.log ∘ g) =o[atTop] (Real.log ∘ f) := by
intro g hg
  cases basis with
  | nil => simp at hg
  | cons basis_hd basis_tl =>
    specialize h_comp basis_hd (by simp)
    simp only [List.mem_cons] at hg
    rcases hg with hg | hg
    · simpa [hg]
    · simp only [WellFormedBasis, List.pairwise_cons, List.mem_cons, forall_eq_or_imp] at h
      exact .trans (by grind) h_comp
```

-- snippet 58
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.self (L47-L64)
theorem self (h : Tendsto f atTop atTop) :
    Majorized (f ^ exp) f exp := by
simp only [Majorized]
  intro exp' h_exp
  apply (isLittleO_iff_tendsto' _).mpr
  · have : (fun t ↦ f t ^ exp / f t ^ exp') =ᶠ[atTop] fun t ↦ (f t) ^ (exp - exp') :=
      (h.eventually_gt_atTop 0).mono (fun _ h ↦ by simp [← Real.rpow_sub h])
    apply Tendsto.congr' this.symm
    conv =>
      arg 1
      rw [show (fun t ↦ f t ^ (exp - exp')) = ((fun t ↦ t ^ (-(exp' - exp))) ∘ f) by ext; simp]
    exact (tendsto_rpow_neg_atTop (by linarith)).comp h
  · apply (Tendsto.eventually_gt_atTop h 0).mono
    intro t h1 h2
    absurd h2
    exact (Real.rpow_pos_of_pos h1 _).ne.symm

/-- If `f` is majorized with exponent `exp₁`, then it is majorized with any `exp₂ ≥ exp₁`. -/
```

-- snippet 59
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_cons_eq_one (L151-L155)
theorem dist_cons_cons_eq_one {x y : α} {s t : Seq α} (h : x ≠ y) :
    dist (cons x s) (cons y t) = 1 := by
apply dist_eq_one_of_head
  simpa
```

-- snippet 60
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigO_of_div_tendsto_atBot (L81-L86)
theorem isBigO_of_div_tendsto_atBot {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atBot) :
    f =O[l] g :=
Asymptotics.IsLittleO.isBigO (.of_tendsto_div_atBot h)

end Tactic.ComputeAsymptotics
```

-- snippet 61
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.sublist_getBasis (L183-L189)
theorem sublist_getBasis {basis : Basis} {ex : BasisExtension basis} :
    List.Sublist basis ex.getBasis := by
induction ex with
  | nil => simp
  | keep _ ex ih => simpa [getBasis] using ih
  | insert _ ex ih => exact List.Sublist.cons _ ih
```

-- snippet 62
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.insert (L105-L115)
theorem insert {left right : Basis} {f : ℝ → ℝ}
    (h : WellFormedBasis (left ++ right)) (hf_tendsto : Tendsto f atTop atTop)
    (hf_comp_left : ∀ g, left.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g))
    (hf_comp_right : ∀ g, right.head? = .some g → (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    WellFormedBasis (left ++ f :: right) := by
have : WellFormedBasis (f :: right) := cons (h.of_sublist (by simp)) hf_tendsto
    (compare_right_aux (h.of_sublist (by simp)) hf_comp_right)
  apply compare_left_aux (h.of_sublist (by simp)) at hf_comp_left
  apply append (h.of_sublist (by simp)) this
  exact fun g hg ↦ compare_right_aux this (by grind)
```

-- snippet 63
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.WellFormedBasis (L36-L41)
def WellFormedBasis (basis : Basis) : Prop :=
basis.Pairwise (fun x y => (Real.log ∘ y) =o[atTop] (Real.log ∘ x)) ∧
  ∀ f ∈ basis, Tendsto f atTop atTop

namespace WellFormedBasis
```

-- snippet 64
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.getBasis (L177-L182)
def getBasis {basis : Basis} (ex : BasisExtension basis) : Basis :=
match ex with
  | nil => []
  | keep basis_hd ex => basis_hd :: ex.getBasis
  | insert f ex => f :: ex.getBasis
```

-- snippet 65
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.push (L116-L122)
theorem push {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
    (hf_tendsto : Tendsto f atTop atTop)
    (hf_comp : ∀ g, basis.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) :
    WellFormedBasis (basis ++ [f]) :=
insert (by simp [h]) hf_tendsto hf_comp (by simp)

/-- All functions from a well-formed basis tend to `atTop`. -/
```

-- snippet 66
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_eq_half_of_head (L135-L139)
theorem dist_eq_half_of_head {s t : Seq α} (h : s.head = t.head) :
    dist s t = 2⁻¹ * dist s.tail t.tail := by
cases s <;> cases t <;> simp at h <;> simp [h]

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 67
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.Basis (L28-L35)
abbrev Basis := List (ℝ → ℝ)
/-- `WellFormedBasis basis` means that all functions from `basis` tend to `atTop`, and
`basis` is sorted such that if
`g` goes after `f` in `basis`, then `log f =o[atTop] log g`.

We use two types `Basis` and `WellFormedBasis` instead of a single bundled one because it
it lets us to use the `List` API for `Basis`. -/
```

-- snippet 68
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.push_log_last (L149-L176)
theorem push_log_last {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h_basis : WellFormedBasis (basis_hd :: basis_tl)) :
    WellFormedBasis ((basis_hd :: basis_tl) ++
      [Real.log ∘ (basis_hd :: basis_tl).getLast (by simp)]) := by
apply h_basis.push
  · simp [Real.tendsto_log_atTop.comp, h_basis.right]
  · intro g hg
    simpa [List.getLast_of_getLast?_eq_some hg] using Real.isLittleO_log_id_atTop.comp_tendsto <|
      Real.tendsto_log_atTop.comp <| h_basis.tendsto_atTop <| List.mem_of_getLast? hg

end WellFormedBasis

/-! ### Basis extensions -/

/-- The type of extensions of a given basis, defined as an inductive type.
Given a `basis : Basis` and `ex : BasisExtension basis` of it, one can use `getBasis` to produce a
basis `basis'` for which `basis <+ basis'`. Moreover, all such bases for which `basis` is a sublist
can be obtained in this manner. In this sense `BasisExtension` is a `Type`-valued analogue
of `List.Sublist`. -/
inductive BasisExtension : Basis → Type
| nil : BasisExtension []
| keep (basis_hd : ℝ → ℝ) {basis_tl : Basis} (ex : BasisExtension basis_tl) :
  BasisExtension (basis_hd :: basis_tl)
| insert {basis : Basis} (f : ℝ → ℝ) (ex : BasisExtension basis) : BasisExtension basis

namespace BasisExtension

/-- The basis after applying a basis extension. -/
```

-- snippet 69
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_eq_two_inv_pow (L111-L115)
theorem dist_eq_two_inv_pow {s t : Seq α} (h : s ≠ t) : ∃ n, dist s t = 2⁻¹ ^ n := by
rw [Subtype.dist_eq, PiNat.dist_eq_of_ne (Subtype.coe_ne_coe.mpr h)]
  simp

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 70
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.head_eventually_pos (L138-L142)
theorem head_eventually_pos {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h : WellFormedBasis (basis_hd :: basis_tl)) : ∀ᶠ x in atTop, 0 < basis_hd x :=
(forall_eventually_of_eventually_forall h.eventually_pos basis_hd).mono (by grind)

/-- All functions in the tail of a well-formed basis are little-o of the basis' head. -/
```

-- snippet 71
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.append (L89-L97)
theorem append {left right : Basis}
    (h_left : WellFormedBasis left) (h_right : WellFormedBasis right)
    (h : ∀ f ∈ left, ∀ g ∈ right, (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    WellFormedBasis (left ++ right) := by
simp only [WellFormedBasis] at *
  constructor
  · simpa [List.pairwise_append, h_left, h_right] using h
  · grind
```

-- snippet 72
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.insert_tail_wellFormedBasis (L190-L198)
theorem insert_tail_wellFormedBasis {basis : Basis} {f : ℝ → ℝ}
    {ex_tl : BasisExtension basis}
    (h_basis : WellFormedBasis <| BasisExtension.getBasis (.insert f ex_tl)) :
    WellFormedBasis ex_tl.getBasis :=
h_basis.of_sublist (by simp [getBasis])

end BasisExtension

end Tactic.ComputeAsymptotics
```

-- snippet 73
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.tendsto_zero_of_neg (L71-L75)
theorem tendsto_zero_of_neg (h_lt : exp < 0) (h : Majorized f b exp) :
    Tendsto f atTop (𝓝 0) := by
simpa [Pi.pow_def, Majorized] using h 0 (by linarith)

/-- Constants are majorized with exponent `exp = 0` by any functions which tends to infinity. -/
```

-- snippet 74
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.FriendlyOperation (L169-L174)
def FriendlyOperation (op : Seq α → Seq α) : Prop := LipschitzWith 1 op
/-- A family of friendly operations on sequences indexed by a type `γ`. -/
class FriendlyOperationClass (F : γ → Seq α → Seq α) : Prop where
  friend : ∀ c : γ, FriendlyOperation (F c)
```

-- snippet 75
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.smul (L89-L94)
theorem smul (h : Majorized f b exp) {c : ℝ} :
    Majorized (c • f) b exp :=
fun exp h_exp ↦ (h exp h_exp).const_mul_left _

/-- The sum of two functions that are majorized with exponents `f_exp` and `g_exp` is
majorized with exponent `exp` whenever `exp ≥ max f_exp g_exp`. -/
```

-- snippet 76
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.compare_left_aux (L60-L74)
theorem compare_left_aux {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
    (h_comp : ∀ g, basis.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) :
    ∀ g ∈ basis, (Real.log ∘ f) =o[atTop] (Real.log ∘ g) := by
intro g hg
  rcases basis.eq_nil_or_concat with rfl | ⟨basis_begin, basis_end, rfl⟩
  · simp at hg
  simp only [List.concat_eq_append, List.mem_append, List.mem_cons, List.not_mem_nil, or_false,
    List.getLast?_append, List.getLast?_singleton, Option.some_or, Option.some.injEq,
    forall_eq'] at hg h_comp
  rcases hg with hg | hg
  · simp only [WellFormedBasis, List.concat_eq_append, List.mem_append, List.mem_cons,
      List.not_mem_nil, or_false] at h
    exact h_comp.trans (by grind)
  · grind
```

-- snippet 77
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.add (L95-L103)
theorem add {f_exp g_exp : ℝ} (hf : Majorized f b f_exp)
    (hg : Majorized g b g_exp) (hf_exp : f_exp ≤ exp) (hg_exp : g_exp ≤ exp) :
    Majorized (f + g) b exp := by
simp only [Majorized] at *
  intro exp' h_exp'
  exact (hf _ (by order)).add (hg _ (by order))

/-- The product of two functions that are majorized with exponents `f_exp` and `g_exp` is
majorized with exponent `f_exp + g_exp`. -/
```

-- snippet 78
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.of_sublist (L47-L51)
theorem of_sublist {basis basis' : Basis} (h : List.Sublist basis basis')
    (h_basis : WellFormedBasis basis') : WellFormedBasis basis :=
⟨h_basis.left.sublist h, fun _ hf ↦ h_basis.right _ (h.subset hf)⟩

/-- The tail of a well-formed basis is well-formed. -/
```

-- snippet 79
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigO_of_div_tendsto_atTop (L76-L80)
theorem isBigO_of_div_tendsto_atTop {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atTop) :
    f =O[l] g :=
Asymptotics.IsLittleO.isBigO (.of_tendsto_div_atTop h)
```

-- snippet 80
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.gcorec_nil (L279-L285)
theorem gcorec_nil {F : β → Option (α × γ × β)} {op : γ → Seq α → Seq α}
    [FriendlyOperationClass op] {b : β}
    (h : F b = none) :
    gcorec F op b = nil := by
have := (FriendlyOperation.exists_fixed_point F op).choose_spec b
  simpa [h] using this
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
theorem tail_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    (cons exp coef tl).tail = tl
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.Basis (L44-L53)
abbrev Basis := List (ℝ → ℝ)
/-- Multiseries representing a given function `f : ℝ → ℝ`.
`MultiseriesExpansion []` is just `ℝ`: multiseries representing constant functions.
Otherwise it is a pair of a `Multiseries basis_hd basis_tl` and a function `ℝ → ℝ`. We call
the former an expansion of the latter.

Note: most of the theory can be formulated in terms of `Multiseries`, but we need to explicitly
store the approximated function to be able to use the eventual zeroness oracle at the trimming step.
-/
```

-- snippet 2
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.MultiseriesExpansion (L54-L71)
def MultiseriesExpansion (basis : Basis) : Type :=
match basis with
  | [] => ℝ
  | .cons _ basis_tl => Seq (ℝ × MultiseriesExpansion basis_tl) × (ℝ → ℝ)

namespace MultiseriesExpansion

set_option linter.unusedVariables false in
/-- Multiseries in a basis `basis_hd :: basis_tl`. It is a generalisation of asymptotic expansions.
A multiseries in a basis `[b₁, ..., bₙ]` is a formal series made from monomials
`b₁ ^ e₁ * ... * bₙ ^ eₙ` where `e₁, ..., eₙ` are real numbers. We treat multivariate series in
a basis `[b₁, ..., bₙ]` as a univariate series in the variable `b₁` (`basis_hd`) with coefficients
being multiseries in the basis `[b₂, ..., bₙ]` (`basis_tl`). We represent such a series as a lazy
list (`Seq`) of pairs `(exp, coef)` where `exp` is the exponent of `b₁` and `coef` is the
coefficient (a multiseries in `basis_tl`).

`MultiseriesExpansion` is a `Multiseries` with an attached real function.
-/
```

-- snippet 3
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.Multiseries (L73-L78)
def Multiseries (basis_hd : ℝ → ℝ) (basis_tl : Basis) : Type :=
Seq (ℝ × MultiseriesExpansion basis_tl)

namespace Multiseries

/-- Converts a `Multiseries basis_hd basis_tl` to a `Seq (ℝ × MultiseriesExpansion basis_tl)`. -/
```

-- snippet 4
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.toSeq (L79-L83)
def toSeq {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Seq (ℝ × MultiseriesExpansion basis_tl) :=
ms

/-- The empty multiseries. -/
```

-- snippet 5
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.nil (L84-L86)
def nil {basis_hd basis_tl} : Multiseries basis_hd basis_tl := Seq.nil
/-- Prepend a monomial to a multiseries. -/
```

-- snippet 6
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.cons (L87-L93)
def cons {basis_hd basis_tl} (exp : ℝ) (coef : MultiseriesExpansion basis_tl)
    (tl : Multiseries basis_hd basis_tl) :
    Multiseries basis_hd basis_tl :=
Seq.cons (exp, coef) tl

/-- Recursion principle for `Multiseries basis_hd basis_tl`. It is equivalent to
`Stream'.Seq.recOn` but provides some convenience. -/
```

-- snippet 7
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.recOn (L95-L101)
def recOn {basis_hd basis_tl} {motive : Multiseries basis_hd basis_tl → Sort*}
    (ms : Multiseries basis_hd basis_tl) (nil : motive nil)
    (cons : ∀ exp coef (tl : Multiseries basis_hd basis_tl), motive (cons exp coef tl)) :
    motive ms := Stream'.Seq.recOn _ nil fun _ _ ↦ cons _ _ _
/-- Destruct a multiseries into a triple `(exp, coef, tl)`, where `exp` is the leading exponent,
`coef` is the leading coefficient, and `tl` is the tail. -/
```

-- snippet 8
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct (L102-L106)
def destruct {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Option (ℝ × MultiseriesExpansion basis_tl × Multiseries basis_hd basis_tl) :=
(Seq.destruct ms).map (fun ((exp, coef), tl) => (exp, coef, tl))

/-- The head of a multiseries, i.e. the first two entries of the tuple returned by `destruct`. -/
```

-- snippet 9
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head (L107-L111)
def head {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) :
    Option (ℝ × MultiseriesExpansion basis_tl) :=
Seq.head ms

/-- The tail of a multiseries, i.e. the last entry of the tuple returned by `destruct`. -/
```

-- snippet 10
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.tail (L112-L117)
def tail {basis_hd basis_tl} (ms : Multiseries basis_hd basis_tl) : Multiseries basis_hd basis_tl :=
Seq.tail ms

/-- Given two functions `f : ℝ → ℝ` and
`g : MultiseriesExpansion basis_tl → MultiseriesExpansion basis_tl'`, apply them to exponents and
coefficients of a multiseries. -/
```

-- snippet 11
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.map (L118-L124)
def map {basis_hd basis_tl basis_hd' basis_tl'} (f : ℝ → ℝ)
    (g : MultiseriesExpansion basis_tl → MultiseriesExpansion basis_tl')
    (ms : Multiseries basis_hd basis_tl) :
    Multiseries basis_hd' basis_tl' :=
Seq.map (fun (exp, coef) ↦ (f exp, g coef)) ms

/-- Corecursor for `Multiseries basis_hd basis_tl`. -/
```

-- snippet 12
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.corec (L125-L136)
def corec {β : Type*} {basis_hd} {basis_tl}
    (f : β → Option (ℝ × MultiseriesExpansion basis_tl × β)) (b : β) :
    Multiseries basis_hd basis_tl :=
Seq.corec (fun a => (f a).map (fun (exp, coef, next) => ((exp, coef), next))) b

private lemma destruct_eq_destruct_map {basis_hd basis_tl}
    (s : Stream'.Seq (ℝ × MultiseriesExpansion basis_tl)) :
    s.destruct = (Multiseries.destruct (basis_hd := basis_hd) s).map
      (fun (exp, coef, tl) => ((exp, coef), tl)) := by
  simp only [destruct, Option.map_map]
  exact Option.map_id_apply.symm
```

-- snippet 13
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.eq_of_bisim (L144-L151)
theorem eq_of_bisim {basis_hd : ℝ → ℝ} {basis_tl : Basis} {x y : Multiseries basis_hd basis_tl}
    (motive : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl → Prop)
    (base : motive x y)
    (step : ∀ x y, motive x y → (x = .nil ∧ y = .nil) ∨ ∃ exp coef,
      ∃ (x' y' : Multiseries basis_hd basis_tl),
      x = cons exp coef x' ∧ y = cons exp coef y' ∧ motive x' y') :
    x = y := Seq.eq_of_bisim' motive base (by grind [nil, cons])
```

-- snippet 14
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.eq_of_bisim_strong (L152-L162)
theorem eq_of_bisim_strong {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    {x y : Multiseries basis_hd basis_tl}
    (motive : Multiseries basis_hd basis_tl → Multiseries basis_hd basis_tl → Prop)
    (base : motive x y)
    (step : ∀ x y, motive x y → (x = y) ∨ ∃ exp coef,
      ∃ (x' y' : Multiseries basis_hd basis_tl),
      x = cons exp coef x' ∧ y = cons exp coef y' ∧ motive x' y') :
    x = y := Seq.eq_of_bisim_strong motive base (by grind [nil, cons])
section simp
```

-- snippet 15
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.cons_ne_nil (L164-L171)
theorem cons_ne_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    cons exp coef tl ≠ .nil := by
intro h
  simp only [cons, nil] at h
  apply Seq.cons_ne_nil h
```

-- snippet 16
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.nil_ne_cons (L173-L178)
theorem nil_ne_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    .nil ≠ cons exp coef tl := cons_ne_nil.symm
set_option backward.isDefEq.respectTransparency false in
```

-- snippet 17
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.cons_eq_cons (L180-L185)
theorem cons_eq_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp1 exp2 : ℝ}
    {coef1 coef2 : MultiseriesExpansion basis_tl} {tl1 tl2 : Multiseries basis_hd basis_tl} :
    cons exp1 coef1 tl1 = cons exp2 coef2 tl2 ↔ exp1 = exp2 ∧ coef1 = coef2 ∧ tl1 = tl2 := by
rw [cons, cons, Seq.cons_eq_cons]
  grind
```

-- snippet 18
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.corec_nil (L186-L192)
theorem corec_nil {β : Type*} {basis_hd} {basis_tl}
    {f : β → Option (ℝ × MultiseriesExpansion basis_tl × β)} {b : β} (h : f b = none) :
    corec f b = (nil : Multiseries basis_hd basis_tl) := by
simp only [corec, nil]
  rw [Seq.corec_nil]
  simpa
```

-- snippet 19
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.corec_cons (L193-L201)
theorem corec_cons {β : Type*} {basis_hd} {basis_tl} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl} {next : β}
    {f : β → Option (ℝ × MultiseriesExpansion basis_tl × β)} {b : β}
    (h : f b = some (exp, coef, next)) :
    (corec f b : Multiseries basis_hd basis_tl) = cons exp coef (corec f next) := by
simp only [corec, cons]
  rw [Seq.corec_cons]
  simpa
```

-- snippet 20
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_nil (L203-L207)
theorem destruct_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
    destruct (nil : Multiseries basis_hd basis_tl) = none := by
simp [destruct, nil]

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 21
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_cons (L209-L214)
theorem destruct_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    destruct (cons exp coef tl) = some (exp, coef, tl) := by
simp [destruct, cons]
```

-- snippet 22
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_eq_none (L215-L219)
theorem destruct_eq_none {basis_hd : ℝ → ℝ} {basis_tl : Basis} {ms : Multiseries basis_hd basis_tl}
    (h : destruct ms = none) : ms = nil := by
apply Stream'.Seq.destruct_eq_none
  simpa [destruct] using h
```

-- snippet 23
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.destruct_eq_cons (L220-L226)
theorem destruct_eq_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {ms : Multiseries basis_hd basis_tl}
    {exp : ℝ} {coef : MultiseriesExpansion basis_tl} {tl : Multiseries basis_hd basis_tl}
    (h : destruct ms = some (exp, coef, tl)) : ms = cons exp coef tl := by
apply Stream'.Seq.destruct_eq_cons
  simp [destruct] at h
  grind
```

-- snippet 24
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head_nil (L228-L231)
theorem head_nil {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
    (nil : Multiseries basis_hd basis_tl).head = none := by
simp [head, nil]
```

-- snippet 25
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs.head_cons (L233-L238)
theorem head_cons {basis_hd : ℝ → ℝ} {basis_tl : Basis} {exp : ℝ}
    {coef : MultiseriesExpansion basis_tl}
    {tl : Multiseries basis_hd basis_tl} :
    (cons exp coef tl).head = some (exp, coef) := by
simp [head, cons]
```

-- snippet 26
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.eventually_pos (L128-L137)
theorem eventually_pos {basis : Basis} (h : WellFormedBasis basis) :
    ∀ᶠ x in atTop, ∀ f ∈ basis, 0 < f x := by
induction basis with
  | nil => simp
  | cons hd tl ih =>
    simp only [WellFormedBasis, List.pairwise_cons, List.mem_cons, forall_eq_or_imp] at h
    simp only [List.mem_cons, forall_eq_or_imp]
    exact (h.right.left.eventually <| eventually_gt_atTop 0).and (ih (by tauto))

/-- The first function in a well-formed basis is eventually positive. -/
```

-- snippet 27
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.exists_fixed_point_of_contractible (L207-L218)
theorem exists_fixed_point_of_contractible (F : (β →ᵤ Seq α) → (β →ᵤ Seq α))
    (h : LipschitzWith 2⁻¹ F) :
    ∃ f : β → Seq α, Function.IsFixedPt F f := by
have hF : ContractingWith 2⁻¹ F := by
    constructor
    · norm_num
    · exact h
  let f := hF.fixedPoint _
  use f
  exact hF.fixedPoint_isFixedPt

/-- Main theorem of this file. It shows that there exists a function satisfying the corecursive
```

-- snippet 28
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigOWith_of_tendsto_top (L66-L70)
theorem isBigOWith_of_tendsto_top {C : ℝ} {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atTop) (hC : 0 < C) :
    IsBigOWith C l f g :=
Asymptotics.IsLittleO.forall_isBigOWith (.of_tendsto_div_atTop h) hC
```

-- snippet 29
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_cons (L117-L134)
theorem dist_cons_cons (x : α) (s t : Seq α) : dist (cons x s) (cons x t) = 2⁻¹ * dist s t := by
by_cases! h : s = t
  · simp [h]
  have h' : cons x s ≠ cons x t := by
    simpa
  rw [Subtype.dist_eq, Subtype.dist_eq, PiNat.dist_eq_of_ne (Subtype.coe_ne_coe.mpr h),
    PiNat.dist_eq_of_ne (Subtype.coe_ne_coe.mpr h')]
  simp only [show (1 / 2 : ℝ) = 2⁻¹ by simp, ← pow_succ']
  congr
  simp only [val_cons, PiNat.firstDiff, ne_eq, Classical.dite_not, Subtype.coe_ne_coe.mpr h,
    not_false_eq_true, ↓reduceDIte, val_eq_get]
  split_ifs with h_if
  · contrapose! h'
    apply_fun Subtype.val using Subtype.val_injective
    simpa
  · convert Nat.find_comp_succ _ _ _
    simp [Stream'.cons]
```

-- snippet 30
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.Stream' (L95-L100)
theorem Stream'.dist_le_one (s t : Stream' α) : dist s t ≤ 1 := by
by_cases h : s = t
  · simp [h]
  rw [PiNat.dist_eq_of_ne h]
  bound
```

-- snippet 31
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.of_append_right (L56-L59)
theorem of_append_right {left right : Basis} (h : WellFormedBasis (left ++ right)) :
    WellFormedBasis right :=
h.of_sublist (by simp)
```

-- snippet 32
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.const (L76-L84)
theorem const (h_tendsto : Tendsto b atTop atTop) {c : ℝ} :
    Majorized (fun _ ↦ c) b 0 := by
intro exp h_exp
  apply Asymptotics.isLittleO_const_left.mpr
  right
  apply tendsto_norm_atTop_atTop.comp
  exact (tendsto_rpow_atTop h_exp).comp h_tendsto

/-- The zero function is majorized with any exponent. -/
```

-- snippet 33
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsNE_of_tendsto_atTop (L53-L58)
theorem tendsto_nhdsNE_of_tendsto_atTop (h_neg : Tendsto (fun x ↦ f (c - x⁻¹)) atTop l)
    (h_pos : Tendsto (fun x ↦ f (c + x⁻¹)) atTop l) :
    Tendsto f (𝓝[≠] c) l := by
simpa [Tendsto, ← nhdsLT_sup_nhdsGT] using
    ⟨tendsto_nhdsLT_of_tendsto_atTop _ _ h_neg, tendsto_nhdsGT_of_tendsto_atTop _ _ h_pos⟩
```

-- snippet 34
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.gcorec_some (L286-L294)
theorem gcorec_some {F : β → Option (α × γ × β)} {op : γ → Seq α → Seq α}
    [FriendlyOperationClass op] {b : β}
    {a : α} {c : γ} {b' : β}
    (h : F b = some (a, c, b')) :
    gcorec F op b = Seq.cons a (op c (gcorec F op b')) := by
have := (FriendlyOperation.exists_fixed_point F op).choose_spec b
  simpa [h] using this

end Tactic.ComputeAsymptotics.Seq
```

-- snippet 35
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.foo (L19-L33)
def foo (x : X) := hd x :: foo (tlArg x)
```
(where hd and tlArg are arbitrary functions) can be encoded via the corecursor `Seq.corec`.

It is not enough, however, to define multiplication and `powser` operation for multiseries.

This file implements a more general form of corecursion in the spirit of [blanchette2015].
This is a bare minimum that needed for the tactic, it justifies a weaker class of
corecursive definitions than [blanchette2015] does, and only works for `Seq`.

A function `f : Seq α → Seq α` is called *friendly* if for all `n : ℕ` the `n`-prefix of its result
`f s` depends only on the `n`-prefix of its input `s`.

In this file we develop a theory that justifies corecursive definitions of the form
```
```

-- snippet 36
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tendsto_atTop (L123-L127)
theorem tendsto_atTop {basis : Basis} (h : WellFormedBasis basis) {f : ℝ → ℝ}
    (hf : f ∈ basis) :
    Tendsto f atTop atTop := h.right f hf
/-- Eventually all functions from a well-formed basis are positive. -/
```

-- snippet 37
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.Majorized (L32-L39)
def Majorized (f b : ℝ → ℝ) (exp : ℝ) : Prop :=
∀ exp' > exp, f =o[atTop] (b ^ exp')

namespace Majorized

variable {f g b : ℝ → ℝ} {exp : ℝ}

/-- Replacing the first argument of `Majorized` by an eventually equal function preserves it. -/
```

-- snippet 38
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tail (L52-L55)
theorem tail {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h : WellFormedBasis (basis_hd :: basis_tl)) : WellFormedBasis basis_tl :=
h.of_sublist (by simp)
```

-- snippet 39
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.mul_bounded (L118-L128)
theorem mul_bounded {f g basis_hd : ℝ → ℝ} {exp : ℝ} (hf : Majorized f basis_hd exp)
    (hg : g =O[atTop] (fun _ ↦ (1 : ℝ))) :
    Majorized (f * g) basis_hd exp := by
intro exp h_exp
  convert IsLittleO.mul_isBigO (hf _ h_exp) hg using 1
  simp
  rfl

end Majorized

end Tactic.ComputeAsymptotics
```

-- snippet 40
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_eq_one_of_head (L140-L150)
theorem dist_eq_one_of_head {s t : Seq α} (h : s.head ≠ t.head) : dist s t = 1 := by
rw [Subtype.dist_eq, PiNat.dist_eq_of_ne]
  · convert pow_zero _
    simp only [PiNat.firstDiff, ne_eq, Classical.dite_not, dite_eq_left_iff,
      Nat.find_eq_zero]
    intro h'
    simpa [Stream'.cons]
  · rw [Subtype.coe_ne_coe]
    contrapose! h
    simp [h]
```

-- snippet 41
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.single (L44-L46)
theorem single (f : ℝ → ℝ) (hf : Tendsto f atTop atTop) : WellFormedBasis [f] := by
simpa [WellFormedBasis]
```

-- snippet 42
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigOWith_of_tendsto_bot (L71-L75)
theorem isBigOWith_of_tendsto_bot {C : ℝ} {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atBot) (hC : 0 < C) :
    IsBigOWith C l f g :=
Asymptotics.IsLittleO.forall_isBigOWith (.of_tendsto_div_atBot h) hC
```

-- snippet 43
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsLT_of_tendsto_atTop (L46-L52)
theorem tendsto_nhdsLT_of_tendsto_atTop (h : Tendsto (fun x ↦ f (c - x⁻¹)) atTop l) :
    Tendsto f (𝓝[<] c) l := by
convert_to Tendsto (f ∘ (fun x ↦ c + x) ∘ Neg.neg ∘ Inv.inv) atTop l at h
  · ext
    simp [AddGroupWithOne.sub_eq_add_neg]
  simpa [Tendsto, ← Filter.map_map] using h
```

-- snippet 44
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.mul (L104-L117)
theorem mul {f_exp g_exp : ℝ} (hf : Majorized f b f_exp)
    (hg : Majorized g b g_exp) (h_pos : ∀ᶠ t in atTop, 0 < b t) :
    Majorized (f * g) b (f_exp + g_exp) := by
simp only [Majorized] at *
  intro exp h_exp
  let ε := (exp - f_exp - g_exp) / 2
  specialize hf (f_exp + ε) (by dsimp [ε]; linarith)
  specialize hg (g_exp + ε) (by dsimp [ε]; linarith)
  apply (hf.mul hg).trans_eventuallyEq (g₁ := fun t ↦ b t ^ (f_exp + ε) * b t ^ (g_exp + ε))
  apply h_pos.mono
  intro t hx
  simp only [Pi.pow_apply]
  conv_rhs => rw [show exp = (f_exp + ε) + (g_exp + ε) by dsimp [ε]; ring_nf, Real.rpow_add hx]
```

-- snippet 45
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.of_le (L65-L70)
theorem of_le {exp1 exp2 : ℝ} (h_lt : exp1 ≤ exp2) (h : Majorized f b exp1) :
    Majorized f b exp2 := by
simp only [Majorized] at *
  exact fun exp' h_exp ↦ h _ (by linarith)

/-- If `f` is majorized with a negative exponent, then it tends to zero. -/
```

-- snippet 46
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_le_one (L102-L110)
theorem dist_le_one (s t : Seq α) : dist s t ≤ 1 := PiNat.dist_le_one _ _
local instance : BoundedSpace (Stream' α) :=
  @PiNat.boundedSpace _ (fun _ ↦ ⊥) (fun _ ↦ discreteTopology_bot _)

local instance : BoundedSpace (Seq α) :=
  instBoundedSpaceSubtype

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 47
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.cons (L98-L104)
theorem cons {basis : Basis} {f : ℝ → ℝ} (h_basis : WellFormedBasis basis)
    (hf_tendsto : Tendsto f atTop atTop)
    (hf : ∀ g ∈ basis, (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    WellFormedBasis (f :: basis) := by
change WellFormedBasis ([f] ++ basis)
  exact append (by simpa [WellFormedBasis]) h_basis (by simpa)
```

-- snippet 48
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_nil (L157-L160)
theorem dist_cons_nil (x : α) (s : Seq α) : dist (cons x s) nil = 1 := by
apply dist_eq_one_of_head
  simp
```

-- snippet 49
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.tail_isLittleO_head (L143-L148)
theorem tail_isLittleO_head {hd : ℝ → ℝ} {tl : Basis}
    (h : WellFormedBasis (hd :: tl)) {f : ℝ → ℝ} (hf : f ∈ tl) :
    (Real.log ∘ f) =o[atTop] (Real.log ∘ hd) := by
rw [WellFormedBasis, List.pairwise_cons] at h
  exact h.left.left _ hf
```

-- snippet 50
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.nil (L42-L43)
theorem nil : WellFormedBasis [] := by simp [WellFormedBasis]
```

-- snippet 51
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsGT_of_tendsto_atTop (L42-L45)
theorem tendsto_nhdsGT_of_tendsto_atTop (h : Tendsto (fun x ↦ f (c + x⁻¹)) atTop l) :
    Tendsto f (𝓝[>] c) l := by
simpa [← Function.comp_def, Tendsto, ← Filter.map_map] using h
```

-- snippet 52
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.tendsto_nhdsNE_of_tendsto_atTop_nhds_of_eq (L59-L65)
theorem tendsto_nhdsNE_of_tendsto_atTop_nhds_of_eq [TopologicalSpace α] {a b : α}
    (h_neg : Tendsto (fun x ↦ f (c - x⁻¹)) atTop (𝓝 a))
    (h_pos : Tendsto (fun x ↦ f (c + x⁻¹)) atTop (𝓝 b)) (h_eq : a = b) :
    Tendsto f (𝓝[≠] c) (𝓝 a) := by
apply tendsto_nhdsNE_of_tendsto_atTop _ _ h_neg
  convert h_pos
```

-- snippet 53
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.of_eventuallyEq (L40-L46)
theorem of_eventuallyEq (h_eq : g =ᶠ[atTop] f) (h : Majorized f b exp) :
    Majorized g b exp := by
simp only [Majorized] at *
  intro exp' h_exp
  exact EventuallyEq.trans_isLittleO h_eq (h exp' h_exp)

/-- For any function `f` tending to infinity, `f ^ exp` is majorized by `f` with exponent `exp`. -/
```

-- snippet 54
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.FriendlyOperationClass (L188-L191)
theorem FriendlyOperationClass.comp (F : γ → Seq α → Seq α) (g : γ' → γ)
    [h : FriendlyOperationClass F] : FriendlyOperationClass (fun c ↦ F (g c)) := by
grind [FriendlyOperationClass]
```

-- snippet 55
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.zero (L85-L88)
theorem zero : Majorized 0 b exp :=
fun _ _ ↦ Asymptotics.isLittleO_zero _ _

/-- `c • f` is majorized with the same exponent as `f` for any constant `c`. -/
```

-- snippet 56
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_nil_cons (L162-L167)
theorem dist_nil_cons (x : α) (s : Seq α) : dist nil (cons x s) = 1 := by
rw [dist_comm]
  simp

/-- A function on sequences is called a "friend" if any `n`-prefix of its output depends only on
the `n`-prefix of the input. Such functions can be used in the tail of (non-primitive) corecursive
```

-- snippet 57
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.compare_right_aux (L75-L88)
theorem compare_right_aux {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
    (h_comp : ∀ g, basis.head? = .some g → (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    ∀ g ∈ basis, (Real.log ∘ g) =o[atTop] (Real.log ∘ f) := by
intro g hg
  cases basis with
  | nil => simp at hg
  | cons basis_hd basis_tl =>
    specialize h_comp basis_hd (by simp)
    simp only [List.mem_cons] at hg
    rcases hg with hg | hg
    · simpa [hg]
    · simp only [WellFormedBasis, List.pairwise_cons, List.mem_cons, forall_eq_or_imp] at h
      exact .trans (by grind) h_comp
```

-- snippet 58
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.self (L47-L64)
theorem self (h : Tendsto f atTop atTop) :
    Majorized (f ^ exp) f exp := by
simp only [Majorized]
  intro exp' h_exp
  apply (isLittleO_iff_tendsto' _).mpr
  · have : (fun t ↦ f t ^ exp / f t ^ exp') =ᶠ[atTop] fun t ↦ (f t) ^ (exp - exp') :=
      (h.eventually_gt_atTop 0).mono (fun _ h ↦ by simp [← Real.rpow_sub h])
    apply Tendsto.congr' this.symm
    conv =>
      arg 1
      rw [show (fun t ↦ f t ^ (exp - exp')) = ((fun t ↦ t ^ (-(exp' - exp))) ∘ f) by ext; simp]
    exact (tendsto_rpow_neg_atTop (by linarith)).comp h
  · apply (Tendsto.eventually_gt_atTop h 0).mono
    intro t h1 h2
    absurd h2
    exact (Real.rpow_pos_of_pos h1 _).ne.symm

/-- If `f` is majorized with exponent `exp₁`, then it is majorized with any `exp₂ ≥ exp₁`. -/
```

-- snippet 59
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_cons_cons_eq_one (L151-L155)
theorem dist_cons_cons_eq_one {x y : α} {s t : Seq α} (h : x ≠ y) :
    dist (cons x s) (cons y t) = 1 := by
apply dist_eq_one_of_head
  simpa
```

-- snippet 60
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigO_of_div_tendsto_atBot (L81-L86)
theorem isBigO_of_div_tendsto_atBot {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atBot) :
    f =O[l] g :=
Asymptotics.IsLittleO.isBigO (.of_tendsto_div_atBot h)

end Tactic.ComputeAsymptotics
```

-- snippet 61
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.sublist_getBasis (L183-L189)
theorem sublist_getBasis {basis : Basis} {ex : BasisExtension basis} :
    List.Sublist basis ex.getBasis := by
induction ex with
  | nil => simp
  | keep _ ex ih => simpa [getBasis] using ih
  | insert _ ex ih => exact List.Sublist.cons _ ih
```

-- snippet 62
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.insert (L105-L115)
theorem insert {left right : Basis} {f : ℝ → ℝ}
    (h : WellFormedBasis (left ++ right)) (hf_tendsto : Tendsto f atTop atTop)
    (hf_comp_left : ∀ g, left.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g))
    (hf_comp_right : ∀ g, right.head? = .some g → (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    WellFormedBasis (left ++ f :: right) := by
have : WellFormedBasis (f :: right) := cons (h.of_sublist (by simp)) hf_tendsto
    (compare_right_aux (h.of_sublist (by simp)) hf_comp_right)
  apply compare_left_aux (h.of_sublist (by simp)) at hf_comp_left
  apply append (h.of_sublist (by simp)) this
  exact fun g hg ↦ compare_right_aux this (by grind)
```

-- snippet 63
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.WellFormedBasis (L36-L41)
def WellFormedBasis (basis : Basis) : Prop :=
basis.Pairwise (fun x y => (Real.log ∘ y) =o[atTop] (Real.log ∘ x)) ∧
  ∀ f ∈ basis, Tendsto f atTop atTop

namespace WellFormedBasis
```

-- snippet 64
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.getBasis (L177-L182)
def getBasis {basis : Basis} (ex : BasisExtension basis) : Basis :=
match ex with
  | nil => []
  | keep basis_hd ex => basis_hd :: ex.getBasis
  | insert f ex => f :: ex.getBasis
```

-- snippet 65
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.push (L116-L122)
theorem push {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
    (hf_tendsto : Tendsto f atTop atTop)
    (hf_comp : ∀ g, basis.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) :
    WellFormedBasis (basis ++ [f]) :=
insert (by simp [h]) hf_tendsto hf_comp (by simp)

/-- All functions from a well-formed basis tend to `atTop`. -/
```

-- snippet 66
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_eq_half_of_head (L135-L139)
theorem dist_eq_half_of_head {s t : Seq α} (h : s.head = t.head) :
    dist s t = 2⁻¹ * dist s.tail t.tail := by
cases s <;> cases t <;> simp at h <;> simp [h]

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 67
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.Basis (L28-L35)
abbrev Basis := List (ℝ → ℝ)
/-- `WellFormedBasis basis` means that all functions from `basis` tend to `atTop`, and
`basis` is sorted such that if
`g` goes after `f` in `basis`, then `log f =o[atTop] log g`.

We use two types `Basis` and `WellFormedBasis` instead of a single bundled one because it
it lets us to use the `List` API for `Basis`. -/
```

-- snippet 68
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.push_log_last (L149-L176)
theorem push_log_last {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h_basis : WellFormedBasis (basis_hd :: basis_tl)) :
    WellFormedBasis ((basis_hd :: basis_tl) ++
      [Real.log ∘ (basis_hd :: basis_tl).getLast (by simp)]) := by
apply h_basis.push
  · simp [Real.tendsto_log_atTop.comp, h_basis.right]
  · intro g hg
    simpa [List.getLast_of_getLast?_eq_some hg] using Real.isLittleO_log_id_atTop.comp_tendsto <|
      Real.tendsto_log_atTop.comp <| h_basis.tendsto_atTop <| List.mem_of_getLast? hg

end WellFormedBasis

/-! ### Basis extensions -/

/-- The type of extensions of a given basis, defined as an inductive type.
Given a `basis : Basis` and `ex : BasisExtension basis` of it, one can use `getBasis` to produce a
basis `basis'` for which `basis <+ basis'`. Moreover, all such bases for which `basis` is a sublist
can be obtained in this manner. In this sense `BasisExtension` is a `Type`-valued analogue
of `List.Sublist`. -/
inductive BasisExtension : Basis → Type
| nil : BasisExtension []
| keep (basis_hd : ℝ → ℝ) {basis_tl : Basis} (ex : BasisExtension basis_tl) :
  BasisExtension (basis_hd :: basis_tl)
| insert {basis : Basis} (f : ℝ → ℝ) (ex : BasisExtension basis) : BasisExtension basis

namespace BasisExtension

/-- The basis after applying a basis extension. -/
```

-- snippet 69
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.dist_eq_two_inv_pow (L111-L115)
theorem dist_eq_two_inv_pow {s t : Seq α} (h : s ≠ t) : ∃ n, dist s t = 2⁻¹ ^ n := by
rw [Subtype.dist_eq, PiNat.dist_eq_of_ne (Subtype.coe_ne_coe.mpr h)]
  simp

set_option backward.isDefEq.respectTransparency false in
```

-- snippet 70
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.head_eventually_pos (L138-L142)
theorem head_eventually_pos {basis_hd : ℝ → ℝ} {basis_tl : Basis}
    (h : WellFormedBasis (basis_hd :: basis_tl)) : ∀ᶠ x in atTop, 0 < basis_hd x :=
(forall_eventually_of_eventually_forall h.eventually_pos basis_hd).mono (by grind)

/-- All functions in the tail of a well-formed basis are little-o of the basis' head. -/
```

-- snippet 71
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.append (L89-L97)
theorem append {left right : Basis}
    (h_left : WellFormedBasis left) (h_right : WellFormedBasis right)
    (h : ∀ f ∈ left, ∀ g ∈ right, (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
    WellFormedBasis (left ++ right) := by
simp only [WellFormedBasis] at *
  constructor
  · simpa [List.pairwise_append, h_left, h_right] using h
  · grind
```

-- snippet 72
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.insert_tail_wellFormedBasis (L190-L198)
theorem insert_tail_wellFormedBasis {basis : Basis} {f : ℝ → ℝ}
    {ex_tl : BasisExtension basis}
    (h_basis : WellFormedBasis <| BasisExtension.getBasis (.insert f ex_tl)) :
    WellFormedBasis ex_tl.getBasis :=
h_basis.of_sublist (by simp [getBasis])

end BasisExtension

end Tactic.ComputeAsymptotics
```

-- snippet 73
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.tendsto_zero_of_neg (L71-L75)
theorem tendsto_zero_of_neg (h_lt : exp < 0) (h : Majorized f b exp) :
    Tendsto f atTop (𝓝 0) := by
simpa [Pi.pow_def, Majorized] using h 0 (by linarith)

/-- Constants are majorized with exponent `exp = 0` by any functions which tends to infinity. -/
```

-- snippet 74
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.FriendlyOperation (L169-L174)
def FriendlyOperation (op : Seq α → Seq α) : Prop := LipschitzWith 1 op
/-- A family of friendly operations on sequences indexed by a type `γ`. -/
class FriendlyOperationClass (F : γ → Seq α → Seq α) : Prop where
  friend : ∀ c : γ, FriendlyOperation (F c)
```

-- snippet 75
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.smul (L89-L94)
theorem smul (h : Majorized f b exp) {c : ℝ} :
    Majorized (c • f) b exp :=
fun exp h_exp ↦ (h exp h_exp).const_mul_left _

/-- The sum of two functions that are majorized with exponents `f_exp` and `g_exp` is
majorized with exponent `exp` whenever `exp ≥ max f_exp g_exp`. -/
```

-- snippet 76
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.compare_left_aux (L60-L74)
theorem compare_left_aux {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
    (h_comp : ∀ g, basis.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) :
    ∀ g ∈ basis, (Real.log ∘ f) =o[atTop] (Real.log ∘ g) := by
intro g hg
  rcases basis.eq_nil_or_concat with rfl | ⟨basis_begin, basis_end, rfl⟩
  · simp at hg
  simp only [List.concat_eq_append, List.mem_append, List.mem_cons, List.not_mem_nil, or_false,
    List.getLast?_append, List.getLast?_singleton, Option.some_or, Option.some.injEq,
    forall_eq'] at hg h_comp
  rcases hg with hg | hg
  · simp only [WellFormedBasis, List.concat_eq_append, List.mem_append, List.mem_cons,
      List.not_mem_nil, or_false] at h
    exact h_comp.trans (by grind)
  · grind
```

-- snippet 77
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized.add (L95-L103)
theorem add {f_exp g_exp : ℝ} (hf : Majorized f b f_exp)
    (hg : Majorized g b g_exp) (hf_exp : f_exp ≤ exp) (hg_exp : g_exp ≤ exp) :
    Majorized (f + g) b exp := by
simp only [Majorized] at *
  intro exp' h_exp'
  exact (hf _ (by order)).add (hg _ (by order))

/-- The product of two functions that are majorized with exponents `f_exp` and `g_exp` is
majorized with exponent `f_exp + g_exp`. -/
```

-- snippet 78
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis.of_sublist (L47-L51)
theorem of_sublist {basis basis' : Basis} (h : List.Sublist basis basis')
    (h_basis : WellFormedBasis basis') : WellFormedBasis basis :=
⟨h_basis.left.sublist h, fun _ hf ↦ h_basis.right _ (h.subset hf)⟩

/-- The tail of a well-formed basis is well-formed. -/
```

-- snippet 79
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Lemmas.isBigO_of_div_tendsto_atTop (L76-L80)
theorem isBigO_of_div_tendsto_atTop {f g : ℝ → ℝ} {l : Filter ℝ}
    (h : Tendsto (fun x ↦ g x / f x) l atTop) :
    f =O[l] g :=
Asymptotics.IsLittleO.isBigO (.of_tendsto_div_atTop h)
```

-- snippet 80
```lean
-- Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion.gcorec_nil (L279-L285)
theorem gcorec_nil {F : β → Option (α × γ × β)} {op : γ → Seq α → Seq α}
    [FriendlyOperationClass op] {b : β}
    (h : F b = none) :
    gcorec F op b = nil := by
have := (FriendlyOperation.exists_fixed_point F op).choose_spec b
  simpa [h] using this
```
[/INST]


Instruction: Edit `le_rearrange` so it still compiles and the proof is simplified where possible. Return the full updated `le_rearrange` block.

[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Tactic.LinearCombination.Lemmas).

[User]
You are editing a file in `Mathlib/Tactic/LinearCombination/Lemmas.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.Tactic.LinearCombination.Lemmas.le_rearrange`, L184-L187)
```lean
theorem le_rearrange {α : Type*} [AddCommGroup α] [PartialOrder α] [IsOrderedAddMonoid α]
    {a b : α} (h : a - b ≤ 0) : a ≤ b := sub_nonpos.mp h
```

## Edit instruction
Edit `le_rearrange` so it still compiles and the proof is simplified where possible. Return the full updated `le_rearrange` block.

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Tactic.LinearCombination.Lemmas).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]You are editing a file in `Mathlib/Tactic/LinearCombination/Lemmas.lean` (mathlib commit 5e932f97dd25535344f80f9dd8da3aab83df0fe6).

## Current excerpt (around `Mathlib.Tactic.LinearCombination.Lemmas.le_rearrange`, L184-L187)
```lean
theorem le_rearrange {α : Type*} [AddCommGroup α] [PartialOrder α] [IsOrderedAddMonoid α]
    {a b : α} (h : a - b ≤ 0) : a ≤ b := sub_nonpos.mp h
```

## Edit instruction
Edit `le_rearrange` so it still compiles and the proof is simplified where possible. Return the full updated `le_rearrange` block.
[/INST]