Skip to content

Commit a844008

Browse files
vasnesterovReemMelamed
authored andcommitted
feat(Tactic/ComputeAsymptotics/Multiseries): basic constructions (leanprover-community#40014)
Introduce basic constructions for multiseries: `const`, `monomial`, `monomialRpow`.
1 parent 29e1694 commit a844008

4 files changed

Lines changed: 290 additions & 1 deletion

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7199,6 +7199,7 @@ public import Mathlib.Tactic.ClickSuggestions.Util
71997199
public import Mathlib.Tactic.Coe
72007200
public import Mathlib.Tactic.Common
72017201
public import Mathlib.Tactic.ComputeAsymptotics.Lemmas
7202+
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basic
72027203
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis
72037204
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion
72047205
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs

Mathlib/Tactic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public import Mathlib.Tactic.ClickSuggestions.Util
6868
public import Mathlib.Tactic.Coe
6969
public import Mathlib.Tactic.Common
7070
public import Mathlib.Tactic.ComputeAsymptotics.Lemmas
71+
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basic
7172
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis
7273
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion
7374
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
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+
8+
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs
9+
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Basis
10+
11+
/-!
12+
# Basic constructions for multiseries
13+
14+
## Main definitions
15+
16+
Let `[b₁, ..., bₙ]` be our basis.
17+
18+
* `const c` represents a constant multiseries `c • b₁⁰ ... bₙ⁰`.
19+
Then we define `zero` and `one` in terms of it.
20+
* `monomial k` represents a monomial `bₖ`.
21+
* `monomialRpow k r` represents a monomial `bₖʳ`.
22+
23+
For each construction, we provide two definitions: one for `Multiseries` and one for
24+
`MultiseriesExpansion`. We then prove structural `simp`-lemmas describing their relationships with
25+
`MultiseriesExpansion.seq` and `MultiseriesExpansion.toFun`. Finally, we prove that all
26+
constructions are `Sorted` and `Approximates` their attached functions.
27+
28+
-/
29+
30+
@[expose] public section
31+
32+
namespace Tactic.ComputeAsymptotics
33+
34+
namespace MultiseriesExpansion
35+
36+
open Filter Stream' Topology
37+
38+
mutual
39+
40+
/-- `Multiseries`-part of `MultiseriesExpansion.const`. -/
41+
def Multiseries.const (basis_hd : ℝ → ℝ) (basis_tl : Basis) (c : ℝ) :
42+
Multiseries basis_hd basis_tl :=
43+
.cons 0 (const basis_tl c) .nil
44+
45+
/-- Multiseries representing a constant. -/
46+
def const (basis : Basis) (c : ℝ) : MultiseriesExpansion basis :=
47+
match basis with
48+
| [] => ofReal c
49+
| List.cons basis_hd basis_tl => mk (Multiseries.const basis_hd basis_tl c) (fun _ ↦ c)
50+
51+
end
52+
53+
/-- Neutral element for addition. It is `0 : ℝ` for the empty basis and `[]` otherwise. -/
54+
def zero {basis : Basis} : MultiseriesExpansion basis :=
55+
match basis with
56+
| [] => ofReal 0
57+
| List.cons _ _ => mk .nil (fun _ ↦ 0)
58+
59+
/-- This instance is needed to create an instance for `AddCommMonoid (MultiseriesExpansion basis)`,
60+
which is necessary for using the `abel` tactic in our proofs. -/
61+
instance {basis : Basis} : Zero (MultiseriesExpansion basis) where
62+
zero := zero
63+
64+
/-- This instance is needed to create an instance for `AddCommMonoid (MultiseriesExpansion basis)`,
65+
which is necessary for using the `abel` tactic in our proofs. -/
66+
instance {basis_hd : ℝ → ℝ} {basis_tl : Basis} : Zero (Multiseries basis_hd basis_tl) where
67+
zero := .nil
68+
69+
/-- `Multiseries`-part of `MultiseriesExpansion.one`. -/
70+
def Multiseries.one {basis_hd : ℝ → ℝ} {basis_tl : Basis} : Multiseries basis_hd basis_tl :=
71+
Multiseries.const _ _ 1
72+
73+
/-- Neutral element for multiplication. -/
74+
def one {basis : Basis} : MultiseriesExpansion basis :=
75+
const basis 1
76+
77+
mutual
78+
79+
/-- `Multiseries`-part of `MultiseriesExpansion.monomialRpow`. -/
80+
noncomputable def Multiseries.monomialRpow (basis_hd : ℝ → ℝ) (basis_tl : Basis) (n : ℕ) (r : ℝ) :
81+
Multiseries basis_hd basis_tl :=
82+
match n with
83+
| 0 => .cons r one .nil
84+
| m + 1 => .cons 0 (monomialRpow _ m r) .nil
85+
86+
/-- Multiseries representing `basis[n] ^ r`. -/
87+
noncomputable def monomialRpow (basis : Basis) (n : ℕ) (r : ℝ) : MultiseriesExpansion basis :=
88+
match basis with
89+
| [] => default
90+
| List.cons basis_hd basis_tl =>
91+
mk (Multiseries.monomialRpow _ _ n r) ((basis_hd :: basis_tl)[n]! ^ r)
92+
93+
end
94+
95+
/-- `Multiseries`-part of `MultiseriesExpansion.monomial`. -/
96+
noncomputable def Multiseries.monomial (basis_hd : ℝ → ℝ) (basis_tl : Basis) (n : ℕ) :
97+
Multiseries basis_hd basis_tl :=
98+
Multiseries.monomialRpow _ _ n 1
99+
100+
/-- Multiseries representing `basis[n]`. -/
101+
noncomputable def monomial (basis : Basis) (n : ℕ) : MultiseriesExpansion basis :=
102+
monomialRpow _ n 1
103+
104+
theorem zero_def {basis_hd basis_tl} :
105+
(0 : MultiseriesExpansion (basis_hd :: basis_tl)) = mk .nil (fun _ ↦ 0) :=
106+
rfl
107+
108+
@[simp]
109+
theorem Multiseries.zero_def {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
110+
(0 : Multiseries basis_hd basis_tl) = .nil := rfl
111+
112+
theorem Multiseries.const_def {basis_hd basis_tl} (c : ℝ) :
113+
Multiseries.const basis_hd basis_tl c =
114+
Multiseries.cons 0 (MultiseriesExpansion.const basis_tl c) .nil := by
115+
simp [Multiseries.const]
116+
117+
@[simp]
118+
theorem const_toFun' {basis : Basis} {c : ℝ} : (const basis c).toFun = fun _ ↦ c := by
119+
match basis with
120+
| [] => simp [const, ofReal, toReal]
121+
| List.cons _ _ => simp [const]
122+
123+
@[simp]
124+
theorem const_seq {basis_hd basis_tl} {c : ℝ} :
125+
(const (basis_hd :: basis_tl) c).seq = Multiseries.const basis_hd basis_tl c := by
126+
simp [const, Multiseries.const]
127+
128+
@[simp]
129+
theorem zero_toFun {basis : Basis} : (@zero basis).toFun = 0 := by
130+
match basis with
131+
| [] => rfl
132+
| List.cons _ _ => rfl
133+
134+
theorem Multiseries.one_def {basis_hd basis_tl} :
135+
@Multiseries.one basis_hd basis_tl = Multiseries.cons 0 MultiseriesExpansion.one .nil := by
136+
simp [Multiseries.one, Multiseries.const_def, MultiseriesExpansion.one]
137+
138+
@[simp]
139+
theorem one_toFun {basis : Basis} : (@one basis).toFun = 1 := by
140+
simp [one]
141+
rfl
142+
143+
@[simp]
144+
theorem one_seq {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
145+
(@one (basis_hd :: basis_tl)).seq = Multiseries.one := by
146+
simp [one, Multiseries.one, const]
147+
148+
mutual
149+
150+
theorem Multiseries.const_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} {c : ℝ} :
151+
(Multiseries.const basis_hd basis_tl c).Sorted := by
152+
simp only [Multiseries.const]
153+
exact const_sorted.cons_nil
154+
155+
/-- Constants are well-ordered. -/
156+
theorem const_sorted {basis : Basis} {c : ℝ} :
157+
(const basis c).Sorted := by
158+
cases basis with
159+
| nil => constructor
160+
| cons basis_hd basis_tl =>
161+
simpa only [const, sorted_iff_seq_sorted, mk_seq] using Multiseries.const_sorted
162+
163+
end
164+
165+
/-- Zero is well-ordered. -/
166+
theorem zero_sorted {basis : Basis} : (0 : MultiseriesExpansion basis).Sorted := by
167+
cases basis with
168+
| nil => constructor
169+
| cons => apply Sorted.nil
170+
171+
theorem Multiseries.one_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} :
172+
(Multiseries.one : Multiseries basis_hd basis_tl).Sorted :=
173+
Multiseries.const_sorted
174+
175+
/-- `one` is Sorted. -/
176+
theorem one_sorted {basis : Basis} : one.Sorted (basis := basis) :=
177+
const_sorted
178+
179+
/-- The constant multiseries approximates the constant function. -/
180+
theorem const_approximates {c : ℝ} {basis : Basis} (h_basis : WellFormedBasis basis) :
181+
(const basis c).Approximates := by
182+
cases basis with
183+
| nil => simp
184+
| cons basis_hd basis_tl =>
185+
simp only [const, Multiseries.const]
186+
apply (const_approximates h_basis.tail).cons _ (by simp)
187+
exact Majorized.const <| h_basis.tendsto_atTop (by simp)
188+
189+
/-- `zero` approximates the zero function. -/
190+
theorem zero_approximates {basis : Basis} :
191+
(@zero basis).Approximates := by
192+
cases basis with
193+
| nil => simp [zero]
194+
| cons => exact Approximates.nil (by rfl)
195+
196+
/-- `one` approximates the unit function. -/
197+
theorem one_approximates {basis : Basis} (h_basis : WellFormedBasis basis) :
198+
(@one basis).Approximates :=
199+
const_approximates h_basis
200+
201+
@[simp]
202+
theorem monomialRpow_toFun {basis : Basis} {n : Fin (List.length basis)} {r : ℝ} :
203+
(monomialRpow basis n r).toFun = basis[n] ^ r := by
204+
cases basis with
205+
| nil => grind
206+
| cons basis_hd basis_tl => cases n using Fin.cases <;> simp [monomialRpow]
207+
208+
@[simp]
209+
theorem monomialRpow_seq {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} {r : ℝ} :
210+
(monomialRpow (basis_hd :: basis_tl) n r).seq = Multiseries.monomialRpow _ _ n r := by
211+
simp [monomialRpow]
212+
213+
mutual
214+
215+
theorem Multiseries.monomialRpow_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} {r : ℝ} :
216+
(@Multiseries.monomialRpow basis_hd basis_tl n r).Sorted := by
217+
cases n with
218+
| zero =>
219+
simp only [Multiseries.monomialRpow]
220+
exact Sorted.cons_nil const_sorted
221+
| succ m =>
222+
simp only [Multiseries.monomialRpow]
223+
exact Sorted.cons_nil monomialRpow_sorted
224+
225+
/-- `monomial` is well-ordered. -/
226+
theorem monomialRpow_sorted {basis : Basis} {n : ℕ} {r : ℝ} :
227+
(monomialRpow basis n r).Sorted := by
228+
cases basis with
229+
| nil => constructor
230+
| cons basis_hd basis_tl =>
231+
simpa only [sorted_iff_seq_sorted, monomialRpow_seq] using Multiseries.monomialRpow_sorted
232+
233+
end
234+
235+
/-- `monomialRpow` approximates the monomial function. -/
236+
theorem monomialRpow_approximates {basis : Basis} {n : Fin (List.length basis)} {r : ℝ}
237+
(h_basis : WellFormedBasis basis) :
238+
(monomialRpow basis n r).Approximates := by
239+
cases basis with
240+
| nil => simp
241+
| cons basis_hd basis_tl =>
242+
simp only [List.length_cons, monomialRpow, Fin.is_lt, getElem!_pos]
243+
cases n using Fin.cases with
244+
| zero =>
245+
simp only [Fin.coe_ofNat_eq_mod, Nat.zero_mod, Multiseries.monomialRpow,
246+
List.getElem_cons_zero]
247+
apply (one_approximates h_basis.tail).cons _ (by simp)
248+
exact Majorized.self <| h_basis.tendsto_atTop (by simp)
249+
| succ m =>
250+
simp only [Fin.val_succ, Multiseries.monomialRpow, List.getElem_cons_succ]
251+
apply (monomialRpow_approximates h_basis.tail).cons _ (by simp)
252+
apply h_basis.tail_pow_majorized_head (by simp)
253+
254+
@[simp]
255+
theorem monomial_toFun {basis : Basis} {n : ℕ} (h : n < basis.length) :
256+
(monomial basis n).toFun = basis[n] := by
257+
let n' : Fin basis.length := ⟨n, h⟩
258+
conv_lhs => rw [show n = n'.val by simp [n']]
259+
convert! monomialRpow_toFun
260+
simp
261+
grind
262+
263+
theorem monomial_toFun' {basis : Basis} {n : Fin basis.length} :
264+
(monomial basis n).toFun = basis[n] := by
265+
simp
266+
267+
@[simp]
268+
theorem monomial_seq {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} :
269+
(monomial (basis_hd :: basis_tl) n).seq = Multiseries.monomial _ _ n :=
270+
monomialRpow_seq
271+
272+
theorem Multiseries.monomial_sorted {basis_hd : ℝ → ℝ} {basis_tl : Basis} {n : ℕ} :
273+
(@Multiseries.monomial basis_hd basis_tl n).Sorted :=
274+
Multiseries.monomialRpow_sorted
275+
276+
/-- `monomial` is well-ordered. -/
277+
theorem monomial_sorted {basis : Basis} {n : ℕ} : (monomial basis n).Sorted :=
278+
monomialRpow_sorted
279+
280+
/-- `monomial` approximates the monomial function. -/
281+
theorem monomial_approximates {basis : Basis} {n : Fin (List.length basis)}
282+
(h_basis : WellFormedBasis basis) : (monomial basis n).Approximates :=
283+
monomialRpow_approximates h_basis
284+
285+
end MultiseriesExpansion
286+
287+
end Tactic.ComputeAsymptotics

Mathlib/Tactic/ComputeAsymptotics/Multiseries/Basis.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Vasilii Nesterov
55
-/
66
module
7-
public import Mathlib.Analysis.Complex.Exponential
7+
88
public import Mathlib.Analysis.Asymptotics.AsymptoticEquivalent
99
public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal
1010
public import Mathlib.Tactic.ComputeAsymptotics.Multiseries.Defs

0 commit comments

Comments
 (0)