Skip to content

Commit 9cae144

Browse files
feat(Tactic/ComputeAsymptotics/Multiseries): WellFormedBasis lemmas (#34422)
Introduce `WellFormedBasis` and prove basic lemmas about it. Co-authored-by: LLaurance <[email protected]>
1 parent cbd09a2 commit 9cae144

File tree

3 files changed

+200
-0
lines changed

3 files changed

+200
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6698,6 +6698,7 @@ public import Mathlib.Tactic.Clear_
66986698
public import Mathlib.Tactic.Coe
66996699
public import Mathlib.Tactic.Common
67006700
public import Mathlib.Tactic.ComputeAsymptotics.Lemmas
6701+
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis
67016702
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion
67026703
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized
67036704
public import Mathlib.Tactic.ComputeDegree

Mathlib/Tactic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public import Mathlib.Tactic.Clear_
5555
public import Mathlib.Tactic.Coe
5656
public import Mathlib.Tactic.Common
5757
public import Mathlib.Tactic.ComputeAsymptotics.Lemmas
58+
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis
5859
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion
5960
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Majorized
6061
public import Mathlib.Tactic.ComputeDegree
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/-
2+
Copyright (c) 2026 Vasilii Nesterov. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Vasilii Nesterov
5+
-/
6+
module
7+
public import Mathlib.Analysis.SpecialFunctions.Pow.Asymptotics
8+
public import Mathlib.Analysis.Complex.Exponential
9+
10+
/-!
11+
# Well-formed bases
12+
13+
## Main definitions
14+
15+
* `WellFormedBasis basis`: a predicate meaning that all functions from `basis` tend to `atTop`,
16+
and `basis` is sorted such that if
17+
`g` goes after `f` in `basis`, then `log f =o[atTop] log g`.
18+
19+
-/
20+
21+
@[expose] public section
22+
23+
namespace Tactic.ComputeAsymptotics
24+
25+
open Asymptotics Filter
26+
27+
/-- List of functions used to construct monomials in multiseries. -/
28+
abbrev Basis := List (ℝ → ℝ)
29+
30+
/-- `WellFormedBasis basis` means that all functions from `basis` tend to `atTop`, and
31+
`basis` is sorted such that if
32+
`g` goes after `f` in `basis`, then `log f =o[atTop] log g`.
33+
34+
We use two types `Basis` and `WellFormedBasis` instead of a single bundled one because it
35+
it lets us to use the `List` API for `Basis`. -/
36+
def WellFormedBasis (basis : Basis) : Prop :=
37+
basis.Pairwise (fun x y => (Real.log ∘ y) =o[atTop] (Real.log ∘ x)) ∧
38+
∀ f ∈ basis, Tendsto f atTop atTop
39+
40+
namespace WellFormedBasis
41+
42+
theorem nil : WellFormedBasis [] := by simp [WellFormedBasis]
43+
44+
theorem single (f : ℝ → ℝ) (hf : Tendsto f atTop atTop) : WellFormedBasis [f] := by
45+
simpa [WellFormedBasis]
46+
47+
theorem of_sublist {basis basis' : Basis} (h : List.Sublist basis basis')
48+
(h_basis : WellFormedBasis basis') : WellFormedBasis basis :=
49+
⟨h_basis.left.sublist h, fun _ hf ↦ h_basis.right _ (h.subset hf)⟩
50+
51+
/-- The tail of a well-formed basis is well-formed. -/
52+
theorem tail {basis_hd : ℝ → ℝ} {basis_tl : Basis}
53+
(h : WellFormedBasis (basis_hd :: basis_tl)) : WellFormedBasis basis_tl :=
54+
h.of_sublist (by simp)
55+
56+
theorem of_append_right {left right : Basis} (h : WellFormedBasis (left ++ right)) :
57+
WellFormedBasis right :=
58+
h.of_sublist (by simp)
59+
60+
theorem compare_left_aux {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
61+
(h_comp : ∀ g, basis.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) :
62+
∀ g ∈ basis, (Real.log ∘ f) =o[atTop] (Real.log ∘ g) := by
63+
intro g hg
64+
rcases basis.eq_nil_or_concat with rfl | ⟨basis_begin, basis_end, rfl⟩
65+
· simp at hg
66+
simp only [List.concat_eq_append, List.mem_append, List.mem_cons, List.not_mem_nil, or_false,
67+
List.getLast?_append, List.getLast?_singleton, Option.some_or, Option.some.injEq,
68+
forall_eq'] at hg h_comp
69+
rcases hg with hg | hg
70+
· simp only [WellFormedBasis, List.concat_eq_append, List.mem_append, List.mem_cons,
71+
List.not_mem_nil, or_false] at h
72+
exact h_comp.trans (by grind)
73+
· grind
74+
75+
theorem compare_right_aux {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
76+
(h_comp : ∀ g, basis.head? = .some g → (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
77+
∀ g ∈ basis, (Real.log ∘ g) =o[atTop] (Real.log ∘ f) := by
78+
intro g hg
79+
cases basis with
80+
| nil => simp at hg
81+
| cons basis_hd basis_tl =>
82+
specialize h_comp basis_hd (by simp)
83+
simp only [List.mem_cons] at hg
84+
rcases hg with hg | hg
85+
· simpa [hg]
86+
· simp only [WellFormedBasis, List.pairwise_cons, List.mem_cons, forall_eq_or_imp] at h
87+
exact .trans (by grind) h_comp
88+
89+
theorem append {left right : Basis}
90+
(h_left : WellFormedBasis left) (h_right : WellFormedBasis right)
91+
(h : ∀ f ∈ left, ∀ g ∈ right, (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
92+
WellFormedBasis (left ++ right) := by
93+
simp only [WellFormedBasis] at *
94+
constructor
95+
· simpa [List.pairwise_append, h_left, h_right] using h
96+
· grind
97+
98+
theorem cons {basis : Basis} {f : ℝ → ℝ} (h_basis : WellFormedBasis basis)
99+
(hf_tendsto : Tendsto f atTop atTop)
100+
(hf : ∀ g ∈ basis, (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
101+
WellFormedBasis (f :: basis) := by
102+
change WellFormedBasis ([f] ++ basis)
103+
exact append (by simpa [WellFormedBasis]) h_basis (by simpa)
104+
105+
theorem insert {left right : Basis} {f : ℝ → ℝ}
106+
(h : WellFormedBasis (left ++ right)) (hf_tendsto : Tendsto f atTop atTop)
107+
(hf_comp_left : ∀ g, left.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g))
108+
(hf_comp_right : ∀ g, right.head? = .some g → (Real.log ∘ g) =o[atTop] (Real.log ∘ f)) :
109+
WellFormedBasis (left ++ f :: right) := by
110+
have : WellFormedBasis (f :: right) := cons (h.of_sublist (by simp)) hf_tendsto
111+
(compare_right_aux (h.of_sublist (by simp)) hf_comp_right)
112+
apply compare_left_aux (h.of_sublist (by simp)) at hf_comp_left
113+
apply append (h.of_sublist (by simp)) this
114+
exact fun g hg ↦ compare_right_aux this (by grind)
115+
116+
theorem push {basis : Basis} {f : ℝ → ℝ} (h : WellFormedBasis basis)
117+
(hf_tendsto : Tendsto f atTop atTop)
118+
(hf_comp : ∀ g, basis.getLast? = .some g → (Real.log ∘ f) =o[atTop] (Real.log ∘ g)) :
119+
WellFormedBasis (basis ++ [f]) :=
120+
insert (by simp [h]) hf_tendsto hf_comp (by simp)
121+
122+
/-- All functions from a well-formed basis tend to `atTop`. -/
123+
theorem tendsto_atTop {basis : Basis} (h : WellFormedBasis basis) {f : ℝ → ℝ}
124+
(hf : f ∈ basis) :
125+
Tendsto f atTop atTop := h.right f hf
126+
127+
/-- Eventually all functions from a well-formed basis are positive. -/
128+
theorem eventually_pos {basis : Basis} (h : WellFormedBasis basis) :
129+
∀ᶠ x in atTop, ∀ f ∈ basis, 0 < f x := by
130+
induction basis with
131+
| nil => simp
132+
| cons hd tl ih =>
133+
simp only [WellFormedBasis, List.pairwise_cons, List.mem_cons, forall_eq_or_imp] at h
134+
simp only [List.mem_cons, forall_eq_or_imp]
135+
exact (h.right.left.eventually <| eventually_gt_atTop 0).and (ih (by tauto))
136+
137+
/-- The first function in a well-formed basis is eventually positive. -/
138+
theorem head_eventually_pos {basis_hd : ℝ → ℝ} {basis_tl : Basis}
139+
(h : WellFormedBasis (basis_hd :: basis_tl)) : ∀ᶠ x in atTop, 0 < basis_hd x :=
140+
(forall_eventually_of_eventually_forall h.eventually_pos basis_hd).mono (by grind)
141+
142+
/-- All functions in the tail of a well-formed basis are little-o of the basis' head. -/
143+
theorem tail_isLittleO_head {hd : ℝ → ℝ} {tl : Basis}
144+
(h : WellFormedBasis (hd :: tl)) {f : ℝ → ℝ} (hf : f ∈ tl) :
145+
(Real.log ∘ f) =o[atTop] (Real.log ∘ hd) := by
146+
rw [WellFormedBasis, List.pairwise_cons] at h
147+
exact h.left.left _ hf
148+
149+
theorem push_log_last {basis_hd : ℝ → ℝ} {basis_tl : Basis}
150+
(h_basis : WellFormedBasis (basis_hd :: basis_tl)) :
151+
WellFormedBasis ((basis_hd :: basis_tl) ++
152+
[Real.log ∘ (basis_hd :: basis_tl).getLast (by simp)]) := by
153+
apply h_basis.push
154+
· simp [Real.tendsto_log_atTop.comp, h_basis.right]
155+
· intro g hg
156+
simpa [List.getLast_of_getLast?_eq_some hg] using Real.isLittleO_log_id_atTop.comp_tendsto <|
157+
Real.tendsto_log_atTop.comp <| h_basis.tendsto_atTop <| List.mem_of_getLast? hg
158+
159+
end WellFormedBasis
160+
161+
/-! ### Basis extensions -/
162+
163+
/-- The type of extensions of a given basis, defined as an inductive type.
164+
Given a `basis : Basis` and `ex : BasisExtension basis` of it, one can use `getBasis` to produce a
165+
basis `basis'` for which `basis <+ basis'`. Moreover, all such bases for which `basis` is a sublist
166+
can be obtained in this manner. In this sense `BasisExtension` is a `Type`-valued analogue
167+
of `List.Sublist`. -/
168+
inductive BasisExtension : Basis → Type
169+
| nil : BasisExtension []
170+
| keep (basis_hd : ℝ → ℝ) {basis_tl : Basis} (ex : BasisExtension basis_tl) :
171+
BasisExtension (basis_hd :: basis_tl)
172+
| insert {basis : Basis} (f : ℝ → ℝ) (ex : BasisExtension basis) : BasisExtension basis
173+
174+
namespace BasisExtension
175+
176+
/-- The basis after applying a basis extension. -/
177+
def getBasis {basis : Basis} (ex : BasisExtension basis) : Basis :=
178+
match ex with
179+
| nil => []
180+
| keep basis_hd ex => basis_hd :: ex.getBasis
181+
| insert f ex => f :: ex.getBasis
182+
183+
theorem sublist_getBasis {basis : Basis} {ex : BasisExtension basis} :
184+
List.Sublist basis ex.getBasis := by
185+
induction ex with
186+
| nil => simp
187+
| keep _ ex ih => simpa [getBasis] using ih
188+
| insert _ ex ih => exact List.Sublist.cons _ ih
189+
190+
theorem insert_tail_wellFormedBasis {basis : Basis} {f : ℝ → ℝ}
191+
{ex_tl : BasisExtension basis}
192+
(h_basis : WellFormedBasis <| BasisExtension.getBasis (.insert f ex_tl)) :
193+
WellFormedBasis ex_tl.getBasis :=
194+
h_basis.of_sublist (by simp [getBasis])
195+
196+
end BasisExtension
197+
198+
end Tactic.ComputeAsymptotics

0 commit comments

Comments
 (0)