Skip to content

Commit 1d8f1f1

Browse files
committed
better
1 parent 9e66b28 commit 1d8f1f1

2 files changed

Lines changed: 16 additions & 64 deletions

File tree

Mathlib/Geometry/Manifold/Notation.lean

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,13 @@ where
312312
let iTerm : Term ← ``(𝓘($eT, $eT))
313313
Term.elabTerm iTerm none
314314

315+
/-- Ensures that `e` is a function. Attempts to coerce `e` to a function if necessary. -/
316+
def ensureIsFunction (e : Expr) : MetaM Expr := do
317+
let ty ← whnf <|← instantiateMVars <|← inferType e
318+
if ty.isForall then return e else (← coerceToFunction? e).getDM <|
319+
throwError "Expected{indentD e}\nof type{indentD ty}\nto be a function, or to be coercible to \
320+
a function"
321+
315322
/-- If the type of `e` is a non-dependent function between spaces `src` and `tgt`, try to find a
316323
model with corners on both `src` and `tgt`. If successful, return both models.
317324
@@ -337,43 +344,7 @@ def findModels (e : Expr) (es : Option Expr) : TermElabM (Expr × Expr) := do
337344
the set {es} : {estype}"
338345
let tgtI ← findModel tgt (src, srcI)
339346
return (srcI, tgtI)
340-
| _ =>
341-
match_expr etype with
342-
| OpenPartialHomeomorph src tgt _ _ =>
343-
trace[Elab.DiffGeo.MDiff] m!"found a partial homeomorphism from {src} to {tgt}"
344-
if tgt.hasLooseBVars then
345-
-- TODO: try `T%` here, and if it works, add an interactive suggestion to use it
346-
throwError "Term {e} is a dependent function, of type {etype}\nHint: you can use the `T%` \
347-
elaborator to convert a dependent function to a non-dependent one"
348-
let srcI ← findModel src
349-
if let some es := es then
350-
let estype ← inferType es
351-
/- Note: we use `isDefEq` here since persistent metavariable assignments in `src` and
352-
`estype` are acceptable.
353-
TODO: consider attempting to coerce `es` to a `Set`. -/
354-
if !(← isDefEq estype <|← mkAppM ``Set #[src]) then
355-
throwError "The domain {src} of {e} is not definitionally equal to the carrier type of \
356-
the set {es} : {estype}"
357-
let tgtI ← findModel tgt (src, srcI)
358-
return (srcI, tgtI)
359-
| PartialEquiv src tgt =>
360-
trace[Elab.DiffGeo.MDiff] m!"found a partial equivalence from {src} to {tgt}"
361-
if tgt.hasLooseBVars then
362-
-- TODO: try `T%` here, and if it works, add an interactive suggestion to use it
363-
throwError "Term {e} is a dependent function, of type {etype}\nHint: you can use the `T%` \
364-
elaborator to convert a dependent function to a non-dependent one"
365-
let srcI ← findModel src
366-
if let some es := es then
367-
let estype ← inferType es
368-
/- Note: we use `isDefEq` here since persistent metavariable assignments in `src` and
369-
`estype` are acceptable.
370-
TODO: consider attempting to coerce `es` to a `Set`. -/
371-
if !(← isDefEq estype <|← mkAppM ``Set #[src]) then
372-
throwError "The domain {src} of {e} is not definitionally equal to the carrier type of \
373-
the set {es} : {estype}"
374-
let tgtI ← findModel tgt (src, srcI)
375-
return (srcI, tgtI)
376-
| _ => throwError "Expected{indentD e}\nof type{indentD etype}\nto be a function"
347+
| _ => throwError "Expected{indentD e}\nof type{indentD etype}\nto be a function"
377348

378349
end Elab
379350

@@ -384,7 +355,7 @@ trying to determine `I` and `J` from the local context.
384355
The argument `x` can be omitted. -/
385356
scoped elab:max "MDiffAt[" s:term "]" ppSpace f:term:arg : term => do
386357
let es ← Term.elabTerm s none
387-
let ef ← Term.elabTerm f none
358+
let ef ← ensureIsFunction <|← Term.elabTerm f none
388359
let (srcI, tgtI) ← findModels ef es
389360
mkAppM ``MDifferentiableWithinAt #[srcI, tgtI, ef, es]
390361

MathlibTest/DifferentialGeometry/Notation.lean

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -120,40 +120,21 @@ variable {f : M → M'} {s : Set M} {m : M}
120120
#guard_msgs in
121121
#check MDiff[s] f
122122

123-
-- A partial homeomorphism or partial equivalence.
124-
variable {φ : OpenPartialHomeomorph M E} {ψ : PartialEquiv M E}
125-
126-
#check MDifferentiableWithinAt I 𝓘(𝕜, E) ψ
127-
#check MDifferentiableWithinAt I 𝓘(𝕜, E) ψ s
123+
/-! A partial homeomorphism or partial equivalence. More generally, this works for any type
124+
with a coercion to (possibly dependent) functions. -/
125+
section coercion
128126

127+
variable {φ : OpenPartialHomeomorph M E} {ψ : PartialEquiv M E}
129128

130-
/--
131-
error: Application type mismatch: The argument
132-
φ
133-
has type
134-
OpenPartialHomeomorph M E
135-
but is expected to have type
136-
?M → ?M'
137-
in the application
138-
MDifferentiableWithinAt I 𝓘(𝕜, E) φ
139-
-/
129+
/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑φ) s : M → Prop -/
140130
#guard_msgs in
141131
#check MDiffAt[s] φ
142132

143-
/--
144-
error: Application type mismatch: The argument
145-
ψ
146-
has type
147-
PartialEquiv M E
148-
but is expected to have type
149-
?M → ?M'
150-
in the application
151-
MDifferentiableWithinAt I 𝓘(𝕜, E) ψ
152-
-/
133+
/-- info: MDifferentiableWithinAt I 𝓘(𝕜, E) (↑ψ) s : M → Prop -/
153134
#guard_msgs in
154135
#check MDiffAt[s] ψ
155136

156-
#exit
137+
end coercion
157138

158139
-- Testing an error message.
159140
section

0 commit comments

Comments
 (0)