@@ -67,7 +67,7 @@ variable {s : E → E'} in
6767These elaborators can be combined: `CMDiffAt[u] n (T% s) x`
6868
6969**Warning.** These elaborators are a proof of concept; the implementation should be considered a
70- prototype. Don't rewrite all of mathlib to use it just yet. Notable bugs and limitations include
70+ prototype. Don't rewrite all of mathlib to use it just yet. Notable limitations include
7171the following.
7272
7373## TODO
@@ -76,10 +76,8 @@ the following.
7676 is correct 90% of the time).
7777 For products of vector spaces `E × F`, this could print a warning about making a choice between
7878 the model in `E × F` and the product of the models on `E` and `F`.
79- - extend the elaborators to support `OpenPartialHomeomorph`s and `PartialEquiv`s
80- - better error messages (as needed)
81- - further testing and fixing of edge cases
82- - add tests for all of the above
79+ - better error messages (as needed), with tests
80+ - further testing and fixing of edge cases (with tests)
8381- add delaborators for these elaborators
8482
8583 -/
@@ -102,7 +100,7 @@ private def findSomeLocalInstanceOf? (c : Name) {α} (p : Expr → Expr → Meta
102100 MetaM (Option α) := do
103101 (← getLocalInstances).findSomeM? fun inst ↦ do
104102 if inst.className == c then
105- let type ← whnfR <|← instantiateMVars <|← inferType inst.fvar
103+ let type ← whnfR <| ← instantiateMVars <| ← inferType inst.fvar
106104 p inst.fvar type
107105 else return none
108106
@@ -112,7 +110,7 @@ to `p`. -/
112110private def findSomeLocalHyp? {α} (p : Expr → Expr → MetaM (Option α)) : MetaM (Option α) := do
113111 (← getLCtx).findDeclRevM? fun decl ↦ do
114112 if decl.isImplementationDetail then return none
115- let type ← whnfR <|← instantiateMVars decl.type
113+ let type ← whnfR <| ← instantiateMVars decl.type
116114 p decl.toExpr type
117115
118116end Elab
134132-- TODO: factor out `MetaM` component for reuse
135133scoped elab :max "T% " t:term:arg : term => do
136134 let e ← Term.elabTerm t none
137- let etype ← whnf <|← instantiateMVars <|← inferType e
135+ let etype ← whnf <| ← instantiateMVars <| ← inferType e
138136 match etype with
139137 | .forallE x base tgt _ => withLocalDeclD x base fun x ↦ do
140138 let tgtHasLooseBVars := tgt.hasLooseBVars
@@ -319,7 +317,7 @@ We pass `e` instead of just its type for better diagnostics.
319317
320318If `es` is `some`, we verify that `src` and the type of `es` are definitionally equal. -/
321319def findModels (e : Expr) (es : Option Expr) : TermElabM (Expr × Expr) := do
322- let etype ← whnf <|← instantiateMVars <|← inferType e
320+ let etype ← whnf <| ← instantiateMVars <| ← inferType e
323321 match etype with
324322 | .forallE _ src tgt _ =>
325323 if tgt.hasLooseBVars then
@@ -332,7 +330,7 @@ def findModels (e : Expr) (es : Option Expr) : TermElabM (Expr × Expr) := do
332330 /- Note: we use `isDefEq` here since persistent metavariable assignments in `src` and
333331 `estype` are acceptable.
334332 TODO: consider attempting to coerce `es` to a `Set`. -/
335- if !(← isDefEq estype <|← mkAppM ``Set #[src]) then
333+ if !(← isDefEq estype <| ← mkAppM ``Set #[src]) then
336334 throwError "The domain {src} of {e} is not definitionally equal to the carrier type of \
337335 the set {es} : {estype}"
338336 let tgtI ← findModel tgt (src, srcI)
@@ -348,15 +346,15 @@ trying to determine `I` and `J` from the local context.
348346The argument `x` can be omitted. -/
349347scoped elab :max "MDiffAt[" s:term "]" ppSpace f:term:arg : term => do
350348 let es ← Term.elabTerm s none
351- let ef ← Term.elabTerm f none
349+ let ef ← ensureIsFunction <| ← Term.elabTerm f none
352350 let (srcI, tgtI) ← findModels ef es
353351 mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es]
354352
355353/-- `MDiffAt f x` elaborates to `MDifferentiableAt I J f x`,
356354trying to determine `I` and `J` from the local context.
357355The argument `x` can be omitted. -/
358356scoped elab :max "MDiffAt" ppSpace t:term:arg : term => do
359- let e ← Term.elabTerm t none
357+ let e ← ensureIsFunction <| ← Term.elabTerm t none
360358 let (srcI, tgtI) ← findModels e none
361359 mkAppM ``MDifferentiableAt #[srcI, tgtI, e]
362360
@@ -366,7 +364,7 @@ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do
366364-- The argument `x` can be omitted. -/
367365-- scoped elab:max "MDiffAt2" ppSpace t:term:arg : term => do
368366-- let e ← Term.elabTerm t none
369- -- let etype ← whnfR <|← instantiateMVars <|← inferType e
367+ -- let etype ← whnfR <| ← instantiateMVars <| ← inferType e
370368-- forallBoundedTelescope etype (some 1) fun src tgt ↦ do
371369-- if let some src := src[ 0 ] ? then
372370-- let srcI ← findModel (← inferType src)
@@ -383,25 +381,30 @@ scoped elab:max "MDiffAt" ppSpace t:term:arg : term => do
383381trying to determine `I` and `J` from the local context. -/
384382scoped elab :max "MDiff[" s:term "]" ppSpace t:term:arg : term => do
385383 let es ← Term.elabTerm s none
386- let et ← Term.elabTerm t none
384+ let et ← ensureIsFunction <| ← Term.elabTerm t none
387385 let (srcI, tgtI) ← findModels et es
388386 mkAppM ``MDifferentiableOn #[srcI, tgtI, et, es]
389387
390388/-- `MDiff f` elaborates to `MDifferentiable I J f`,
391389trying to determine `I` and `J` from the local context. -/
392390scoped elab :max "MDiff" ppSpace t:term:arg : term => do
393- let e ← Term.elabTerm t none
391+ let e ← ensureIsFunction <| ← Term.elabTerm t none
394392 let (srcI, tgtI) ← findModels e none
395393 mkAppM ``MDifferentiable #[srcI, tgtI, e]
396394
395+ -- We ensure the type of `n` before checking `f` is a function to provide better error messages
396+ -- in case e.g. `f` and `n` are swapped.
397+ -- TODO: provide better error messages if just `n` is forgotten (say, by making `n` optional in
398+ -- the parser and erroring later in the elaborator); currently, this yields just a parser error.
399+
397400/-- `CMDiffAt[s] n f x` elaborates to `ContMDiffWithinAt I J n f s x`,
398401trying to determine `I` and `J` from the local context.
399402`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported).
400403The argument `x` can be omitted. -/
401404scoped elab :max "CMDiffAt[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do
402405 let es ← Term.elabTerm s none
403- let ef ← Term.elabTerm f none
404406 let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞)
407+ let ef ← ensureIsFunction <| ← Term.elabTerm f none
405408 let (srcI, tgtI) ← findModels ef es
406409 mkAppM ``ContMDiffWithinAt #[srcI, tgtI, ne, ef, es]
407410
@@ -410,7 +413,7 @@ trying to determine `I` and `J` from the local context.
410413`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported).
411414The argument `x` can be omitted. -/
412415scoped elab :max "CMDiffAt" ppSpace nt:term:arg ppSpace t:term:arg : term => do
413- let e ← Term.elabTerm t none
416+ let e ← ensureIsFunction <| ← Term.elabTerm t none
414417 let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞)
415418 let (srcI, tgtI) ← findModels e none
416419 mkAppM ``ContMDiffAt #[srcI, tgtI, ne, e]
@@ -420,32 +423,32 @@ trying to determine `I` and `J` from the local context.
420423`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/
421424scoped elab :max "CMDiff[" s:term "]" ppSpace nt:term:arg ppSpace f:term:arg : term => do
422425 let es ← Term.elabTerm s none
423- let ef ← Term.elabTerm f none
424426 let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞)
427+ let ef ← ensureIsFunction <| ← Term.elabTerm f none
425428 let (srcI, tgtI) ← findModels ef es
426429 mkAppM ``ContMDiffOn #[srcI, tgtI, ne, ef, es]
427430
428431/-- `CMDiff n f` elaborates to `ContMDiff I J n f`,
429432trying to determine `I` and `J` from the local context.
430433`n` is coerced to `WithTop ℕ∞` if necessary (so passing a `ℕ`, `∞` or `ω` are all supported). -/
431434scoped elab :max "CMDiff" ppSpace nt:term:arg ppSpace f:term:arg : term => do
432- let e ← Term.elabTerm f none
433435 let ne ← Term.elabTermEnsuringType nt q(WithTop ℕ∞)
436+ let e ← ensureIsFunction <| ← Term.elabTerm f none
434437 let (srcI, tgtI) ← findModels e none
435438 mkAppM ``ContMDiff #[srcI, tgtI, ne, e]
436439
437440/-- `mfderiv[u] f x` elaborates to `mfderivWithin I J f u x`,
438441trying to determine `I` and `J` from the local context. -/
439442scoped elab :max "mfderiv[" s:term "]" ppSpace t:term:arg : term => do
440443 let es ← Term.elabTerm s none
441- let e ← Term.elabTerm t none
444+ let e ← ensureIsFunction <| ← Term.elabTerm t none
442445 let (srcI, tgtI) ← findModels e es
443446 mkAppM ``mfderivWithin #[srcI, tgtI, e, es]
444447
445448/-- `mfderiv% f x` elaborates to `mfderiv I J f x`,
446449trying to determine `I` and `J` from the local context. -/
447450scoped elab :max "mfderiv%" ppSpace t:term:arg : term => do
448- let e ← Term.elabTerm t none
451+ let e ← ensureIsFunction <| ← Term.elabTerm t none
449452 let (srcI, tgtI) ← findModels e none
450453 mkAppM ``mfderiv #[srcI, tgtI, e]
451454
0 commit comments