Skip to content

Commit e963315

Browse files
committed
feat: further extensions of the differential geometry elaborators (#30413)
Also infer the model with corners on - a space of continuous linear equivalences - a closed real interval (Set.Icc) - the complex upper half plane And add elaborators for `HasMFDeriv(Within)At` analogous to the `mfderiv(Within)` ones. Further cases, as well as products, disjoint unions or open subsets, will be covered in future PRs.
1 parent 9859788 commit e963315

File tree

3 files changed

+498
-27
lines changed

3 files changed

+498
-27
lines changed

Mathlib/Geometry/Manifold/Notation.lean

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,20 @@ All of these elaborators are scoped to the `Manifold` namespace.
2121
We provide compact notation for differentiability and continuous differentiability on manifolds,
2222
including inference of the model with corners.
2323
24-
| Notation | Elaborates to |
25-
|---------------------|-------------------------------------|
26-
| `MDiff f` | `MDifferentiable I J f` |
27-
| `MDiffAt f x` | `MDifferentiableAt I J f x` |
28-
| `MDiff[u] f` | `MDifferentiableOn I J f u` |
29-
| `MDiffAt[u] f x` | `MDifferentiableWithinAt I J f u x` |
30-
| `CMDiff n f` | `ContMDiff I J n f` |
31-
| `CMDiffAt n f x` | `ContMDiffAt I J n f x` |
32-
| `CMDiff[u] n f` | `ContMDiffOn I J n f u` |
33-
| `CMDiffAt[u] n f x` | `ContMDiffWithinAt I J n f u x` |
34-
| `mfderiv[u] f x` | `mfderivWithin I J f u x` |
35-
| `mfderiv% f x` | `mfderiv I J f x` |
24+
| Notation | Elaborates to |
25+
|--------------------------|-------------------------------------|
26+
| `MDiff f` | `MDifferentiable I J f` |
27+
| `MDiffAt f x` | `MDifferentiableAt I J f x` |
28+
| `MDiff[u] f` | `MDifferentiableOn I J f u` |
29+
| `MDiffAt[u] f x` | `MDifferentiableWithinAt I J f u x` |
30+
| `CMDiff n f` | `ContMDiff I J n f` |
31+
| `CMDiffAt n f x` | `ContMDiffAt I J n f x` |
32+
| `CMDiff[u] n f` | `ContMDiffOn I J n f u` |
33+
| `CMDiffAt[u] n f x` | `ContMDiffWithinAt I J n f u x` |
34+
| `mfderiv[u] f x` | `mfderivWithin I J f u x` |
35+
| `mfderiv% f x` | `mfderiv I J f x` |
36+
| `HasMFDerivAt[s] f x f'` | `HasMFDerivWithinAt I J f s x f'` |
37+
| `HasMFDerivAt% f x f'` | `HasMFDerivAt I J f x f'` |
3638
3739
In each of these cases, the models with corners are inferred from the domain and codomain of `f`.
3840
The search for models with corners uses the local context and is (almost) only based on expression
@@ -216,6 +218,9 @@ using the local context to infer the appropriate instance. This supports the fol
216218
- the model with corners on the total space of a vector bundle
217219
- the model with corners on the tangent space of a manifold
218220
- a model with corners on a manifold, or on its underlying model space
221+
- a closed interval of real numbers
222+
- the complex upper half plane
223+
- a space of continuous k-linear maps
219224
- the trivial model `𝓘(𝕜, E)` on a normed space
220225
- if the above are not found, try to find a `NontriviallyNormedField` instance on the type of `e`,
221226
and if successful, return `𝓘(𝕜)`.
@@ -239,11 +244,14 @@ This implementation is not maximally robust yet.
239244
-- TODO: consider lowering monad to `MetaM`
240245
def findModel (e : Expr) (baseInfo : Option (Expr × Expr) := none) : TermElabM Expr := do
241246
trace[Elab.DiffGeo.MDiff] "Finding a model for: {e}"
242-
if let some m ← tryStrategy m!"TotalSpace" fromTotalSpace then return m
243-
if let some m ← tryStrategy m!"TangentBundle" fromTangentBundle then return m
244-
if let some m ← tryStrategy m!"NormedSpace" fromNormedSpace then return m
245-
if let some m ← tryStrategy m!"Manifold" fromManifold then return m
246-
if let some m ← tryStrategy m!"NormedField" fromNormedField then return m
247+
if let some m ← tryStrategy m!"TotalSpace" fromTotalSpace then return m
248+
if let some m ← tryStrategy m!"TangentBundle" fromTangentBundle then return m
249+
if let some m ← tryStrategy m!"NormedSpace" fromNormedSpace then return m
250+
if let some m ← tryStrategy m!"Manifold" fromManifold then return m
251+
if let some m ← tryStrategy m!"ContinuousLinearMap" fromCLM then return m
252+
if let some m ← tryStrategy m!"RealInterval" fromRealInterval then return m
253+
if let some m ← tryStrategy m!"UpperHalfPlane" fromUpperHalfPlane then return m
254+
if let some m ← tryStrategy m!"NormedField" fromNormedField then return m
247255
throwError "Could not find a model with corners for `{e}`"
248256
where
249257
/- Note that errors thrown in the following are caught by `tryStrategy` and converted to trace
@@ -284,12 +292,12 @@ where
284292
let srcIT : Term ← Term.exprToSyntax I
285293
let resTerm : Term ← ``(ModelWithCorners.prod $srcIT (ModelWithCorners.tangent $srcIT))
286294
Term.elabTerm resTerm none
287-
| _ => throwError "{V} is not a `TangentSpace`"
295+
| _ => throwError "`{V}` is not a `TangentSpace`"
288296
/-- Attempt to find a model on a `TangentBundle` -/
289297
fromTangentBundle : TermElabM Expr := do
290298
match_expr e with
291299
| TangentBundle _k _ _E _ _ _H _ I M _ _ => do
292-
trace[Elab.DiffGeo.MDiff] "{e} is a `TangentBundle` over model `{I}` on `{M}`"
300+
trace[Elab.DiffGeo.MDiff] "`{e}` is a `TangentBundle` over model `{I}` on `{M}`"
293301
let srcIT : Term ← Term.exprToSyntax I
294302
let resTerm : Term ← ``(ModelWithCorners.tangent $srcIT)
295303
Term.elabTerm resTerm none
@@ -320,15 +328,61 @@ where
320328
trace[Elab.DiffGeo.MDiff] "`{e}` is the charted space of `{M}` via `{inst}`"
321329
return some H else return none
322330
| _ => return none
323-
| throwError "Couldn't find a `ChartedSpace` structure on {e} among local instances, \
324-
and {e} is not the charted space of some type in the local context either."
331+
| throwError "Couldn't find a `ChartedSpace` structure on `{e}` among local instances, \
332+
and `{e}` is not the charted space of some type in the local context either."
325333
let some m ← findSomeLocalHyp? fun fvar type ↦ do
326334
match_expr type with
327335
| ModelWithCorners _ _ _ _ _ H' _ => do
328336
if ← withReducible (pureIsDefEq H' H) then return some fvar else return none
329337
| _ => return none
330338
| throwError "Couldn't find a `ModelWithCorners` with model space `{H}` in the local context."
331339
return m
340+
/-- Attempt to find a model with corners on a space of continuous linear maps -/
341+
-- Note that (continuous) linear equivalences are not an abelian group, so are not a model with
342+
-- corners as a normed space. Merely linear maps are not a normed space either.
343+
fromCLM : TermElabM Expr := do
344+
match_expr e with
345+
| ContinuousLinearMap k S _ _ _σ _E _ _ _F _ _ _ _ =>
346+
trace[Elab.DiffGeo.MDiff] "`{e}` is a space of continuous linear maps"
347+
-- If `S` were a copy of `k` with a non-standard topology or smooth structure
348+
-- (such as, imposed deliberately through a type synonym), we do not want to infer
349+
-- the standard model with corners.
350+
-- Therefore, we only check definitional equality at reducible transparency.
351+
if ← withReducible <| isDefEq k S then
352+
-- TODO: check if σ is actually the identity!
353+
let eK : Term ← Term.exprToSyntax k
354+
let eT : Term ← Term.exprToSyntax e
355+
let iTerm : Term ← ``(𝓘($eK, $eT))
356+
Term.elabTerm iTerm none
357+
else
358+
throwError "Coefficients `{k}` and `{S}` of `{e}` are not reducibly definitionally equal"
359+
| _ => throwError "`{e}` is not a space of continuous linear maps"
360+
/-- Attempt to find a model with corners on a closed interval of real numbers -/
361+
fromRealInterval : TermElabM Expr := do
362+
let some e := (← instantiateMVars e).cleanupAnnotations.coeTypeSet?
363+
| throwError "`{e}` is not a coercion of a set to a type"
364+
-- We don't use `match_expr` here to avoid importing `Set.Icc`.
365+
-- Note that `modelWithCornersEuclideanHalfSpace` is also not imported.
366+
match e with
367+
| mkApp4 (.const `Set.Icc _) α _ _x _y =>
368+
-- If `S` were a copy of `k` with a non-standard topology or smooth structure
369+
-- (such as, imposed deliberately through a type synonym), we do not want to infer
370+
-- the standard model with corners.
371+
-- Therefore, we only check definitional equality at reducible transparency.
372+
if ← withReducible <| isDefEq α q(ℝ) then
373+
-- We need not check if `x < y` is a fact in the local context: Lean will verify this
374+
-- itself when trying to synthesize a ChartedSpace instance.
375+
mkAppOptM `modelWithCornersEuclideanHalfSpace #[q(1 : ℕ), none]
376+
else throwError "`{e}` is a closed interval of type `{α}`, \
377+
which is not reducibly definitionally equal to ℝ"
378+
| _ => throwError "`{e}` is not a closed real interval"
379+
/-- Attempt to find a model with corners on the upper half plane in complex space -/
380+
fromUpperHalfPlane : TermElabM Expr := do
381+
-- We don't use `match_expr` to avoid importing `UpperHalfPlane`.
382+
if (← instantiateMVars e).cleanupAnnotations.isConstOf `UpperHalfPlane then
383+
let c ← Term.exprToSyntax (mkConst `Complex)
384+
Term.elabTerm (← `(𝓘($c))) none
385+
else throwError "`{e}` is not the complex upper half plane"
332386
/-- Attempt to find a model with corners from a normed field.
333387
We attempt to find a global instance here. -/
334388
fromNormedField : TermElabM Expr := do
@@ -395,7 +449,7 @@ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do
395449
-- if let some src := src[0]? then
396450
-- let srcI ← findModel (← inferType src)
397451
-- if Lean.Expr.occurs src tgt then
398-
-- throwErrorAt t "Term {e} is a dependent function, of type {etype}\n\
452+
-- throwErrorAt t "Term `{e}` is a dependent function, of type `{etype}`\n\
399453
-- Hint: you can use the `T%` elaborator to convert a dependent function \
400454
-- to a non-dependent one"
401455
-- let tgtI ← findModel tgt (src, srcI)
@@ -478,6 +532,27 @@ scoped elab:max "mfderiv%" ppSpace t:term:arg : term => do
478532
let (srcI, tgtI) ← findModels e none
479533
mkAppM ``mfderiv #[srcI, tgtI, e]
480534

535+
/-- `HasMFDerivAt[s] f x f'` elaborates to `HasMFDerivWithinAt I J f s x f'`,
536+
trying to determine `I` and `J` from the local context. -/
537+
scoped elab:max "HasMFDerivAt[" s:term "]" ppSpace
538+
f:term:arg ppSpace x:term:arg ppSpace f':term:arg : term => do
539+
let es ← Term.elabTerm s none
540+
let ef ← ensureIsFunction <|← Term.elabTerm f none
541+
let ex ← Term.elabTerm x none
542+
let ef' ← Term.elabTerm f' none
543+
let (srcI, tgtI) ← findModels ef es
544+
mkAppM ``HasMFDerivWithinAt #[srcI, tgtI, ef, es, ex, ef']
545+
546+
/-- `HasMFDerivAt% f x f'` elaborates to `HasMFDerivAt I J f x f'`,
547+
trying to determine `I` and `J` from the local context. -/
548+
scoped elab:max "HasMFDerivAt%" ppSpace
549+
f:term:arg ppSpace x:term:arg ppSpace f':term:arg : term => do
550+
let ef ← ensureIsFunction <|← Term.elabTerm f none
551+
let ex ← Term.elabTerm x none
552+
let ef' ← Term.elabTerm f' none
553+
let (srcI, tgtI) ← findModels ef none
554+
mkAppM ``HasMFDerivAt #[srcI, tgtI, ef, ex, ef']
555+
481556
end Manifold
482557

483558
section trace

MathlibTest/DifferentialGeometry/Notation.lean

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,16 @@ trace: [Elab.DiffGeo.MDiff] Finding a model for: Unit
901901
[Elab.DiffGeo.MDiff] ❌️ Manifold
902902
[Elab.DiffGeo.MDiff] considering instance of type `ChartedSpace H M`
903903
[Elab.DiffGeo.MDiff] Failed with error:
904-
Couldn't find a `ChartedSpace` structure on Unit among local instances, and Unit is not the charted space of some type in the local context either.
904+
Couldn't find a `ChartedSpace` structure on `Unit` among local instances, and `Unit` is not the charted space of some type in the local context either.
905+
[Elab.DiffGeo.MDiff] ❌️ ContinuousLinearMap
906+
[Elab.DiffGeo.MDiff] Failed with error:
907+
`Unit` is not a space of continuous linear maps
908+
[Elab.DiffGeo.MDiff] ❌️ RealInterval
909+
[Elab.DiffGeo.MDiff] Failed with error:
910+
`Unit` is not a coercion of a set to a type
911+
[Elab.DiffGeo.MDiff] ❌️ UpperHalfPlane
912+
[Elab.DiffGeo.MDiff] Failed with error:
913+
`Unit` is not the complex upper half plane
905914
[Elab.DiffGeo.MDiff] ❌️ NormedField
906915
[Elab.DiffGeo.MDiff] Failed with error:
907916
failed to synthesize

0 commit comments

Comments
 (0)