feat: extend valid set of valid auto bound names
@Kha The motivation was Andrew's example :) Users often use `u₁`, `u1`, `u₂`, ... to name universe variables.
This commit is contained in:
parent
498dae8fab
commit
bbcd2247f2
5 changed files with 47 additions and 23 deletions
|
|
@ -21,8 +21,11 @@ def isLetterLike (c : Char) : Bool :=
|
|||
(0x2100 ≤ c.val && c.val ≤ 0x214f) || -- Letter like block
|
||||
(0x1d49c ≤ c.val && c.val ≤ 0x1d59f) -- Latin letters, Script, Double-struck, Fractur
|
||||
|
||||
def isNumericSubscript (c : Char) : Bool :=
|
||||
0x2080 ≤ c.val && c.val ≤ 0x2089
|
||||
|
||||
def isSubScriptAlnum (c : Char) : Bool :=
|
||||
(0x2080 ≤ c.val && c.val ≤ 0x2089) || -- numeric subscripts
|
||||
isNumericSubscript c ||
|
||||
(0x2090 ≤ c.val && c.val ≤ 0x209c) ||
|
||||
(0x1d62 ≤ c.val && c.val ≤ 0x1d6a)
|
||||
|
||||
|
|
|
|||
35
src/Lean/Elab/AutoBound.lean
Normal file
35
src/Lean/Elab/AutoBound.lean
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/-
|
||||
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
import Lean.Data.Options
|
||||
|
||||
/- Basic support for auto bound implicit local names -/
|
||||
|
||||
namespace Lean.Elab
|
||||
|
||||
builtin_initialize
|
||||
registerOption `autoBoundImplicitLocal {
|
||||
defValue := true
|
||||
group := ""
|
||||
descr := "Unbound local variables in declaration headers become implicit arguments if they are a lower case or greek letter followed by numeric digits. For example, `def f (x : Vector α n) : Vector α n :=` automatically introduces the implicit variables {α n}"
|
||||
}
|
||||
|
||||
def getAutoBoundImplicitLocalOption (opts : Options) : Bool :=
|
||||
opts.get `autoBoundImplicitLocal true
|
||||
|
||||
private def allNumeral (s : Substring) : Bool :=
|
||||
s.all fun c => c.isDigit || isNumericSubscript c
|
||||
|
||||
def isValidAutoBoundImplicitName (n : Name) : Bool :=
|
||||
match n.eraseMacroScopes with
|
||||
| Name.str Name.anonymous s _ => s.length > 0 && (isGreek s[0] || s[0].isLower) && allNumeral (s.toSubstring.drop 1)
|
||||
| _ => false
|
||||
|
||||
def isValidAutoBoundLevelName (n : Name) : Bool :=
|
||||
match n.eraseMacroScopes with
|
||||
| Name.str Name.anonymous s _ => s.length > 0 && s[0].isLower && allNumeral (s.toSubstring.drop 1)
|
||||
| _ => false
|
||||
|
||||
end Lean.Elab
|
||||
|
|
@ -6,6 +6,7 @@ Authors: Leonardo de Moura
|
|||
import Lean.Meta.LevelDefEq
|
||||
import Lean.Elab.Exception
|
||||
import Lean.Elab.Log
|
||||
import Lean.Elab.AutoBound
|
||||
|
||||
namespace Lean.Elab.Level
|
||||
|
||||
|
|
@ -33,17 +34,11 @@ instance : MonadNameGenerator LevelElabM where
|
|||
|
||||
setNGen ngen := modify fun s => { s with ngen := ngen }
|
||||
|
||||
|
||||
def mkFreshLevelMVar : LevelElabM Level := do
|
||||
let mvarId ← mkFreshId
|
||||
modify fun s => { s with mctx := s.mctx.addLevelMVarDecl mvarId }
|
||||
return mkLevelMVar mvarId
|
||||
|
||||
private def isValidAutoBoundLevelName (n : Name) : Bool :=
|
||||
match n.eraseMacroScopes with
|
||||
| Name.str Name.anonymous s _ => s.length == 1 && s[0].isLower
|
||||
| _ => false
|
||||
|
||||
partial def elabLevel (stx : Syntax) : LevelElabM Level := withRef stx do
|
||||
let kind := stx.getKind
|
||||
if kind == `Lean.Parser.Level.paren then
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import Lean.Util.RecDepth
|
|||
import Lean.Elab.Log
|
||||
import Lean.Elab.Level
|
||||
import Lean.Elab.Attributes
|
||||
import Lean.Elab.AutoBound
|
||||
|
||||
namespace Lean.Elab.Term
|
||||
/-
|
||||
|
|
@ -297,16 +298,6 @@ def withLevelNames {α} (levelNames : List Name) (x : TermElabM α) : TermElabM
|
|||
def withoutErrToSorry {α} (x : TermElabM α) : TermElabM α :=
|
||||
withReader (fun ctx => { ctx with errToSorry := false }) x
|
||||
|
||||
builtin_initialize
|
||||
registerOption `autoBoundImplicitLocal {
|
||||
defValue := true
|
||||
group := ""
|
||||
descr := "Unbound local variables in declaration headers become implicit arguments if they are a lower case or greek letter. For example, `def f (x : Vector α n) : Vector α n :=` automatically introduces the implicit variables {α n}"
|
||||
}
|
||||
|
||||
private def getAutoBoundImplicitLocalOption (opts : Options) : Bool :=
|
||||
opts.get `autoBoundImplicitLocal true
|
||||
|
||||
/-- Execute `x` with `autoBoundImplicit = (options.get `autoBoundImplicitLocal) && flag` -/
|
||||
def withAutoBoundImplicitLocal {α} (x : TermElabM α) (flag := true) : TermElabM α := do
|
||||
let flag := getAutoBoundImplicitLocalOption (← getOptions) && flag
|
||||
|
|
@ -1217,11 +1208,6 @@ private def mkConsts (candidates : List (Name × List String)) (explicitLevels :
|
|||
let const ← mkConst constName explicitLevels
|
||||
pure $ (const, projs) :: result
|
||||
|
||||
def isValidAutoBoundImplicitName (n : Name) : Bool :=
|
||||
match n.eraseMacroScopes with
|
||||
| Name.str Name.anonymous s _ => s.length == 1 && (isGreek s[0] || s[0].isLower)
|
||||
| _ => false
|
||||
|
||||
def resolveName (n : Name) (preresolved : List (Name × List String)) (explicitLevels : List Level) : TermElabM (List (Expr × List String)) := do
|
||||
match (← resolveLocalName n) with
|
||||
| some (e, projs) =>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ def mkVec : Vec α 0 := ⟨ #[], rfl ⟩
|
|||
def Vec.map (xs : Vec α n) (f : α → β) : Vec β n :=
|
||||
⟨ xs.val.map f, sorry ⟩
|
||||
|
||||
/- unbound implicit locals must be greek or lower case letters -/
|
||||
/- unbound implicit locals must be greek or lower case letters followed by numerical digits -/
|
||||
def Vec.map2 (xs : Vec α size /- error: unknown identifier size -/) (f : α → β) : Vec β n :=
|
||||
⟨ xs.val.map f, sorry ⟩
|
||||
|
||||
|
|
@ -65,3 +65,8 @@ def findSomeRev? (as : Array α) (f : α → Option β) : Option β :=
|
|||
Id.run <| findSomeRevM? as f
|
||||
|
||||
end Ex1
|
||||
|
||||
def apply {α : Type u₁} {β : α → Type u₂} (f : (a : α) → β a) (a : α) : β a :=
|
||||
f a
|
||||
|
||||
def pair (a : α₁) := (a, a)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue