@@ -21,18 +21,20 @@ All of these elaborators are scoped to the `Manifold` namespace.
2121We provide compact notation for differentiability and continuous differentiability on manifolds,
2222including 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
3739In each of these cases, the models with corners are inferred from the domain and codomain of `f`.
3840The 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`
240245def 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}`"
248256where
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+
481556end Manifold
482557
483558section trace
0 commit comments