feat: split Lean.Kernel.Environment from Lean.Environment (#5145)
This PR splits the environment used by the kernel from that used by the elaborator, providing the foundation for tracking of asynchronously elaborated declarations, which will exist as a concept only in the latter. Minor changes: * kernel diagnostics are moved from an environment extension to a direct environment as they are the only extension used directly by the kernel * `initQuot` is moved from an environment header field to a direct environment as it is the only header field used by the kernel; this also makes the remaining header immutable after import
This commit is contained in:
parent
5e63dd292f
commit
3770808b58
87 changed files with 792 additions and 609 deletions
|
|
@ -699,12 +699,12 @@ else()
|
|||
endif()
|
||||
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||
add_custom_target(lake_lib ALL
|
||||
add_custom_target(lake_lib
|
||||
WORKING_DIRECTORY ${LEAN_SOURCE_DIR}
|
||||
DEPENDS leanshared
|
||||
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make Lake
|
||||
VERBATIM)
|
||||
add_custom_target(lake_shared ALL
|
||||
add_custom_target(lake_shared
|
||||
WORKING_DIRECTORY ${LEAN_SOURCE_DIR}
|
||||
DEPENDS lake_lib
|
||||
COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make libLake_shared
|
||||
|
|
|
|||
|
|
@ -14,8 +14,16 @@ register_builtin_option debug.skipKernelTC : Bool := {
|
|||
descr := "skip kernel type checker. WARNING: setting this option to true may compromise soundness because your proofs will not be checked by the Lean kernel"
|
||||
}
|
||||
|
||||
/-- Adds given declaration to the environment, respecting `debug.skipKernelTC`. -/
|
||||
def Kernel.Environment.addDecl (env : Environment) (opts : Options) (decl : Declaration)
|
||||
(cancelTk? : Option IO.CancelToken := none) : Except Exception Environment :=
|
||||
if debug.skipKernelTC.get opts then
|
||||
addDeclWithoutChecking env decl
|
||||
else
|
||||
addDeclCore env (Core.getMaxHeartbeats opts).toUSize decl cancelTk?
|
||||
|
||||
def Environment.addDecl (env : Environment) (opts : Options) (decl : Declaration)
|
||||
(cancelTk? : Option IO.CancelToken := none) : Except KernelException Environment :=
|
||||
(cancelTk? : Option IO.CancelToken := none) : Except Kernel.Exception Environment :=
|
||||
if debug.skipKernelTC.get opts then
|
||||
addDeclWithoutChecking env decl
|
||||
else
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ register_builtin_option compiler.enableNew : Bool := {
|
|||
opaque compileDeclsNew (declNames : List Name) : CoreM Unit
|
||||
|
||||
@[extern "lean_compile_decls"]
|
||||
opaque compileDeclsOld (env : Environment) (opt : @& Options) (decls : @& List Name) : Except KernelException Environment
|
||||
opaque compileDeclsOld (env : Environment) (opt : @& Options) (decls : @& List Name) : Except Kernel.Exception Environment
|
||||
|
||||
def compileDecl (decl : Declaration) : CoreM Unit := do
|
||||
let opts ← getOptions
|
||||
|
|
@ -526,7 +526,7 @@ def compileDecl (decl : Declaration) : CoreM Unit := do
|
|||
return compileDeclsOld (← getEnv) opts decls
|
||||
match res with
|
||||
| Except.ok env => setEnv env
|
||||
| Except.error (KernelException.other msg) =>
|
||||
| Except.error (.other msg) =>
|
||||
checkUnsupported decl -- Generate nicer error message for unsupported recursors and axioms
|
||||
throwError msg
|
||||
| Except.error ex =>
|
||||
|
|
@ -538,7 +538,7 @@ def compileDecls (decls : List Name) : CoreM Unit := do
|
|||
compileDeclsNew decls
|
||||
match compileDeclsOld (← getEnv) opts decls with
|
||||
| Except.ok env => setEnv env
|
||||
| Except.error (KernelException.other msg) =>
|
||||
| Except.error (.other msg) =>
|
||||
throwError msg
|
||||
| Except.error ex =>
|
||||
throwKernelException ex
|
||||
|
|
|
|||
|
|
@ -193,6 +193,19 @@ def Declaration.definitionVal! : Declaration → DefinitionVal
|
|||
| .defnDecl val => val
|
||||
| _ => panic! "Expected a `Declaration.defnDecl`."
|
||||
|
||||
/--
|
||||
Returns all top-level names to be defined by adding this declaration to the environment. This does
|
||||
not include auxiliary definitions such as projections.
|
||||
-/
|
||||
def Declaration.getNames : Declaration → List Name
|
||||
| .axiomDecl val => [val.name]
|
||||
| .defnDecl val => [val.name]
|
||||
| .thmDecl val => [val.name]
|
||||
| .opaqueDecl val => [val.name]
|
||||
| .quotDecl => [``Quot, ``Quot.mk, ``Quot.lift, ``Quot.ind]
|
||||
| .mutualDefnDecl defns => defns.map (·.name)
|
||||
| .inductDecl _ _ types _ => types.map (·.name)
|
||||
|
||||
@[specialize] def Declaration.foldExprM {α} {m : Type → Type} [Monad m] (d : Declaration) (f : α → Expr → m α) (a : α) : m α :=
|
||||
match d with
|
||||
| .quotDecl => pure a
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ private partial def checkResultingUniversesForFields (fieldInfos : Array StructF
|
|||
throwErrorAt info.ref msg
|
||||
|
||||
@[extern "lean_mk_projections"]
|
||||
private opaque mkProjections (env : Environment) (structName : Name) (projs : List Name) (isClass : Bool) : Except KernelException Environment
|
||||
private opaque mkProjections (env : Environment) (structName : Name) (projs : List Name) (isClass : Bool) : Except Kernel.Exception Environment
|
||||
|
||||
private def addProjections (r : ElabHeaderResult) (fieldInfos : Array StructFieldInfo) : TermElabM Unit := do
|
||||
if r.type.isProp then
|
||||
|
|
|
|||
|
|
@ -88,11 +88,6 @@ structure EnvironmentHeader where
|
|||
-/
|
||||
trustLevel : UInt32 := 0
|
||||
/--
|
||||
`quotInit = true` if the command `init_quot` has already been executed for the environment, and
|
||||
`Quot` declarations have been added to the environment.
|
||||
-/
|
||||
quotInit : Bool := false
|
||||
/--
|
||||
Name of the module being compiled.
|
||||
-/
|
||||
mainModule : Name := default
|
||||
|
|
@ -106,6 +101,15 @@ structure EnvironmentHeader where
|
|||
moduleData : Array ModuleData := #[]
|
||||
deriving Nonempty
|
||||
|
||||
namespace Kernel
|
||||
|
||||
structure Diagnostics where
|
||||
/-- Number of times each declaration has been unfolded by the kernel. -/
|
||||
unfoldCounter : PHashMap Name Nat := {}
|
||||
/-- If `enabled = true`, kernel records declarations that have been unfolded. -/
|
||||
enabled : Bool := false
|
||||
deriving Inhabited
|
||||
|
||||
/--
|
||||
An environment stores declarations provided by the user. The kernel
|
||||
currently supports different kinds of declarations such as definitions, theorems,
|
||||
|
|
@ -121,10 +125,33 @@ declared by users are stored in an environment extension. Users can declare new
|
|||
using meta-programming.
|
||||
-/
|
||||
structure Environment where
|
||||
/-- The constructor of `Environment` is private to protect against modification
|
||||
that bypasses the kernel. -/
|
||||
/--
|
||||
The constructor of `Environment` is private to protect against modification that bypasses the
|
||||
kernel.
|
||||
-/
|
||||
private mk ::
|
||||
/--
|
||||
Mapping from constant name to `ConstantInfo`. It contains all constants (definitions, theorems,
|
||||
axioms, etc) that have been already type checked by the kernel.
|
||||
-/
|
||||
constants : ConstMap
|
||||
/--
|
||||
`quotInit = true` if the command `init_quot` has already been executed for the environment, and
|
||||
`Quot` declarations have been added to the environment. When the flag is set, the type checker can
|
||||
assume that the `Quot` declarations in the environment have indeed been added by the kernel and
|
||||
not by the user.
|
||||
-/
|
||||
quotInit : Bool := false
|
||||
/--
|
||||
Diagnostic information collected during kernel execution.
|
||||
|
||||
Remark: We store kernel diagnostic information in an environment field to simplify the interface
|
||||
with the kernel implemented in C/C++. Thus, we can only track declarations in methods, such as
|
||||
`addDecl`, which return a new environment. `Kernel.isDefEq` and `Kernel.whnf` do not update the
|
||||
statistics. We claim this is ok since these methods are mainly used for debugging.
|
||||
-/
|
||||
diagnostics : Diagnostics := {}
|
||||
/--
|
||||
Mapping from constant name to module (index) where constant has been declared.
|
||||
Recall that a Lean file has a header where previously compiled modules can be imported.
|
||||
Each imported module has a unique `ModuleIdx`.
|
||||
|
|
@ -134,96 +161,23 @@ structure Environment where
|
|||
the field `constants`. These auxiliary constants are invisible to the Lean kernel and elaborator.
|
||||
Only the code generator uses them.
|
||||
-/
|
||||
const2ModIdx : Std.HashMap Name ModuleIdx
|
||||
/--
|
||||
Mapping from constant name to `ConstantInfo`. It contains all constants (definitions, theorems, axioms, etc)
|
||||
that have been already type checked by the kernel.
|
||||
-/
|
||||
constants : ConstMap
|
||||
const2ModIdx : Std.HashMap Name ModuleIdx
|
||||
/--
|
||||
Environment extensions. It also includes user-defined extensions.
|
||||
-/
|
||||
extensions : Array EnvExtensionState
|
||||
private extensions : Array EnvExtensionState
|
||||
/--
|
||||
Constant names to be saved in the field `extraConstNames` at `ModuleData`.
|
||||
It contains auxiliary declaration names created by the code generator which are not in `constants`.
|
||||
When importing modules, we want to insert them at `const2ModIdx`.
|
||||
-/
|
||||
extraConstNames : NameSet
|
||||
/-- The header contains additional information that is not updated often. -/
|
||||
header : EnvironmentHeader := {}
|
||||
deriving Nonempty
|
||||
private extraConstNames : NameSet
|
||||
/-- The header contains additional information that is set at import time. -/
|
||||
header : EnvironmentHeader := {}
|
||||
deriving Nonempty
|
||||
|
||||
namespace Environment
|
||||
|
||||
private def addAux (env : Environment) (cinfo : ConstantInfo) : Environment :=
|
||||
{ env with constants := env.constants.insert cinfo.name cinfo }
|
||||
|
||||
/--
|
||||
Save an extra constant name that is used to populate `const2ModIdx` when we import
|
||||
.olean files. We use this feature to save in which module an auxiliary declaration
|
||||
created by the code generator has been created.
|
||||
-/
|
||||
def addExtraName (env : Environment) (name : Name) : Environment :=
|
||||
if env.constants.contains name then
|
||||
env
|
||||
else
|
||||
{ env with extraConstNames := env.extraConstNames.insert name }
|
||||
|
||||
@[export lean_environment_find]
|
||||
def find? (env : Environment) (n : Name) : Option ConstantInfo :=
|
||||
/- It is safe to use `find'` because we never overwrite imported declarations. -/
|
||||
env.constants.find?' n
|
||||
|
||||
def contains (env : Environment) (n : Name) : Bool :=
|
||||
env.constants.contains n
|
||||
|
||||
def imports (env : Environment) : Array Import :=
|
||||
env.header.imports
|
||||
|
||||
def allImportedModuleNames (env : Environment) : Array Name :=
|
||||
env.header.moduleNames
|
||||
|
||||
@[export lean_environment_set_main_module]
|
||||
def setMainModule (env : Environment) (m : Name) : Environment :=
|
||||
{ env with header := { env.header with mainModule := m } }
|
||||
|
||||
@[export lean_environment_main_module]
|
||||
def mainModule (env : Environment) : Name :=
|
||||
env.header.mainModule
|
||||
|
||||
@[export lean_environment_mark_quot_init]
|
||||
private def markQuotInit (env : Environment) : Environment :=
|
||||
{ env with header := { env.header with quotInit := true } }
|
||||
|
||||
@[export lean_environment_quot_init]
|
||||
private def isQuotInit (env : Environment) : Bool :=
|
||||
env.header.quotInit
|
||||
|
||||
@[export lean_environment_trust_level]
|
||||
private def getTrustLevel (env : Environment) : UInt32 :=
|
||||
env.header.trustLevel
|
||||
|
||||
def getModuleIdxFor? (env : Environment) (declName : Name) : Option ModuleIdx :=
|
||||
env.const2ModIdx[declName]?
|
||||
|
||||
def isConstructor (env : Environment) (declName : Name) : Bool :=
|
||||
match env.find? declName with
|
||||
| some (.ctorInfo _) => true
|
||||
| _ => false
|
||||
|
||||
def isSafeDefinition (env : Environment) (declName : Name) : Bool :=
|
||||
match env.find? declName with
|
||||
| some (.defnInfo { safety := .safe, .. }) => true
|
||||
| _ => false
|
||||
|
||||
def getModuleIdx? (env : Environment) (moduleName : Name) : Option ModuleIdx :=
|
||||
env.header.moduleNames.findIdx? (· == moduleName)
|
||||
|
||||
end Environment
|
||||
|
||||
/-- Exceptions that can be raised by the Kernel when type checking new declarations. -/
|
||||
inductive KernelException where
|
||||
/-- Exceptions that can be raised by the kernel when type checking new declarations. -/
|
||||
inductive Exception where
|
||||
| unknownConstant (env : Environment) (name : Name)
|
||||
| alreadyDeclared (env : Environment) (name : Name)
|
||||
| declTypeMismatch (env : Environment) (decl : Declaration) (givenType : Expr)
|
||||
|
|
@ -244,21 +198,166 @@ inductive KernelException where
|
|||
|
||||
namespace Environment
|
||||
|
||||
/--
|
||||
Type check given declaration and add it to the environment
|
||||
-/
|
||||
@[export lean_environment_find]
|
||||
def find? (env : Environment) (n : Name) : Option ConstantInfo :=
|
||||
/- It is safe to use `find'` because we never overwrite imported declarations. -/
|
||||
env.constants.find?' n
|
||||
|
||||
@[export lean_environment_mark_quot_init]
|
||||
private def markQuotInit (env : Environment) : Environment :=
|
||||
{ env with quotInit := true }
|
||||
|
||||
@[export lean_environment_quot_init]
|
||||
private def isQuotInit (env : Environment) : Bool :=
|
||||
env.quotInit
|
||||
|
||||
/-- Type check given declaration and add it to the environment -/
|
||||
@[extern "lean_add_decl"]
|
||||
opaque addDeclCore (env : Environment) (maxHeartbeats : USize) (decl : @& Declaration)
|
||||
(cancelTk? : @& Option IO.CancelToken) : Except KernelException Environment
|
||||
(cancelTk? : @& Option IO.CancelToken) : Except Exception Environment
|
||||
|
||||
/--
|
||||
Add declaration to kernel without type checking it.
|
||||
|
||||
**WARNING** This function is meant for temporarily working around kernel performance issues.
|
||||
It compromises soundness because, for example, a buggy tactic may produce an invalid proof,
|
||||
and the kernel will not catch it if the new option is set to true.
|
||||
-/
|
||||
@[extern "lean_add_decl_without_checking"]
|
||||
opaque addDeclWithoutChecking (env : Environment) (decl : @& Declaration) : Except KernelException Environment
|
||||
opaque addDeclWithoutChecking (env : Environment) (decl : @& Declaration) : Except Exception Environment
|
||||
|
||||
@[export lean_environment_add]
|
||||
private def add (env : Environment) (cinfo : ConstantInfo) : Environment :=
|
||||
{ env with constants := env.constants.insert cinfo.name cinfo }
|
||||
|
||||
@[export lean_kernel_diag_is_enabled]
|
||||
def Diagnostics.isEnabled (d : Diagnostics) : Bool :=
|
||||
d.enabled
|
||||
|
||||
/-- Enables/disables kernel diagnostics. -/
|
||||
def enableDiag (env : Environment) (flag : Bool) : Environment :=
|
||||
{ env with diagnostics.enabled := flag }
|
||||
|
||||
def isDiagnosticsEnabled (env : Environment) : Bool :=
|
||||
env.diagnostics.enabled
|
||||
|
||||
def resetDiag (env : Environment) : Environment :=
|
||||
{ env with diagnostics.unfoldCounter := {} }
|
||||
|
||||
@[export lean_kernel_record_unfold]
|
||||
def Diagnostics.recordUnfold (d : Diagnostics) (declName : Name) : Diagnostics :=
|
||||
if d.enabled then
|
||||
let cNew := if let some c := d.unfoldCounter.find? declName then c + 1 else 1
|
||||
{ d with unfoldCounter := d.unfoldCounter.insert declName cNew }
|
||||
else
|
||||
d
|
||||
|
||||
@[export lean_kernel_get_diag]
|
||||
def getDiagnostics (env : Environment) : Diagnostics :=
|
||||
env.diagnostics
|
||||
|
||||
@[export lean_kernel_set_diag]
|
||||
def setDiagnostics (env : Environment) (diag : Diagnostics) : Environment :=
|
||||
{ env with diagnostics := diag}
|
||||
|
||||
end Kernel.Environment
|
||||
|
||||
@[deprecated Kernel.Exception (since := "2024-12-12")]
|
||||
abbrev KernelException := Kernel.Exception
|
||||
|
||||
/--
|
||||
Elaboration-specific extension of `Kernel.Environment` that adds tracking of asynchronously
|
||||
elaborated declarations.
|
||||
-/
|
||||
structure Environment where
|
||||
/-
|
||||
Like with `Kernel.Environment`, this constructor is private to protect consistency of the
|
||||
environment, though there are no soundness concerns in this case given that it is used purely for
|
||||
elaboration.
|
||||
-/
|
||||
private mk ::
|
||||
private base : Kernel.Environment
|
||||
-- TODO: async data
|
||||
deriving Nonempty
|
||||
|
||||
namespace Environment
|
||||
|
||||
@[export lean_elab_environment_of_kernel_env]
|
||||
def ofKernelEnv (env : Kernel.Environment) : Environment :=
|
||||
{ base := env }
|
||||
|
||||
@[export lean_elab_environment_to_kernel_env]
|
||||
def toKernelEnv (env : Environment) : Kernel.Environment :=
|
||||
env.base
|
||||
|
||||
/-- Type check given declaration and add it to the environment. -/
|
||||
@[extern "lean_elab_add_decl"]
|
||||
opaque addDeclCore (env : Environment) (maxHeartbeats : USize) (decl : @& Declaration)
|
||||
(cancelTk? : @& Option IO.CancelToken) : Except Kernel.Exception Environment
|
||||
|
||||
@[inherit_doc Kernel.Environment.addDeclWithoutChecking, extern "lean_elab_add_decl_without_checking"]
|
||||
opaque addDeclWithoutChecking (env : Environment) (decl : @& Declaration) : Except Kernel.Exception Environment
|
||||
|
||||
@[inherit_doc Kernel.Environment.constants]
|
||||
def constants (env : Environment) : ConstMap :=
|
||||
env.toKernelEnv.constants
|
||||
|
||||
@[inherit_doc Kernel.Environment.const2ModIdx]
|
||||
def const2ModIdx (env : Environment) : Std.HashMap Name ModuleIdx :=
|
||||
env.toKernelEnv.const2ModIdx
|
||||
|
||||
@[export lean_elab_environment_add]
|
||||
private def add (env : Environment) (cinfo : ConstantInfo) : Environment :=
|
||||
{ env with base := env.base.add cinfo }
|
||||
|
||||
/--
|
||||
Save an extra constant name that is used to populate `const2ModIdx` when we import
|
||||
.olean files. We use this feature to save in which module an auxiliary declaration
|
||||
created by the code generator has been created.
|
||||
-/
|
||||
def addExtraName (env : Environment) (name : Name) : Environment :=
|
||||
if env.constants.contains name then
|
||||
env
|
||||
else
|
||||
{ env with base.extraConstNames := env.base.extraConstNames.insert name }
|
||||
|
||||
def find? (env : Environment) (n : Name) : Option ConstantInfo :=
|
||||
/- It is safe to use `find'` because we never overwrite imported declarations. -/
|
||||
env.constants.find?' n
|
||||
|
||||
def contains (env : Environment) (n : Name) : Bool :=
|
||||
env.constants.contains n
|
||||
|
||||
def header (env : Environment) : EnvironmentHeader :=
|
||||
env.base.header
|
||||
|
||||
def imports (env : Environment) : Array Import :=
|
||||
env.header.imports
|
||||
|
||||
def allImportedModuleNames (env : Environment) : Array Name :=
|
||||
env.header.moduleNames
|
||||
|
||||
def setMainModule (env : Environment) (m : Name) : Environment :=
|
||||
{ env with base.header.mainModule := m }
|
||||
|
||||
def mainModule (env : Environment) : Name :=
|
||||
env.header.mainModule
|
||||
|
||||
def getModuleIdxFor? (env : Environment) (declName : Name) : Option ModuleIdx :=
|
||||
env.base.const2ModIdx[declName]?
|
||||
|
||||
def isConstructor (env : Environment) (declName : Name) : Bool :=
|
||||
match env.find? declName with
|
||||
| some (.ctorInfo _) => true
|
||||
| _ => false
|
||||
|
||||
def isSafeDefinition (env : Environment) (declName : Name) : Bool :=
|
||||
match env.find? declName with
|
||||
| some (.defnInfo { safety := .safe, .. }) => true
|
||||
| _ => false
|
||||
|
||||
def getModuleIdx? (env : Environment) (moduleName : Name) : Option ModuleIdx :=
|
||||
env.header.moduleNames.findIdx? (· == moduleName)
|
||||
|
||||
end Environment
|
||||
|
||||
|
|
@ -385,20 +484,20 @@ opaque EnvExtensionInterfaceImp : EnvExtensionInterface
|
|||
def EnvExtension (σ : Type) : Type := EnvExtensionInterfaceImp.ext σ
|
||||
|
||||
private def ensureExtensionsArraySize (env : Environment) : IO Environment := do
|
||||
let exts ← EnvExtensionInterfaceImp.ensureExtensionsSize env.extensions
|
||||
return { env with extensions := exts }
|
||||
let exts ← EnvExtensionInterfaceImp.ensureExtensionsSize env.base.extensions
|
||||
return { env with base.extensions := exts }
|
||||
|
||||
namespace EnvExtension
|
||||
instance {σ} [s : Inhabited σ] : Inhabited (EnvExtension σ) := EnvExtensionInterfaceImp.inhabitedExt s
|
||||
|
||||
def setState {σ : Type} (ext : EnvExtension σ) (env : Environment) (s : σ) : Environment :=
|
||||
{ env with extensions := EnvExtensionInterfaceImp.setState ext env.extensions s }
|
||||
{ env with base.extensions := EnvExtensionInterfaceImp.setState ext env.base.extensions s }
|
||||
|
||||
def modifyState {σ : Type} (ext : EnvExtension σ) (env : Environment) (f : σ → σ) : Environment :=
|
||||
{ env with extensions := EnvExtensionInterfaceImp.modifyState ext env.extensions f }
|
||||
{ env with base.extensions := EnvExtensionInterfaceImp.modifyState ext env.base.extensions f }
|
||||
|
||||
def getState {σ : Type} [Inhabited σ] (ext : EnvExtension σ) (env : Environment) : σ :=
|
||||
EnvExtensionInterfaceImp.getState ext env.extensions
|
||||
EnvExtensionInterfaceImp.getState ext env.base.extensions
|
||||
|
||||
end EnvExtension
|
||||
|
||||
|
|
@ -418,11 +517,13 @@ def mkEmptyEnvironment (trustLevel : UInt32 := 0) : IO Environment := do
|
|||
if initializing then throw (IO.userError "environment objects cannot be created during initialization")
|
||||
let exts ← mkInitialExtensionStates
|
||||
pure {
|
||||
const2ModIdx := {}
|
||||
constants := {}
|
||||
header := { trustLevel := trustLevel }
|
||||
extraConstNames := {}
|
||||
extensions := exts
|
||||
base := {
|
||||
const2ModIdx := {}
|
||||
constants := {}
|
||||
header := { trustLevel }
|
||||
extraConstNames := {}
|
||||
extensions := exts
|
||||
}
|
||||
}
|
||||
|
||||
structure PersistentEnvExtensionState (α : Type) (σ : Type) where
|
||||
|
|
@ -710,7 +811,7 @@ def mkModuleData (env : Environment) : IO ModuleData := do
|
|||
let constants := env.constants.foldStage2 (fun cs _ c => cs.push c) #[]
|
||||
return {
|
||||
imports := env.header.imports
|
||||
extraConstNames := env.extraConstNames.toArray
|
||||
extraConstNames := env.base.extraConstNames.toArray
|
||||
constNames, constants, entries
|
||||
}
|
||||
|
||||
|
|
@ -873,17 +974,17 @@ def finalizeImport (s : ImportState) (imports : Array Import) (opts : Options) (
|
|||
let constants : ConstMap := SMap.fromHashMap constantMap false
|
||||
let exts ← mkInitialExtensionStates
|
||||
let mut env : Environment := {
|
||||
const2ModIdx := const2ModIdx
|
||||
constants := constants
|
||||
extraConstNames := {}
|
||||
extensions := exts
|
||||
header := {
|
||||
quotInit := !imports.isEmpty -- We assume `core.lean` initializes quotient module
|
||||
trustLevel := trustLevel
|
||||
imports := imports
|
||||
regions := s.regions
|
||||
moduleNames := s.moduleNames
|
||||
moduleData := s.moduleData
|
||||
base := {
|
||||
const2ModIdx, constants
|
||||
quotInit := !imports.isEmpty -- We assume `core.lean` initializes quotient module
|
||||
extraConstNames := {}
|
||||
extensions := exts
|
||||
header := {
|
||||
trustLevel, imports
|
||||
regions := s.regions
|
||||
moduleNames := s.moduleNames
|
||||
moduleData := s.moduleData
|
||||
}
|
||||
}
|
||||
}
|
||||
env ← setImportedEntries env s.moduleData
|
||||
|
|
@ -946,54 +1047,21 @@ builtin_initialize namespacesExt : SimplePersistentEnvExtension Name NameSSet
|
|||
addEntryFn := fun s n => s.insert n
|
||||
}
|
||||
|
||||
structure Kernel.Diagnostics where
|
||||
/-- Number of times each declaration has been unfolded by the kernel. -/
|
||||
unfoldCounter : PHashMap Name Nat := {}
|
||||
/-- If `enabled = true`, kernel records declarations that have been unfolded. -/
|
||||
enabled : Bool := false
|
||||
deriving Inhabited
|
||||
@[inherit_doc Kernel.Environment.enableDiag]
|
||||
def Kernel.enableDiag (env : Lean.Environment) (flag : Bool) : Lean.Environment :=
|
||||
{ env with base := env.base.enableDiag flag }
|
||||
|
||||
/--
|
||||
Extension for storting diagnostic information.
|
||||
def Kernel.isDiagnosticsEnabled (env : Lean.Environment) : Bool :=
|
||||
env.base.isDiagnosticsEnabled
|
||||
|
||||
Remark: We store kernel diagnostic information in an environment extension to simplify
|
||||
the interface with the kernel implemented in C/C++. Thus, we can only track
|
||||
declarations in methods, such as `addDecl`, which return a new environment.
|
||||
`Kernel.isDefEq` and `Kernel.whnf` do not update the statistics. We claim
|
||||
this is ok since these methods are mainly used for debugging.
|
||||
-/
|
||||
builtin_initialize diagExt : EnvExtension Kernel.Diagnostics ←
|
||||
registerEnvExtension (pure {})
|
||||
def Kernel.resetDiag (env : Lean.Environment) : Lean.Environment :=
|
||||
{ env with base := env.base.resetDiag }
|
||||
|
||||
@[export lean_kernel_diag_is_enabled]
|
||||
def Kernel.Diagnostics.isEnabled (d : Diagnostics) : Bool :=
|
||||
d.enabled
|
||||
def Kernel.getDiagnostics (env : Lean.Environment) : Diagnostics :=
|
||||
env.base.diagnostics
|
||||
|
||||
/-- Enables/disables kernel diagnostics. -/
|
||||
def Kernel.enableDiag (env : Environment) (flag : Bool) : Environment :=
|
||||
diagExt.modifyState env fun s => { s with enabled := flag }
|
||||
|
||||
def Kernel.isDiagnosticsEnabled (env : Environment) : Bool :=
|
||||
diagExt.getState env |>.enabled
|
||||
|
||||
def Kernel.resetDiag (env : Environment) : Environment :=
|
||||
diagExt.modifyState env fun s => { s with unfoldCounter := {} }
|
||||
|
||||
@[export lean_kernel_record_unfold]
|
||||
def Kernel.Diagnostics.recordUnfold (d : Diagnostics) (declName : Name) : Diagnostics :=
|
||||
if d.enabled then
|
||||
let cNew := if let some c := d.unfoldCounter.find? declName then c + 1 else 1
|
||||
{ d with unfoldCounter := d.unfoldCounter.insert declName cNew }
|
||||
else
|
||||
d
|
||||
|
||||
@[export lean_kernel_get_diag]
|
||||
def Kernel.getDiagnostics (env : Environment) : Diagnostics :=
|
||||
diagExt.getState env
|
||||
|
||||
@[export lean_kernel_set_diag]
|
||||
def Kernel.setDiagnostics (env : Environment) (diag : Diagnostics) : Environment :=
|
||||
diagExt.setState env diag
|
||||
def Kernel.setDiagnostics (env : Lean.Environment) (diag : Diagnostics) : Lean.Environment :=
|
||||
{ env with base := env.base.setDiagnostics diag }
|
||||
|
||||
namespace Environment
|
||||
|
||||
|
|
@ -1014,22 +1082,29 @@ private def isNamespaceName : Name → Bool
|
|||
| .str p _ => isNamespaceName p
|
||||
| _ => false
|
||||
|
||||
private def registerNamePrefixes : Environment → Name → Environment
|
||||
| env, .str p _ => if isNamespaceName p then registerNamePrefixes (registerNamespace env p) p else env
|
||||
| env, _ => env
|
||||
|
||||
@[export lean_environment_add]
|
||||
private def add (env : Environment) (cinfo : ConstantInfo) : Environment :=
|
||||
let name := cinfo.name
|
||||
let env := match name with
|
||||
private def registerNamePrefixes (env : Environment) (name : Name) : Environment :=
|
||||
match name with
|
||||
| .str _ s =>
|
||||
if s.get 0 == '_' then
|
||||
-- Do not register namespaces that only contain internal declarations.
|
||||
env
|
||||
else
|
||||
registerNamePrefixes env name
|
||||
go env name
|
||||
| _ => env
|
||||
env.addAux cinfo
|
||||
where go env
|
||||
| .str p _ => if isNamespaceName p then go (registerNamespace env p) p else env
|
||||
| _ => env
|
||||
|
||||
@[export lean_elab_environment_update_base_after_kernel_add]
|
||||
private def updateBaseAfterKernelAdd (env : Environment) (added : Declaration) (base : Kernel.Environment) : Environment := Id.run do
|
||||
let mut env := { env with base }
|
||||
env := added.getNames.foldl registerNamePrefixes env
|
||||
if let .inductDecl _ _ types _ := added then
|
||||
-- also register inductive type names as namespaces; this used to be done by the kernel itself
|
||||
-- when adding e.g. the recursor but now that the environment extension API exists only for
|
||||
-- `Lean.Environment`, we have to do it here
|
||||
env := types.foldl (registerNamePrefixes · <| ·.name ++ `rec) env
|
||||
env
|
||||
|
||||
@[export lean_display_stats]
|
||||
def displayStats (env : Environment) : IO Unit := do
|
||||
|
|
@ -1039,7 +1114,7 @@ def displayStats (env : Environment) : IO Unit := do
|
|||
IO.println ("number of memory-mapped modules: " ++ toString (env.header.regions.filter (·.isMemoryMapped) |>.size));
|
||||
IO.println ("number of buckets for imported consts: " ++ toString env.constants.numBuckets);
|
||||
IO.println ("trust level: " ++ toString env.header.trustLevel);
|
||||
IO.println ("number of extensions: " ++ toString env.extensions.size);
|
||||
IO.println ("number of extensions: " ++ toString env.base.extensions.size);
|
||||
pExtDescrs.forM fun extDescr => do
|
||||
IO.println ("extension '" ++ toString extDescr.name ++ "'")
|
||||
let s := extDescr.toEnvExtension.getState env
|
||||
|
|
@ -1085,27 +1160,33 @@ namespace Kernel
|
|||
|
||||
/--
|
||||
Kernel isDefEq predicate. We use it mainly for debugging purposes.
|
||||
Recall that the Kernel type checker does not support metavariables.
|
||||
Recall that the kernel type checker does not support metavariables.
|
||||
When implementing automation, consider using the `MetaM` methods. -/
|
||||
-- We use `Lean.Environment` for ease of use; as this is a debugging function, we forgo a
|
||||
-- `Kernel.Environment` base variant
|
||||
@[extern "lean_kernel_is_def_eq"]
|
||||
opaque isDefEq (env : Environment) (lctx : LocalContext) (a b : Expr) : Except KernelException Bool
|
||||
opaque isDefEq (env : Lean.Environment) (lctx : LocalContext) (a b : Expr) : Except Kernel.Exception Bool
|
||||
|
||||
def isDefEqGuarded (env : Environment) (lctx : LocalContext) (a b : Expr) : Bool :=
|
||||
def isDefEqGuarded (env : Lean.Environment) (lctx : LocalContext) (a b : Expr) : Bool :=
|
||||
if let .ok result := isDefEq env lctx a b then result else false
|
||||
|
||||
/--
|
||||
Kernel WHNF function. We use it mainly for debugging purposes.
|
||||
Recall that the Kernel type checker does not support metavariables.
|
||||
Recall that the kernel type checker does not support metavariables.
|
||||
When implementing automation, consider using the `MetaM` methods. -/
|
||||
-- We use `Lean.Environment` for ease of use; as this is a debugging function, we forgo a
|
||||
-- `Kernel.Environment` base variant
|
||||
@[extern "lean_kernel_whnf"]
|
||||
opaque whnf (env : Environment) (lctx : LocalContext) (a : Expr) : Except KernelException Expr
|
||||
opaque whnf (env : Lean.Environment) (lctx : LocalContext) (a : Expr) : Except Kernel.Exception Expr
|
||||
|
||||
/--
|
||||
Kernel typecheck function. We use it mainly for debugging purposes.
|
||||
Recall that the Kernel type checker does not support metavariables.
|
||||
When implementing automation, consider using the `MetaM` methods. -/
|
||||
-- We use `Lean.Environment` for ease of use; as this is a debugging function, we forgo a
|
||||
-- `Kernel.Environment` base variant
|
||||
@[extern "lean_kernel_check"]
|
||||
opaque check (env : Environment) (lctx : LocalContext) (a : Expr) : Except KernelException Expr
|
||||
opaque check (env : Lean.Environment) (lctx : LocalContext) (a : Expr) : Except Kernel.Exception Expr
|
||||
|
||||
end Kernel
|
||||
|
||||
|
|
|
|||
|
|
@ -89,11 +89,11 @@ def ofExcept [Monad m] [MonadError m] [ToMessageData ε] (x : Except ε α) : m
|
|||
/--
|
||||
Throw an error exception for the given kernel exception.
|
||||
-/
|
||||
def throwKernelException [Monad m] [MonadError m] [MonadOptions m] (ex : KernelException) : m α := do
|
||||
def throwKernelException [Monad m] [MonadError m] [MonadOptions m] (ex : Kernel.Exception) : m α := do
|
||||
Lean.throwError <| ex.toMessageData (← getOptions)
|
||||
|
||||
/-- Lift from `Except KernelException` to `m` when `m` can throw kernel exceptions. -/
|
||||
def ofExceptKernelException [Monad m] [MonadError m] [MonadOptions m] (x : Except KernelException α) : m α :=
|
||||
def ofExceptKernelException [Monad m] [MonadError m] [MonadOptions m] (x : Except Kernel.Exception α) : m α :=
|
||||
match x with
|
||||
| .ok a => return a
|
||||
| .error e => throwKernelException e
|
||||
|
|
|
|||
|
|
@ -540,12 +540,12 @@ macro_rules
|
|||
def toMessageList (msgs : Array MessageData) : MessageData :=
|
||||
indentD (MessageData.joinSep msgs.toList m!"\n\n")
|
||||
|
||||
namespace KernelException
|
||||
namespace Kernel.Exception
|
||||
|
||||
private def mkCtx (env : Environment) (lctx : LocalContext) (opts : Options) (msg : MessageData) : MessageData :=
|
||||
MessageData.withContext { env := env, mctx := {}, lctx := lctx, opts := opts } msg
|
||||
MessageData.withContext { env := .ofKernelEnv env, mctx := {}, lctx := lctx, opts := opts } msg
|
||||
|
||||
def toMessageData (e : KernelException) (opts : Options) : MessageData :=
|
||||
def toMessageData (e : Kernel.Exception) (opts : Options) : MessageData :=
|
||||
match e with
|
||||
| unknownConstant env constName => mkCtx env {} opts m!"(kernel) unknown constant '{constName}'"
|
||||
| alreadyDeclared env constName => mkCtx env {} opts m!"(kernel) constant has already been declared '{.ofConstName constName true}'"
|
||||
|
|
@ -573,5 +573,5 @@ def toMessageData (e : KernelException) (opts : Options) : MessageData :=
|
|||
| deepRecursion => "(kernel) deep recursion detected"
|
||||
| interrupted => "(kernel) interrupted"
|
||||
|
||||
end KernelException
|
||||
end Kernel.Exception
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import Lean.Meta.Basic
|
|||
|
||||
namespace Lean
|
||||
|
||||
@[extern "lean_mk_cases_on"] opaque mkCasesOnImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
@[extern "lean_mk_cases_on"] opaque mkCasesOnImp (env : Kernel.Environment) (declName : @& Name) : Except Kernel.Exception Declaration
|
||||
|
||||
open Meta
|
||||
|
||||
def mkCasesOn (declName : Name) : MetaM Unit := do
|
||||
let name := mkCasesOnName declName
|
||||
let decl ← ofExceptKernelException (mkCasesOnImp (← getEnv) declName)
|
||||
let decl ← ofExceptKernelException (mkCasesOnImp (← getEnv).toKernelEnv declName)
|
||||
addDecl decl
|
||||
setReducibleAttribute name
|
||||
modifyEnv fun env => markAuxRecursor env name
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import Lean.Meta.CompletionName
|
|||
|
||||
namespace Lean
|
||||
|
||||
@[extern "lean_mk_no_confusion_type"] opaque mkNoConfusionTypeCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
@[extern "lean_mk_no_confusion"] opaque mkNoConfusionCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
|
||||
@[extern "lean_mk_no_confusion_type"] opaque mkNoConfusionTypeCoreImp (env : Environment) (declName : @& Name) : Except Kernel.Exception Declaration
|
||||
@[extern "lean_mk_no_confusion"] opaque mkNoConfusionCoreImp (env : Environment) (declName : @& Name) : Except Kernel.Exception Declaration
|
||||
|
||||
open Meta
|
||||
|
||||
|
|
|
|||
|
|
@ -49,13 +49,11 @@ def isTodo (name : Name) : M Bool := do
|
|||
else
|
||||
return false
|
||||
|
||||
/-- Use the current `Environment` to throw a `KernelException`. -/
|
||||
def throwKernelException (ex : KernelException) : M Unit := do
|
||||
let ctx := { fileName := "", options := ({} : KVMap), fileMap := default }
|
||||
let state := { env := (← get).env }
|
||||
Prod.fst <$> (Lean.Core.CoreM.toIO · ctx state) do Lean.throwKernelException ex
|
||||
/-- Use the current `Environment` to throw a `Kernel.Exception`. -/
|
||||
def throwKernelException (ex : Kernel.Exception) : M Unit := do
|
||||
throw <| .userError <| (← ex.toMessageData {} |>.toString)
|
||||
|
||||
/-- Add a declaration, possibly throwing a `KernelException`. -/
|
||||
/-- Add a declaration, possibly throwing a `Kernel.Exception`. -/
|
||||
def addDecl (d : Declaration) : M Unit := do
|
||||
match (← get).env.addDecl {} d with
|
||||
| .ok env => modify fun s => { s with env := env }
|
||||
|
|
|
|||
|
|
@ -19,16 +19,9 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
extern "C" object* lean_environment_add(object*, object*);
|
||||
extern "C" object* lean_mk_empty_environment(uint32, object*);
|
||||
extern "C" object* lean_environment_find(object*, object*);
|
||||
extern "C" uint32 lean_environment_trust_level(object*);
|
||||
extern "C" object* lean_environment_mark_quot_init(object*);
|
||||
extern "C" uint8 lean_environment_quot_init(object*);
|
||||
extern "C" object* lean_register_extension(object*);
|
||||
extern "C" object* lean_get_extension(object*, object*);
|
||||
extern "C" object* lean_set_extension(object*, object*, object*);
|
||||
extern "C" object* lean_environment_set_main_module(object*, object*);
|
||||
extern "C" object* lean_environment_main_module(object*);
|
||||
extern "C" object* lean_kernel_record_unfold (object*, object*);
|
||||
extern "C" object* lean_kernel_get_diag(object*);
|
||||
extern "C" object* lean_kernel_set_diag(object*, object*);
|
||||
|
|
@ -62,14 +55,6 @@ environment scoped_diagnostics::update(environment const & env) const {
|
|||
return env;
|
||||
}
|
||||
|
||||
environment mk_empty_environment(uint32 trust_lvl) {
|
||||
return get_io_result<environment>(lean_mk_empty_environment(trust_lvl, io_mk_world()));
|
||||
}
|
||||
|
||||
environment::environment(unsigned trust_lvl):
|
||||
object_ref(mk_empty_environment(trust_lvl)) {
|
||||
}
|
||||
|
||||
diagnostics environment::get_diag() const {
|
||||
return diagnostics(lean_kernel_get_diag(to_obj_arg()));
|
||||
}
|
||||
|
|
@ -78,18 +63,6 @@ environment environment::set_diag(diagnostics const & diag) const {
|
|||
return environment(lean_kernel_set_diag(to_obj_arg(), diag.to_obj_arg()));
|
||||
}
|
||||
|
||||
void environment::set_main_module(name const & n) {
|
||||
m_obj = lean_environment_set_main_module(m_obj, n.to_obj_arg());
|
||||
}
|
||||
|
||||
name environment::get_main_module() const {
|
||||
return name(lean_environment_main_module(to_obj_arg()));
|
||||
}
|
||||
|
||||
unsigned environment::trust_lvl() const {
|
||||
return lean_environment_trust_level(to_obj_arg());
|
||||
}
|
||||
|
||||
bool environment::is_quot_initialized() const {
|
||||
return lean_environment_quot_init(to_obj_arg()) != 0;
|
||||
}
|
||||
|
|
@ -297,7 +270,7 @@ environment environment::add(declaration const & d, bool check) const {
|
|||
}
|
||||
/*
|
||||
addDeclCore (env : Environment) (maxHeartbeats : USize) (decl : @& Declaration)
|
||||
(cancelTk? : @& Option IO.CancelToken) : Except KernelException Environment
|
||||
(cancelTk? : @& Option IO.CancelToken) : Except Kernel.Exception Environment
|
||||
*/
|
||||
extern "C" LEAN_EXPORT object * lean_add_decl(object * env, size_t max_heartbeat, object * decl,
|
||||
object * opt_cancel_tk) {
|
||||
|
|
@ -321,12 +294,6 @@ void environment::for_each_constant(std::function<void(constant_info const & d)>
|
|||
});
|
||||
}
|
||||
|
||||
extern "C" obj_res lean_display_stats(obj_arg env, obj_arg w);
|
||||
|
||||
void environment::display_stats() const {
|
||||
dec_ref(lean_display_stats(to_obj_arg(), io_mk_world()));
|
||||
}
|
||||
|
||||
void initialize_environment() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@ Author: Leonardo de Moura
|
|||
#endif
|
||||
|
||||
namespace lean {
|
||||
class environment_extension {
|
||||
public:
|
||||
virtual ~environment_extension() {}
|
||||
};
|
||||
|
||||
/* Wrapper for `Kernel.Diagnostics` */
|
||||
class diagnostics : public object_ref {
|
||||
|
|
@ -41,7 +37,7 @@ public:
|
|||
};
|
||||
|
||||
/*
|
||||
Store `Kernel.Diagnostics` stored in environment extension in `m_diag` IF
|
||||
Store `Kernel.Diagnostics` (to be stored in `Kernel.Environment.diagnostics`) in `m_diag` IF
|
||||
- `Kernel.Diagnostics.enable = true`
|
||||
- `collect = true`. This is a minor optimization.
|
||||
|
||||
|
|
@ -59,6 +55,7 @@ public:
|
|||
diagnostics * get() const { return m_diag; }
|
||||
};
|
||||
|
||||
/* Wrapper for `Lean.Kernel.Environment` */
|
||||
class LEAN_EXPORT environment : public object_ref {
|
||||
friend class add_inductive_fn;
|
||||
|
||||
|
|
@ -76,7 +73,6 @@ class LEAN_EXPORT environment : public object_ref {
|
|||
environment add_quot() const;
|
||||
environment add_inductive(declaration const & d) const;
|
||||
public:
|
||||
environment(unsigned trust_lvl = 0);
|
||||
environment(environment const & other):object_ref(other) {}
|
||||
environment(environment && other):object_ref(other) {}
|
||||
explicit environment(b_obj_arg o, bool b):object_ref(o, b) {}
|
||||
|
|
@ -89,15 +85,8 @@ public:
|
|||
diagnostics get_diag() const;
|
||||
environment set_diag(diagnostics const & diag) const;
|
||||
|
||||
/** \brief Return the trust level of this environment. */
|
||||
unsigned trust_lvl() const;
|
||||
|
||||
bool is_quot_initialized() const;
|
||||
|
||||
void set_main_module(name const & n);
|
||||
|
||||
name get_main_module() const;
|
||||
|
||||
/** \brief Return information for the constant with name \c n (if it is defined in this environment). */
|
||||
optional<constant_info> find(name const & n) const;
|
||||
|
||||
|
|
@ -114,8 +103,6 @@ public:
|
|||
friend bool is_eqp(environment const & e1, environment const & e2) {
|
||||
return e1.raw() == e2.raw();
|
||||
}
|
||||
|
||||
void display_stats() const;
|
||||
};
|
||||
|
||||
void check_no_metavar_no_fvar(environment const & env, name const & n, expr const & e);
|
||||
|
|
|
|||
|
|
@ -152,9 +152,9 @@ public:
|
|||
/*
|
||||
Helper function for interfacing C++ code with code written in Lean.
|
||||
It executes closure `f` which produces an object_ref of type `A` and may throw
|
||||
an `kernel_exception` or `exception`. Then, convert result into `Except KernelException T`
|
||||
an `kernel_exception` or `exception`. Then, convert result into `Except Kernel.Exception T`
|
||||
where `T` is the type of the lean objected represented by `A`.
|
||||
We use the constructor `KernelException.other <msg>` to handle C++ `exception` objects which
|
||||
We use the constructor `Kernel.Exception.other <msg>` to handle C++ `exception` objects which
|
||||
are not `kernel_exception`.
|
||||
*/
|
||||
template<typename A>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Author: Leonardo de Moura
|
|||
#include <string>
|
||||
#include "util/io.h"
|
||||
#include "util/option_declarations.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "kernel/local_ctx.h"
|
||||
#include "kernel/trace.h"
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ static name_set * g_trace_classes = nullptr;
|
|||
static name_map<name_set> * g_trace_aliases = nullptr;
|
||||
MK_THREAD_LOCAL_GET_DEF(std::vector<name>, get_enabled_trace_classes);
|
||||
MK_THREAD_LOCAL_GET_DEF(std::vector<name>, get_disabled_trace_classes);
|
||||
LEAN_THREAD_PTR(environment, g_env);
|
||||
LEAN_THREAD_PTR(elab_environment, g_env);
|
||||
LEAN_THREAD_PTR(options, g_opts);
|
||||
|
||||
void register_trace_class(name const & n, name const & decl_name) {
|
||||
|
|
@ -90,7 +90,7 @@ bool is_trace_class_enabled(name const & n) {
|
|||
}
|
||||
|
||||
|
||||
void scope_trace_env::init(environment * env, options * opts) {
|
||||
void scope_trace_env::init(elab_environment * env, options * opts) {
|
||||
m_enable_sz = get_enabled_trace_classes().size();
|
||||
m_disable_sz = get_disabled_trace_classes().size();
|
||||
m_old_env = g_env;
|
||||
|
|
@ -111,12 +111,12 @@ void scope_trace_env::init(environment * env, options * opts) {
|
|||
g_opts = opts;
|
||||
}
|
||||
|
||||
scope_trace_env::scope_trace_env(environment const & env, options const & o) {
|
||||
init(const_cast<environment*>(&env), const_cast<options*>(&o));
|
||||
scope_trace_env::scope_trace_env(elab_environment const & env, options const & o) {
|
||||
init(const_cast<elab_environment*>(&env), const_cast<options*>(&o));
|
||||
}
|
||||
|
||||
scope_trace_env::~scope_trace_env() {
|
||||
g_env = const_cast<environment*>(m_old_env);
|
||||
g_env = const_cast<elab_environment*>(m_old_env);
|
||||
g_opts = const_cast<options*>(m_old_opts);
|
||||
get_enabled_trace_classes().resize(m_enable_sz);
|
||||
get_disabled_trace_classes().resize(m_disable_sz);
|
||||
|
|
@ -169,7 +169,7 @@ def pretty (f : Format) (w : Nat := defWidth) (indent : Nat := 0) (column := 0)
|
|||
*/
|
||||
extern "C" object * lean_format_pretty(object * f, object * w, object * i, object * c);
|
||||
|
||||
std::string pp_expr(environment const & env, options const & opts, local_ctx const & lctx, expr const & e) {
|
||||
std::string pp_expr(elab_environment const & env, options const & opts, local_ctx const & lctx, expr const & e) {
|
||||
options o = opts;
|
||||
// o = o.update(name{"pp", "proofs"}, true); --
|
||||
object_ref fmt = get_io_result<object_ref>(lean_pp_expr(env.to_obj_arg(), lean_mk_metavar_ctx(lean_box(0)), lctx.to_obj_arg(), o.to_obj_arg(),
|
||||
|
|
@ -178,7 +178,7 @@ std::string pp_expr(environment const & env, options const & opts, local_ctx con
|
|||
return str.to_std_string();
|
||||
}
|
||||
|
||||
std::string pp_expr(environment const & env, options const & opts, expr const & e) {
|
||||
std::string pp_expr(elab_environment const & env, options const & opts, expr const & e) {
|
||||
local_ctx lctx;
|
||||
return pp_expr(env, opts, lctx, e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Author: Leonardo de Moura
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "util/options.h"
|
||||
#include "util/message_definitions.h"
|
||||
|
||||
|
|
@ -20,13 +20,13 @@ bool is_trace_class_enabled(name const & n);
|
|||
#define lean_is_trace_enabled(CName) (::lean::is_trace_enabled() && ::lean::is_trace_class_enabled(CName))
|
||||
|
||||
class scope_trace_env {
|
||||
unsigned m_enable_sz;
|
||||
unsigned m_disable_sz;
|
||||
environment const * m_old_env;
|
||||
options const * m_old_opts;
|
||||
void init(environment * env, options * opts);
|
||||
unsigned m_enable_sz;
|
||||
unsigned m_disable_sz;
|
||||
elab_environment const * m_old_env;
|
||||
options const * m_old_opts;
|
||||
void init(elab_environment * env, options * opts);
|
||||
public:
|
||||
scope_trace_env(environment const & env, options const & opts);
|
||||
scope_trace_env(elab_environment const & env, options const & opts);
|
||||
~scope_trace_env();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ static expr * g_lean_reduce_bool = nullptr;
|
|||
static expr * g_lean_reduce_nat = nullptr;
|
||||
|
||||
namespace ir {
|
||||
object * run_boxed(environment const & env, options const & opts, name const & fn, unsigned n, object **args);
|
||||
object * run_boxed_kernel(environment const & env, options const & opts, name const & fn, unsigned n, object **args);
|
||||
}
|
||||
|
||||
expr mk_bool_true();
|
||||
|
|
@ -560,7 +560,7 @@ optional<expr> reduce_native(environment const & env, expr const & e) {
|
|||
expr const & arg = app_arg(e);
|
||||
if (!is_constant(arg)) return none_expr();
|
||||
if (app_fn(e) == *g_lean_reduce_bool) {
|
||||
object * r = ir::run_boxed(env, options(), const_name(arg), 0, nullptr);
|
||||
object * r = ir::run_boxed_kernel(env, options(), const_name(arg), 0, nullptr);
|
||||
if (!lean_is_scalar(r)) {
|
||||
lean_dec_ref(r);
|
||||
throw kernel_exception(env, "type checker failure, unexpected result value for 'Lean.reduceBool'");
|
||||
|
|
@ -568,7 +568,7 @@ optional<expr> reduce_native(environment const & env, expr const & e) {
|
|||
return lean_unbox(r) == 0 ? some_expr(mk_bool_false()) : some_expr(mk_bool_true());
|
||||
}
|
||||
if (app_fn(e) == *g_lean_reduce_nat) {
|
||||
object * r = ir::run_boxed(env, options(), const_name(arg), 0, nullptr);
|
||||
object * r = ir::run_boxed_kernel(env, options(), const_name(arg), 0, nullptr);
|
||||
if (lean_is_scalar(r) || lean_is_mpz(r)) {
|
||||
return some_expr(mk_lit(literal(nat(r))));
|
||||
} else {
|
||||
|
|
@ -1193,24 +1193,6 @@ type_checker::~type_checker() {
|
|||
delete m_st;
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT lean_object * lean_kernel_is_def_eq(lean_object * env, lean_object * lctx, lean_object * a, lean_object * b) {
|
||||
return catch_kernel_exceptions<object*>([&]() {
|
||||
return lean_box(type_checker(environment(env), local_ctx(lctx)).is_def_eq(expr(a), expr(b)));
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT lean_object * lean_kernel_whnf(lean_object * env, lean_object * lctx, lean_object * a) {
|
||||
return catch_kernel_exceptions<object*>([&]() {
|
||||
return type_checker(environment(env), local_ctx(lctx)).whnf(expr(a)).steal();
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT lean_object * lean_kernel_check(lean_object * env, lean_object * lctx, lean_object * a) {
|
||||
return catch_kernel_exceptions<object*>([&]() {
|
||||
return type_checker(environment(env), local_ctx(lctx)).check(expr(a)).steal();
|
||||
});
|
||||
}
|
||||
|
||||
inline static expr * new_persistent_expr_const(name const & n) {
|
||||
expr * e = new expr(mk_const(n));
|
||||
mark_persistent(e->raw());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Author: Leonardo de Moura
|
|||
#include <memory>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include "runtime/flet.h"
|
||||
#include "util/lbool.h"
|
||||
#include "util/name_set.h"
|
||||
#include "util/name_generator.h"
|
||||
|
|
@ -104,6 +105,7 @@ private:
|
|||
optional<expr> reduce_pow(expr const & e);
|
||||
optional<expr> reduce_nat(expr const & e);
|
||||
public:
|
||||
// The following two constructor are used only by the old compiler and should be deleted with it
|
||||
type_checker(state & st, local_ctx const & lctx, definition_safety ds = definition_safety::safe);
|
||||
type_checker(state & st, definition_safety ds = definition_safety::safe):type_checker(st, local_ctx(), ds) {}
|
||||
type_checker(environment const & env, local_ctx const & lctx, diagnostics * diag = nullptr, definition_safety ds = definition_safety::safe);
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ def elabConfigFile (pkgDir : FilePath) (lakeOpts : NameMap String)
|
|||
return s.commandState.env
|
||||
|
||||
/--
|
||||
`Lean.Environment.add` is now private, but exported as `lean_environment_add`.
|
||||
`Lean.Environment.add` is now private, but exported as `lean_elab_environment_add`.
|
||||
We call it here via `@[extern]` with a mock implementation.
|
||||
-/
|
||||
@[extern "lean_environment_add"]
|
||||
@[extern "lean_elab_environment_add"]
|
||||
private opaque addToEnv (env : Environment) (_ : ConstantInfo) : Environment
|
||||
|
||||
/--
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ add_library(library OBJECT expr_lt.cpp
|
|||
projection.cpp
|
||||
aux_recursors.cpp
|
||||
profiling.cpp time_task.cpp
|
||||
formatter.cpp)
|
||||
formatter.cpp
|
||||
elab_environment.cpp)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ namespace lean {
|
|||
extern "C" uint8 lean_is_aux_recursor(object * env, object * n);
|
||||
extern "C" uint8 lean_is_no_confusion(object * env, object * n);
|
||||
|
||||
bool is_aux_recursor(environment const & env, name const & r) {
|
||||
bool is_aux_recursor(elab_environment const & env, name const & r) {
|
||||
return lean_is_aux_recursor(env.to_obj_arg(), r.to_obj_arg());
|
||||
}
|
||||
|
||||
bool is_no_confusion(environment const & env, name const & r) {
|
||||
bool is_no_confusion(elab_environment const & env, name const & r) {
|
||||
return lean_is_no_confusion(env.to_obj_arg(), r.to_obj_arg());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Return true iff \c n is the name of an auxiliary recursor.
|
||||
\see add_aux_recursor */
|
||||
bool is_aux_recursor(environment const & env, name const & n);
|
||||
bool is_no_confusion(environment const & env, name const & n);
|
||||
bool is_aux_recursor(elab_environment const & env, name const & n);
|
||||
bool is_no_confusion(elab_environment const & env, name const & n);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ extern "C" uint8 lean_is_out_param(object* e);
|
|||
extern "C" uint8 lean_has_out_params(object* env, object* n);
|
||||
|
||||
bool is_class_out_param(expr const & e) { return lean_is_out_param(e.to_obj_arg()); }
|
||||
bool has_class_out_params(environment const & env, name const & c) { return lean_has_out_params(env.to_obj_arg(), c.to_obj_arg()); }
|
||||
bool is_class(environment const & env, name const & c) { return lean_is_class(env.to_obj_arg(), c.to_obj_arg()); }
|
||||
bool is_instance(environment const & env, name const & i) { return lean_is_instance(env.to_obj_arg(), i.to_obj_arg()); }
|
||||
bool has_class_out_params(elab_environment const & env, name const & c) { return lean_has_out_params(env.to_obj_arg(), c.to_obj_arg()); }
|
||||
bool is_class(elab_environment const & env, name const & c) { return lean_is_class(env.to_obj_arg(), c.to_obj_arg()); }
|
||||
bool is_instance(elab_environment const & env, name const & i) { return lean_is_instance(env.to_obj_arg(), i.to_obj_arg()); }
|
||||
|
||||
static name * g_anonymous_inst_name_prefix = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#pragma once
|
||||
#include "library/util.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
/** \brief Return true iff \c c was declared with \c add_class. */
|
||||
bool is_class(environment const & env, name const & c);
|
||||
bool is_class(elab_environment const & env, name const & c);
|
||||
/** \brief Return true iff \c i was declared with \c add_instance. */
|
||||
bool is_instance(environment const & env, name const & i);
|
||||
bool is_instance(elab_environment const & env, name const & i);
|
||||
|
||||
name const & get_anonymous_instance_prefix();
|
||||
name mk_anonymous_inst_name(unsigned idx);
|
||||
|
|
@ -20,7 +21,7 @@ bool is_anonymous_inst_name(name const & n);
|
|||
bool is_class_out_param(expr const & e);
|
||||
|
||||
/** \brief Return true iff c is a type class that contains an `outParam` */
|
||||
bool has_class_out_params(environment const & env, name const & c);
|
||||
bool has_class_out_params(elab_environment const & env, name const & c);
|
||||
|
||||
void initialize_class();
|
||||
void finalize_class();
|
||||
|
|
|
|||
|
|
@ -5,16 +5,17 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "library/util.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
extern "C" object * lean_cache_closed_term_name(object * env, object * e, object * n);
|
||||
extern "C" object * lean_get_closed_term_name(object * env, object * e);
|
||||
|
||||
optional<name> get_closed_term_name(environment const & env, expr const & e) {
|
||||
optional<name> get_closed_term_name(elab_environment const & env, expr const & e) {
|
||||
return to_optional<name>(lean_get_closed_term_name(env.to_obj_arg(), e.to_obj_arg()));
|
||||
}
|
||||
|
||||
environment cache_closed_term_name(environment const & env, expr const & e, name const & n) {
|
||||
return environment(lean_cache_closed_term_name(env.to_obj_arg(), e.to_obj_arg(), n.to_obj_arg()));
|
||||
elab_environment cache_closed_term_name(elab_environment const & env, expr const & e, name const & n) {
|
||||
return elab_environment(lean_cache_closed_term_name(env.to_obj_arg(), e.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
optional<name> get_closed_term_name(environment const & env, expr const & e);
|
||||
environment cache_closed_term_name(environment const & env, expr const & e, name const & n);
|
||||
optional<name> get_closed_term_name(elab_environment const & env, expr const & e);
|
||||
elab_environment cache_closed_term_name(elab_environment const & env, expr const & e, name const & n);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,19 +44,19 @@ static name get_real_name(name const & n) {
|
|||
return n;
|
||||
}
|
||||
|
||||
static comp_decls to_comp_decls(environment const & env, names const & cs) {
|
||||
static comp_decls to_comp_decls(elab_environment const & env, names const & cs) {
|
||||
bool allow_opaque = true;
|
||||
return map2<comp_decl>(cs, [&](name const & n) {
|
||||
return comp_decl(get_real_name(n), env.get(n).get_value(allow_opaque));
|
||||
});
|
||||
}
|
||||
|
||||
static expr eta_expand(environment const & env, expr const & e) {
|
||||
return type_checker(env).eta_expand(e);
|
||||
static expr eta_expand(elab_environment const & env, expr const & e) {
|
||||
return type_checker(env.to_kernel_env()).eta_expand(e);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
comp_decls apply(F && f, environment const & env, comp_decls const & ds) {
|
||||
comp_decls apply(F && f, elab_environment const & env, comp_decls const & ds) {
|
||||
return map(ds, [&](comp_decl const & d) { return comp_decl(d.fst(), f(env, d.snd())); });
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ void trace_comp_decls(comp_decls const & ds) {
|
|||
}
|
||||
}
|
||||
|
||||
static environment cache_stage1(environment env, comp_decls const & ds) {
|
||||
static elab_environment cache_stage1(elab_environment env, comp_decls const & ds) {
|
||||
for (comp_decl const & d : ds) {
|
||||
name n = d.fst();
|
||||
expr v = d.snd();
|
||||
|
|
@ -94,7 +94,7 @@ static expr ensure_arity(expr const & t, unsigned arity) {
|
|||
return update_binding(t, binding_domain(t), ensure_arity(binding_body(t), arity-1));
|
||||
}
|
||||
|
||||
static environment cache_stage2(environment env, comp_decls const & ds, bool only_new_ones = false) {
|
||||
static elab_environment cache_stage2(elab_environment env, comp_decls const & ds, bool only_new_ones = false) {
|
||||
buffer<expr> ts;
|
||||
ll_infer_type(env, ds, ts);
|
||||
lean_assert(ts.size() == length(ds));
|
||||
|
|
@ -116,11 +116,11 @@ static environment cache_stage2(environment env, comp_decls const & ds, bool onl
|
|||
}
|
||||
|
||||
/* Cache the declarations in `ds` that have not already been cached. */
|
||||
static environment cache_new_stage2(environment env, comp_decls const & ds) {
|
||||
static elab_environment cache_new_stage2(elab_environment env, comp_decls const & ds) {
|
||||
return cache_stage2(env, ds, true);
|
||||
}
|
||||
|
||||
bool is_main_fn(environment const & env, name const & n) {
|
||||
bool is_main_fn(elab_environment const & env, name const & n) {
|
||||
if (n == "main") return true;
|
||||
if (optional<name> c = get_export_name_for(env, n)) {
|
||||
return *c == "main";
|
||||
|
|
@ -160,15 +160,15 @@ bool is_main_fn_type(expr const & type) {
|
|||
|
||||
extern "C" object* lean_csimp_replace_constants(object* env, object* n);
|
||||
|
||||
expr csimp_replace_constants(environment const & env, expr const & e) {
|
||||
expr csimp_replace_constants(elab_environment const & env, expr const & e) {
|
||||
return expr(lean_csimp_replace_constants(env.to_obj_arg(), e.to_obj_arg()));
|
||||
}
|
||||
|
||||
bool is_matcher(environment const & env, comp_decls const & ds) {
|
||||
bool is_matcher(elab_environment const & env, comp_decls const & ds) {
|
||||
return length(ds) == 1 && is_matcher(env, head(ds).fst());
|
||||
}
|
||||
|
||||
environment compile(environment const & env, options const & opts, names cs) {
|
||||
elab_environment compile(elab_environment const & env, options const & opts, names cs) {
|
||||
/* Do not generate code for irrelevant decls */
|
||||
cs = filter(cs, [&](name const & c) { return !is_irrelevant_type(env, env.get(c).get_type());});
|
||||
if (empty(cs)) return env;
|
||||
|
|
@ -202,8 +202,8 @@ environment compile(environment const & env, options const & opts, names cs) {
|
|||
csimp_cfg cfg(opts);
|
||||
// Use the following line to see compiler intermediate steps
|
||||
// scope_traces_as_string trace_scope;
|
||||
auto simp = [&](environment const & env, expr const & e) { return csimp(env, e, cfg); };
|
||||
auto esimp = [&](environment const & env, expr const & e) { return cesimp(env, e, cfg); };
|
||||
auto simp = [&](elab_environment const & env, expr const & e) { return csimp(env, e, cfg); };
|
||||
auto esimp = [&](elab_environment const & env, expr const & e) { return cesimp(env, e, cfg); };
|
||||
trace_compiler(name({"compiler", "input"}), ds);
|
||||
ds = apply(eta_expand, env, ds);
|
||||
trace_compiler(name({"compiler", "eta_expand"}), ds);
|
||||
|
|
@ -218,7 +218,7 @@ environment compile(environment const & env, options const & opts, names cs) {
|
|||
ds = apply(simp, env, ds);
|
||||
trace_compiler(name({"compiler", "simp"}), ds);
|
||||
// trace(ds);
|
||||
environment new_env = env;
|
||||
elab_environment new_env = env;
|
||||
std::tie(new_env, ds) = eager_lambda_lifting(new_env, ds, cfg);
|
||||
trace_compiler(name({"compiler", "eager_lambda_lifting"}), ds);
|
||||
ds = apply(max_sharing, ds);
|
||||
|
|
@ -274,8 +274,8 @@ environment compile(environment const & env, options const & opts, names cs) {
|
|||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_compile_decls(object * env, object * opts, object * decls) {
|
||||
return catch_kernel_exceptions<environment>([&]() {
|
||||
return compile(environment(env), options(opts, true), names(decls, true));
|
||||
return catch_kernel_exceptions<elab_environment>([&]() {
|
||||
return compile(elab_environment(env), options(opts, true), names(decls, true));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
environment compile(environment const & env, options const & opts, names cs);
|
||||
inline environment compile(environment const & env, options const & opts, name const & c) {
|
||||
elab_environment compile(elab_environment const & env, options const & opts, names cs);
|
||||
inline elab_environment compile(elab_environment const & env, options const & opts, name const & c) {
|
||||
return compile(env, opts, names(c));
|
||||
}
|
||||
void initialize_compiler();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Author: Leonardo de Moura
|
|||
#include <vector>
|
||||
#include "runtime/flet.h"
|
||||
#include "util/name_generator.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "kernel/instantiate.h"
|
||||
#include "kernel/abstract.h"
|
||||
#include "kernel/for_each_fn.h"
|
||||
|
|
@ -21,7 +21,7 @@ namespace lean {
|
|||
static name * g_cse_fresh = nullptr;
|
||||
|
||||
class cse_fn {
|
||||
environment m_env;
|
||||
elab_environment m_env;
|
||||
name_generator m_ngen;
|
||||
bool m_before_erasure;
|
||||
expr_map<expr> m_map;
|
||||
|
|
@ -148,14 +148,14 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
cse_fn(environment const & env, bool before_erasure):
|
||||
cse_fn(elab_environment const & env, bool before_erasure):
|
||||
m_env(env), m_ngen(*g_cse_fresh), m_before_erasure(before_erasure) {
|
||||
}
|
||||
|
||||
expr operator()(expr const & e) { return visit(e); }
|
||||
};
|
||||
|
||||
expr cse_core(environment const & env, expr const & e, bool before_erasure) {
|
||||
expr cse_core(elab_environment const & env, expr const & e, bool before_erasure) {
|
||||
return cse_fn(env, before_erasure)(e);
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +170,7 @@ expr cse_core(environment const & env, expr const & e, bool before_erasure) {
|
|||
```
|
||||
The "else"-branch is duplicated by the equation compiler for each constructor different from `expr.app`. */
|
||||
class cce_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
buffer<expr> m_fvars;
|
||||
|
|
@ -178,7 +179,7 @@ class cce_fn {
|
|||
name m_j;
|
||||
unsigned m_next_idx{1};
|
||||
public:
|
||||
environment & env() { return m_st.env(); }
|
||||
elab_environment & env() { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -394,8 +395,8 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
cce_fn(environment const & env, local_ctx const & lctx):
|
||||
m_st(env), m_lctx(lctx), m_j("_j") {
|
||||
cce_fn(elab_environment const & env, local_ctx const & lctx):
|
||||
m_env(env), m_st(env), m_lctx(lctx), m_j("_j") {
|
||||
}
|
||||
|
||||
expr operator()(expr const & e) {
|
||||
|
|
@ -404,7 +405,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
expr cce_core(environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
expr cce_core(elab_environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
return cce_fn(env, lctx)(e);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
/* Common subexpression elimination */
|
||||
expr cse_core(environment const & env, expr const & e, bool before_erasure);
|
||||
inline expr cse(environment const & env, expr const & e) { return cse_core(env, e, true); }
|
||||
inline expr ecse(environment const & env, expr const & e) { return cse_core(env, e, false); }
|
||||
expr cse_core(elab_environment const & env, expr const & e, bool before_erasure);
|
||||
inline expr cse(elab_environment const & env, expr const & e) { return cse_core(env, e, true); }
|
||||
inline expr ecse(elab_environment const & env, expr const & e) { return cse_core(env, e, false); }
|
||||
/* Common case elimination */
|
||||
expr cce_core(environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr cce(environment const & env, expr const & e) { return cce_core(env, local_ctx(), e); }
|
||||
expr cce_core(elab_environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr cce(elab_environment const & env, expr const & e) { return cce_core(env, local_ctx(), e); }
|
||||
void initialize_cse();
|
||||
void finalize_cse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ optional<expr> fold_bin_op(bool before_erasure, expr const & f, expr const & a,
|
|||
|
||||
class csimp_fn {
|
||||
typedef expr_pair_struct_map<expr> jp_cache;
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
bool m_before_erasure;
|
||||
|
|
@ -96,7 +97,7 @@ class csimp_fn {
|
|||
typedef rb_expr_map<expr> expr2ctor;
|
||||
expr2ctor m_expr2ctor;
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -1625,12 +1626,12 @@ class csimp_fn {
|
|||
}
|
||||
|
||||
struct is_recursive_fn {
|
||||
environment const & m_env;
|
||||
elab_environment const & m_env;
|
||||
csimp_cfg const & m_cfg;
|
||||
bool m_before_erasure;
|
||||
name m_target;
|
||||
|
||||
is_recursive_fn(environment const & env, csimp_cfg const & cfg, bool before_erasure):
|
||||
is_recursive_fn(elab_environment const & env, csimp_cfg const & cfg, bool before_erasure):
|
||||
m_env(env), m_cfg(cfg), m_before_erasure(before_erasure) {
|
||||
}
|
||||
|
||||
|
|
@ -1969,8 +1970,8 @@ class csimp_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
csimp_fn(environment const & env, local_ctx const & lctx, bool before_erasure, csimp_cfg const & cfg):
|
||||
m_st(env), m_lctx(lctx), m_before_erasure(before_erasure), m_cfg(cfg), m_x("_x"), m_j("j") {}
|
||||
csimp_fn(elab_environment const & env, local_ctx const & lctx, bool before_erasure, csimp_cfg const & cfg):
|
||||
m_env(env), m_st(env), m_lctx(lctx), m_before_erasure(before_erasure), m_cfg(cfg), m_x("_x"), m_j("j") {}
|
||||
|
||||
expr operator()(expr const & e) {
|
||||
if (is_lambda(e)) {
|
||||
|
|
@ -1992,7 +1993,7 @@ bool at_most_once(expr const & e, name const & x) {
|
|||
|
||||
/* Eliminate join-points that are used only once */
|
||||
class elim_jp1_fn {
|
||||
environment const & m_env;
|
||||
elab_environment const & m_env;
|
||||
local_ctx m_lctx;
|
||||
bool m_before_erasure;
|
||||
name_generator m_ngen;
|
||||
|
|
@ -2093,7 +2094,7 @@ class elim_jp1_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
elim_jp1_fn(environment const & env, local_ctx const & lctx, bool before_erasure):
|
||||
elim_jp1_fn(elab_environment const & env, local_ctx const & lctx, bool before_erasure):
|
||||
m_env(env), m_lctx(lctx), m_before_erasure(before_erasure) {}
|
||||
expr operator()(expr const & e) {
|
||||
m_expanded = false;
|
||||
|
|
@ -2103,7 +2104,7 @@ public:
|
|||
bool expanded() const { return m_expanded; }
|
||||
};
|
||||
|
||||
expr csimp_core(environment const & env, local_ctx const & lctx, expr const & e0, bool before_erasure, csimp_cfg const & cfg) {
|
||||
expr csimp_core(elab_environment const & env, local_ctx const & lctx, expr const & e0, bool before_erasure, csimp_cfg const & cfg) {
|
||||
csimp_fn simp(env, lctx, before_erasure, cfg);
|
||||
elim_jp1_fn elim_jp1(env, lctx, before_erasure);
|
||||
expr e = e0;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
struct csimp_cfg {
|
||||
/* If `m_inline` == false, then we will not inline `c` even if it is marked with the attribute `[inline]`. */
|
||||
|
|
@ -23,11 +23,11 @@ public:
|
|||
csimp_cfg();
|
||||
};
|
||||
|
||||
expr csimp_core(environment const & env, local_ctx const & lctx, expr const & e, bool before_erasure, csimp_cfg const & cfg);
|
||||
inline expr csimp(environment const & env, expr const & e, csimp_cfg const & cfg = csimp_cfg()) {
|
||||
expr csimp_core(elab_environment const & env, local_ctx const & lctx, expr const & e, bool before_erasure, csimp_cfg const & cfg);
|
||||
inline expr csimp(elab_environment const & env, expr const & e, csimp_cfg const & cfg = csimp_cfg()) {
|
||||
return csimp_core(env, local_ctx(), e, true, cfg);
|
||||
}
|
||||
inline expr cesimp(environment const & env, expr const & e, csimp_cfg const & cfg = csimp_cfg()) {
|
||||
inline expr cesimp(elab_environment const & env, expr const & e, csimp_cfg const & cfg = csimp_cfg()) {
|
||||
return csimp_core(env, local_ctx(), e, false, cfg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ static bool depends_on_fvar(local_ctx const & lctx, buffer<expr> const & params,
|
|||
Remark: we also skip this transformation for definitions marked as `[inline]` or `[instance]`.
|
||||
*/
|
||||
class eager_lambda_lifting_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
csimp_cfg m_cfg;
|
||||
local_ctx m_lctx;
|
||||
|
|
@ -108,7 +109,7 @@ class eager_lambda_lifting_fn {
|
|||
name_set m_nonterminal_lambdas;
|
||||
unsigned m_next_idx{1};
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -234,12 +235,13 @@ class eager_lambda_lifting_fn {
|
|||
}
|
||||
expr type = cheap_beta_reduce(type_checker(m_st).infer(code));
|
||||
name n = next_name();
|
||||
/* We add the auxiliary declaration `n` as a "meta" axiom to the environment.
|
||||
/* We add the auxiliary declaration `n` as a "meta" axiom to the elab_environment.
|
||||
This is a hack to make sure we can use `csimp` to simplify `code` and
|
||||
other definitions that use `n`.
|
||||
We used a similar hack at `specialize.cpp`. */
|
||||
declaration aux_ax = mk_axiom(n, names(), type, true /* meta */);
|
||||
m_st.env() = env().add(aux_ax, false);
|
||||
m_env = m_env.add(aux_ax, false);
|
||||
m_st.env() = m_env;
|
||||
m_new_decls.push_back(comp_decl(n, code));
|
||||
return mk_app(mk_constant(n), new_params);
|
||||
} catch (exception &) {
|
||||
|
|
@ -398,10 +400,10 @@ class eager_lambda_lifting_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
eager_lambda_lifting_fn(environment const & env, csimp_cfg const & cfg):
|
||||
m_st(env), m_cfg(cfg) {}
|
||||
eager_lambda_lifting_fn(elab_environment const & env, csimp_cfg const & cfg):
|
||||
m_env(env), m_st(env), m_cfg(cfg) {}
|
||||
|
||||
pair<environment, comp_decls> operator()(comp_decl const & cdecl) {
|
||||
pair<elab_environment, comp_decls> operator()(comp_decl const & cdecl) {
|
||||
m_base_name = cdecl.fst();
|
||||
expr r = visit(cdecl.snd(), true);
|
||||
comp_decl new_cdecl(cdecl.fst(), r);
|
||||
|
|
@ -410,7 +412,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
pair<environment, comp_decls> eager_lambda_lifting(environment env, comp_decls const & ds, csimp_cfg const & cfg) {
|
||||
pair<elab_environment, comp_decls> eager_lambda_lifting(elab_environment env, comp_decls const & ds, csimp_cfg const & cfg) {
|
||||
comp_decls r;
|
||||
for (comp_decl const & d : ds) {
|
||||
if (has_inline_attribute(env, d.fst()) || is_instance(env, d.fst())) {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/csimp.h"
|
||||
namespace lean {
|
||||
/** \brief Eager version of lambda lifting. See comment at eager_lambda_lifting.cpp. */
|
||||
pair<environment, comp_decls> eager_lambda_lifting(environment env, comp_decls const & ds, csimp_cfg const & cfg);
|
||||
pair<elab_environment, comp_decls> eager_lambda_lifting(elab_environment env, comp_decls const & ds, csimp_cfg const & cfg);
|
||||
/* Return true iff `fn` is the name of an auxiliary function generated by `eager_lambda_lifting`. */
|
||||
bool is_elambda_lifting_name(name fn);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
class erase_irrelevant_fn {
|
||||
typedef std::tuple<name, expr, expr> let_entry;
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
buffer<expr> m_let_fvars;
|
||||
|
|
@ -24,7 +25,7 @@ class erase_irrelevant_fn {
|
|||
unsigned m_next_idx{1};
|
||||
expr_map<bool> m_irrelevant_cache;
|
||||
|
||||
environment & env() { return m_st.env(); }
|
||||
elab_environment & env() { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -485,14 +486,14 @@ class erase_irrelevant_fn {
|
|||
lean_unreachable();
|
||||
}
|
||||
public:
|
||||
erase_irrelevant_fn(environment const & env, local_ctx const & lctx):
|
||||
m_st(env), m_lctx(lctx), m_x("_x") {}
|
||||
erase_irrelevant_fn(elab_environment const & env, local_ctx const & lctx):
|
||||
m_env(env), m_st(env), m_lctx(lctx), m_x("_x") {}
|
||||
expr operator()(expr const & e) {
|
||||
return mk_let(0, visit(e));
|
||||
}
|
||||
};
|
||||
|
||||
expr erase_irrelevant_core(environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
expr erase_irrelevant_core(elab_environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
return erase_irrelevant_fn(env, lctx)(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
expr erase_irrelevant_core(environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr erase_irrelevant(environment const & env, expr const & e) { return erase_irrelevant_core(env, local_ctx(), e); }
|
||||
expr erase_irrelevant_core(elab_environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr erase_irrelevant(elab_environment const & env, expr const & e) { return erase_irrelevant_core(env, local_ctx(), e); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#include "library/constants.h"
|
||||
#include "library/util.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
extern "C" object* lean_get_export_name_for(object* env, object *n);
|
||||
optional<name> get_export_name_for(environment const & env, name const & n) {
|
||||
optional<name> get_export_name_for(elab_environment const & env, name const & n) {
|
||||
return to_optional<name>(lean_get_export_name_for(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
optional<name> get_export_name_for(environment const & env, name const & n);
|
||||
inline bool has_export_name(environment const & env, name const & n) { return static_cast<bool>(get_export_name_for(env, n)); }
|
||||
optional<name> get_export_name_for(elab_environment const & env, name const & n);
|
||||
inline bool has_export_name(elab_environment const & env, name const & n) { return static_cast<bool>(get_export_name_for(env, n)); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ Authors: Leonardo de Moura
|
|||
namespace lean {
|
||||
extern "C" object* lean_get_extern_attr_data(object* env, object* n);
|
||||
|
||||
optional<extern_attr_data_value> get_extern_attr_data(environment const & env, name const & fn) {
|
||||
optional<extern_attr_data_value> get_extern_attr_data(elab_environment const & env, name const & fn) {
|
||||
return to_optional<extern_attr_data_value>(lean_get_extern_attr_data(env.to_obj_arg(), fn.to_obj_arg()));
|
||||
}
|
||||
|
||||
bool is_extern_constant(environment const & env, name const & c) {
|
||||
bool is_extern_constant(elab_environment const & env, name const & c) {
|
||||
return static_cast<bool>(get_extern_attr_data(env, c));
|
||||
}
|
||||
|
||||
bool is_extern_or_init_constant(environment const & env, name const & c) {
|
||||
bool is_extern_or_init_constant(elab_environment const & env, name const & c) {
|
||||
if (is_extern_constant(env, c)) {
|
||||
return true;
|
||||
} else if (auto info = env.find(c)) {
|
||||
|
|
@ -44,7 +44,7 @@ bool is_extern_or_init_constant(environment const & env, name const & c) {
|
|||
|
||||
extern "C" object * lean_get_extern_const_arity(object* env, object*, object* w);
|
||||
|
||||
optional<unsigned> get_extern_constant_arity(environment const & env, name const & c) {
|
||||
optional<unsigned> get_extern_constant_arity(elab_environment const & env, name const & c) {
|
||||
auto arity = get_io_result<option_ref<nat>>(lean_get_extern_const_arity(env.to_obj_arg(), c.to_obj_arg(), lean_io_mk_world()));
|
||||
if (optional<nat> aux = arity.get()) {
|
||||
return optional<unsigned>(aux->get_small_value());
|
||||
|
|
@ -53,7 +53,7 @@ optional<unsigned> get_extern_constant_arity(environment const & env, name const
|
|||
}
|
||||
}
|
||||
|
||||
bool get_extern_borrowed_info(environment const & env, name const & c, buffer<bool> & borrowed_args, bool & borrowed_res) {
|
||||
bool get_extern_borrowed_info(elab_environment const & env, name const & c, buffer<bool> & borrowed_args, bool & borrowed_res) {
|
||||
if (is_extern_constant(env, c)) {
|
||||
/* Extract borrowed info from type */
|
||||
expr type = env.get(c).get_type();
|
||||
|
|
@ -80,7 +80,7 @@ bool get_extern_borrowed_info(environment const & env, name const & c, buffer<bo
|
|||
return false;
|
||||
}
|
||||
|
||||
optional<expr> get_extern_constant_ll_type(environment const & env, name const & c) {
|
||||
optional<expr> get_extern_constant_ll_type(elab_environment const & env, name const & c) {
|
||||
if (is_extern_or_init_constant(env, c)) {
|
||||
unsigned arity = 0;
|
||||
expr type = env.get(c).get_type();
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ Authors: Leonardo de Moura
|
|||
*/
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
bool is_extern_constant(environment const & env, name const & c);
|
||||
bool is_extern_or_init_constant(environment const & env, name const & c);
|
||||
optional<expr> get_extern_constant_ll_type(environment const & env, name const & c);
|
||||
optional<unsigned> get_extern_constant_arity(environment const & env, name const & c);
|
||||
bool is_extern_constant(elab_environment const & env, name const & c);
|
||||
bool is_extern_or_init_constant(elab_environment const & env, name const & c);
|
||||
optional<expr> get_extern_constant_ll_type(elab_environment const & env, name const & c);
|
||||
optional<unsigned> get_extern_constant_arity(elab_environment const & env, name const & c);
|
||||
typedef object_ref extern_attr_data_value;
|
||||
optional<extern_attr_data_value> get_extern_attr_data(environment const & env, name const & c);
|
||||
optional<extern_attr_data_value> get_extern_attr_data(elab_environment const & env, name const & c);
|
||||
/* Return true if `c` is an extern constant, and store in borrowed_args and
|
||||
borrowed_res which arguments/results are marked as borrowed. */
|
||||
bool get_extern_borrowed_info(environment const & env, name const & c, buffer<bool> & borrowed_args, bool & borrowed_res);
|
||||
bool get_extern_borrowed_info(elab_environment const & env, name const & c, buffer<bool> & borrowed_args, bool & borrowed_res);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ bool is_extract_closed_aux_fn(name const & n) {
|
|||
}
|
||||
|
||||
class extract_closed_fn {
|
||||
environment m_env;
|
||||
elab_environment m_env;
|
||||
comp_decls m_input_decls;
|
||||
name_generator m_ngen;
|
||||
local_ctx m_lctx;
|
||||
|
|
@ -34,7 +34,7 @@ class extract_closed_fn {
|
|||
unsigned m_next_idx{1};
|
||||
expr_map<bool> m_closed;
|
||||
|
||||
environment const & env() const { return m_env; }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
name_generator & ngen() { return m_ngen; }
|
||||
|
||||
name next_name() {
|
||||
|
|
@ -286,11 +286,11 @@ class extract_closed_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
extract_closed_fn(environment const & env, comp_decls const & ds):
|
||||
extract_closed_fn(elab_environment const & env, comp_decls const & ds):
|
||||
m_env(env), m_input_decls(ds) {
|
||||
}
|
||||
|
||||
pair<environment, comp_decls> operator()(comp_decl const & d) {
|
||||
pair<elab_environment, comp_decls> operator()(comp_decl const & d) {
|
||||
if (arity_was_reduced(d)) {
|
||||
/* Do nothing since `d` will be inlined. */
|
||||
return mk_pair(env(), comp_decls(d));
|
||||
|
|
@ -308,11 +308,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
pair<environment, comp_decls> extract_closed_core(environment const & env, comp_decls const & input_ds, comp_decl const & d) {
|
||||
pair<elab_environment, comp_decls> extract_closed_core(elab_environment const & env, comp_decls const & input_ds, comp_decl const & d) {
|
||||
return extract_closed_fn(env, input_ds)(d);
|
||||
}
|
||||
|
||||
pair<environment, comp_decls> extract_closed(environment env, comp_decls const & ds) {
|
||||
pair<elab_environment, comp_decls> extract_closed(elab_environment env, comp_decls const & ds) {
|
||||
comp_decls r;
|
||||
for (comp_decl const & d : ds) {
|
||||
comp_decls new_ds;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/util.h"
|
||||
namespace lean {
|
||||
bool is_extract_closed_aux_fn(name const & n);
|
||||
pair<environment, comp_decls> extract_closed(environment env, comp_decls const & ds);
|
||||
pair<elab_environment, comp_decls> extract_closed(elab_environment env, comp_decls const & ds);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace lean {
|
|||
|
||||
/* Find join-points */
|
||||
class find_jp_fn {
|
||||
environment const & m_env;
|
||||
elab_environment const & m_env;
|
||||
local_ctx m_lctx;
|
||||
name_generator m_ngen;
|
||||
name_map<unsigned> m_candidates;
|
||||
|
|
@ -130,7 +130,7 @@ class find_jp_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
find_jp_fn(environment const & env):
|
||||
find_jp_fn(elab_environment const & env):
|
||||
m_env(env) {}
|
||||
|
||||
expr operator()(expr const & e) {
|
||||
|
|
@ -138,7 +138,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
expr find_jp(environment const & env, expr const & e) {
|
||||
expr find_jp(elab_environment const & env, expr const & e) {
|
||||
return find_jp_fn(env)(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
expr find_jp(environment const & env, expr const & e);
|
||||
expr find_jp(elab_environment const & env, expr const & e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
extern "C" object* lean_get_implemented_by(object*, object*);
|
||||
|
||||
optional<name> get_implemented_by_attribute(environment const & env, name const & n) {
|
||||
optional<name> get_implemented_by_attribute(elab_environment const & env, name const & n) {
|
||||
return to_optional<name>(lean_get_implemented_by(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
optional<name> get_implemented_by_attribute(environment const & env, name const & n);
|
||||
inline bool has_implemented_by_attribute(environment const & env, name const & n) {
|
||||
optional<name> get_implemented_by_attribute(elab_environment const & env, name const & n);
|
||||
inline bool has_implemented_by_attribute(elab_environment const & env, name const & n) {
|
||||
return static_cast<bool>(get_implemented_by_attribute(env, n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
*/
|
||||
#include "runtime/object_ref.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
extern "C" object* lean_get_init_fn_name_for(object* env, object* fn);
|
||||
|
||||
optional<name> get_init_fn_name_for(environment const & env, name const & n) {
|
||||
optional<name> get_init_fn_name_for(elab_environment const & env, name const & n) {
|
||||
return to_optional<name>(lean_get_init_fn_name_for(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
optional<name> get_init_fn_name_for(environment const & env, name const & n);
|
||||
inline bool has_init_attribute(environment const & env, name const & n) {
|
||||
optional<name> get_init_fn_name_for(elab_environment const & env, name const & n);
|
||||
inline bool has_init_attribute(elab_environment const & env, name const & n) {
|
||||
return static_cast<bool>(get_init_fn_name_for(env, n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ std::string decl_to_string(decl const & d) {
|
|||
string_ref r(lean_ir_decl_to_string(d.to_obj_arg()));
|
||||
return r.to_std_string();
|
||||
}
|
||||
environment add_decl(environment const & env, decl const & d) {
|
||||
return environment(lean_ir_add_decl(env.to_obj_arg(), d.to_obj_arg()));
|
||||
elab_environment add_decl(elab_environment const & env, decl const & d) {
|
||||
return elab_environment(lean_ir_add_decl(env.to_obj_arg(), d.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -133,12 +133,13 @@ static ir::type to_ir_type(expr const & e) {
|
|||
}
|
||||
|
||||
class to_ir_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
name m_x{"x"};
|
||||
unsigned m_next_idx{1};
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -493,7 +494,7 @@ class to_ir_fn {
|
|||
return ir::mk_decl(fn, xs, type, b);
|
||||
}
|
||||
public:
|
||||
to_ir_fn(environment const & env):m_st(env) {}
|
||||
to_ir_fn(elab_environment const & env):m_env(env), m_st(env) {}
|
||||
|
||||
ir::decl operator()(comp_decl const & d) { return to_ir_decl(d); }
|
||||
|
||||
|
|
@ -520,7 +521,7 @@ public:
|
|||
};
|
||||
|
||||
namespace ir {
|
||||
decl to_ir_decl(environment const & env, comp_decl const & d) {
|
||||
decl to_ir_decl(elab_environment const & env, comp_decl const & d) {
|
||||
return to_ir_fn(env)(d);
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +529,7 @@ decl to_ir_decl(environment const & env, comp_decl const & d) {
|
|||
@[export lean.ir.compile_core]
|
||||
def compile (env : Environment) (opts : Options) (decls : Array Decl) : Log × (Except String Environment) :=
|
||||
*/
|
||||
environment compile(environment const & env, options const & opts, comp_decls const & decls) {
|
||||
elab_environment compile(elab_environment const & env, options const & opts, comp_decls const & decls) {
|
||||
buffer<decl> ir_decls;
|
||||
for (comp_decl const & decl : decls) {
|
||||
lean_trace(name({"compiler", "lambda_pure"}),
|
||||
|
|
@ -549,7 +550,7 @@ environment compile(environment const & env, options const & opts, comp_decls co
|
|||
dec_ref(r);
|
||||
throw exception(error.data());
|
||||
} else {
|
||||
environment new_env(cnstr_get(v, 0), true);
|
||||
elab_environment new_env(cnstr_get(v, 0), true);
|
||||
dec_ref(r);
|
||||
return new_env;
|
||||
}
|
||||
|
|
@ -560,28 +561,28 @@ environment compile(environment const & env, options const & opts, comp_decls co
|
|||
def addBoxedVersion (env : Environment) (decl : Decl) : Except String Environment :=
|
||||
*/
|
||||
extern "C" object * lean_ir_add_boxed_version(object * env, object * decl);
|
||||
environment add_boxed_version(environment const & env, decl const & d) {
|
||||
elab_environment add_boxed_version(elab_environment const & env, decl const & d) {
|
||||
object * v = lean_ir_add_boxed_version(env.to_obj_arg(), d.to_obj_arg());
|
||||
if (cnstr_tag(v) == 0) {
|
||||
string_ref error(cnstr_get(v, 0), true);
|
||||
dec_ref(v);
|
||||
throw exception(error.data());
|
||||
} else {
|
||||
environment new_env(cnstr_get(v, 0), true);
|
||||
elab_environment new_env(cnstr_get(v, 0), true);
|
||||
dec_ref(v);
|
||||
return new_env;
|
||||
}
|
||||
}
|
||||
|
||||
environment add_extern(environment const & env, name const & fn) {
|
||||
elab_environment add_extern(elab_environment const & env, name const & fn) {
|
||||
decl d = to_ir_fn(env)(fn);
|
||||
environment new_env = ir::add_decl(env, d);
|
||||
elab_environment new_env = ir::add_decl(env, d);
|
||||
return add_boxed_version(new_env, d);
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object* lean_add_extern(object * env, object * fn) {
|
||||
try {
|
||||
environment new_env = add_extern(environment(env), name(fn));
|
||||
elab_environment new_env = add_extern(elab_environment(env), name(fn));
|
||||
return mk_except_ok(new_env);
|
||||
} catch (exception & ex) {
|
||||
// throw; // We use to uncomment this line when debugging weird bugs in the Lean/C++ interface.
|
||||
|
|
@ -591,7 +592,7 @@ extern "C" LEAN_EXPORT object* lean_add_extern(object * env, object * fn) {
|
|||
|
||||
extern "C" object * lean_ir_emit_c(object * env, object * mod_name);
|
||||
|
||||
string_ref emit_c(environment const & env, name const & mod_name) {
|
||||
string_ref emit_c(elab_environment const & env, name const & mod_name) {
|
||||
object * r = lean_ir_emit_c(env.to_obj_arg(), mod_name.to_obj_arg());
|
||||
string_ref s(cnstr_get(r, 0), true);
|
||||
if (cnstr_tag(r) == 0) {
|
||||
|
|
@ -639,7 +640,7 @@ object_ref to_object_ref(cnstr_info const & info) {
|
|||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_ir_get_ctor_layout(object * env0, object * ctor_name0) {
|
||||
environment const & env = TO_REF(environment, env0);
|
||||
elab_environment const & env = TO_REF(elab_environment, env0);
|
||||
name const & ctor_name = TO_REF(name, ctor_name0);
|
||||
type_checker::state st(env);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/util.h"
|
||||
namespace lean {
|
||||
namespace ir {
|
||||
|
|
@ -35,10 +35,10 @@ typedef object_ref decl;
|
|||
typedef object_ref decl;
|
||||
std::string decl_to_string(decl const & d);
|
||||
void test(decl const & d);
|
||||
environment compile(environment const & env, options const & opts, comp_decls const & decls);
|
||||
environment add_extern(environment const & env, name const & fn);
|
||||
LEAN_EXPORT string_ref emit_c(environment const & env, name const & mod_name);
|
||||
void emit_llvm(environment const & env, name const & mod_name, std::string const &filepath);
|
||||
elab_environment compile(elab_environment const & env, options const & opts, comp_decls const & decls);
|
||||
elab_environment add_extern(elab_environment const & env, name const & fn);
|
||||
LEAN_EXPORT string_ref emit_c(elab_environment const & env, name const & mod_name);
|
||||
void emit_llvm(elab_environment const & env, name const & mod_name, std::string const &filepath);
|
||||
}
|
||||
void initialize_ir();
|
||||
void finalize_ir();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Implementation
|
|||
The interpreter mainly consists of a homogeneous stack of `value`s, which are either unboxed values or pointers to boxed
|
||||
objects. The IR type system tells us which union member is active at any time. IR variables are mapped to stack
|
||||
slots by adding the current base pointer to the variable index. Further stacks are used for storing join points and call
|
||||
stack metadata. The interpreted IR is taken directly from the environment. Whenever possible, we try to switch to native
|
||||
stack metadata. The interpreted IR is taken directly from the elab_environment. Whenever possible, we try to switch to native
|
||||
code by checking for the mangled symbol via dlsym/GetProcAddress, which is also how we can call external functions
|
||||
(which only works if the file declaring them has already been compiled). We always call the "boxed" versions of native
|
||||
functions, which have a (relatively) homogeneous ABI that we can use without runtime code generation; see also
|
||||
|
|
@ -182,7 +182,7 @@ type decl_type(decl const & b) { return cnstr_get_type(b, 2); }
|
|||
fn_body const & decl_fun_body(decl const & b) { lean_assert(decl_tag(b) == decl_kind::Fun); return cnstr_get_ref_t<fn_body>(b, 3); }
|
||||
|
||||
extern "C" object * lean_ir_find_env_decl(object * env, object * n);
|
||||
option_ref<decl> find_ir_decl(environment const & env, name const & n) {
|
||||
option_ref<decl> find_ir_decl(elab_environment const & env, name const & n) {
|
||||
return option_ref<decl>(lean_ir_find_env_decl(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
|
||||
|
|
@ -213,12 +213,12 @@ static bool type_is_scalar(type t) {
|
|||
}
|
||||
|
||||
extern "C" object* lean_get_regular_init_fn_name_for(object* env, object* fn);
|
||||
optional<name> get_regular_init_fn_name_for(environment const & env, name const & n) {
|
||||
optional<name> get_regular_init_fn_name_for(elab_environment const & env, name const & n) {
|
||||
return to_optional<name>(lean_get_regular_init_fn_name_for(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
|
||||
extern "C" object* lean_get_builtin_init_fn_name_for(object* env, object* fn);
|
||||
optional<name> get_builtin_init_fn_name_for(environment const & env, name const & n) {
|
||||
optional<name> get_builtin_init_fn_name_for(elab_environment const & env, name const & n) {
|
||||
return to_optional<name>(lean_get_builtin_init_fn_name_for(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
|
||||
|
|
@ -355,7 +355,7 @@ class interpreter {
|
|||
frame(name const & mFn, size_t mArgBp, size_t mJpBp) : m_fn(mFn), m_arg_bp(mArgBp), m_jp_bp(mJpBp) {}
|
||||
};
|
||||
std::vector<frame> m_call_stack;
|
||||
environment const & m_env;
|
||||
elab_environment const & m_env;
|
||||
options const & m_opts;
|
||||
// if `false`, use IR code where possible
|
||||
bool m_prefer_native;
|
||||
|
|
@ -393,7 +393,7 @@ class interpreter {
|
|||
|
||||
public:
|
||||
template<class T>
|
||||
static inline T with_interpreter(environment const & env, options const & opts, name const & fn, std::function<T(interpreter &)> const & f) {
|
||||
static inline T with_interpreter(elab_environment const & env, options const & opts, name const & fn, std::function<T(interpreter &)> const & f) {
|
||||
if (g_interpreter && is_eqp(g_interpreter->m_env, env) && is_eqp(g_interpreter->m_opts, opts)) {
|
||||
return f(*g_interpreter);
|
||||
} else {
|
||||
|
|
@ -808,7 +808,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
/** \brief Retrieve Lean declaration from environment. */
|
||||
/** \brief Retrieve Lean declaration from elab_environment. */
|
||||
decl get_decl(name const & fn) {
|
||||
option_ref<decl> d = find_ir_decl(m_env, fn);
|
||||
if (!d) {
|
||||
|
|
@ -931,7 +931,7 @@ private:
|
|||
|
||||
// static closure stub
|
||||
static object * stub_m_aux(object ** args) {
|
||||
environment env(args[0]);
|
||||
elab_environment env(args[0]);
|
||||
options opts(args[1]);
|
||||
return with_interpreter<object *>(env, opts, decl_fun_id(TO_REF(decl, args[2])), [&](interpreter & interp) {
|
||||
return interp.stub_m(args);
|
||||
|
|
@ -979,7 +979,7 @@ private:
|
|||
}
|
||||
}
|
||||
public:
|
||||
explicit interpreter(environment const & env, options const & opts) : m_env(env), m_opts(opts) {
|
||||
explicit interpreter(elab_environment const & env, options const & opts) : m_env(env), m_opts(opts) {
|
||||
m_prefer_native = opts.get_bool(*g_interpreter_prefer_native, LEAN_DEFAULT_INTERPRETER_PREFER_NATIVE);
|
||||
}
|
||||
|
||||
|
|
@ -1090,24 +1090,34 @@ public:
|
|||
|
||||
extern "C" object * lean_decl_get_sorry_dep(object * env, object * n);
|
||||
|
||||
optional<name> get_sorry_dep(environment const & env, name const & n) {
|
||||
optional<name> get_sorry_dep(elab_environment const & env, name const & n) {
|
||||
return option_ref<name>(lean_decl_get_sorry_dep(env.to_obj_arg(), n.to_obj_arg())).get();
|
||||
}
|
||||
|
||||
object * run_boxed(environment const & env, options const & opts, name const & fn, unsigned n, object **args) {
|
||||
object * run_boxed(elab_environment const & env, options const & opts, name const & fn, unsigned n, object **args) {
|
||||
if (optional<name> decl_with_sorry = get_sorry_dep(env, fn)) {
|
||||
throw exception(sstream() << "cannot evaluate code because '" << *decl_with_sorry
|
||||
<< "' uses 'sorry' and/or contains errors");
|
||||
}
|
||||
return interpreter::with_interpreter<object *>(env, opts, fn, [&](interpreter & interp) { return interp.call_boxed(fn, n, args); });
|
||||
}
|
||||
uint32 run_main(environment const & env, options const & opts, int argv, char * argc[]) {
|
||||
|
||||
extern "C" obj_res lean_elab_environment_of_kernel_env(obj_arg);
|
||||
elab_environment elab_environment_of_kernel_env(environment const & env) {
|
||||
return elab_environment(lean_elab_environment_of_kernel_env(env.to_obj_arg()));
|
||||
}
|
||||
|
||||
object * run_boxed_kernel(environment const & env, options const & opts, name const & fn, unsigned n, object **args) {
|
||||
return run_boxed(elab_environment_of_kernel_env(env), opts, fn, n, args);
|
||||
}
|
||||
|
||||
uint32 run_main(elab_environment const & env, options const & opts, int argv, char * argc[]) {
|
||||
return interpreter::with_interpreter<uint32>(env, opts, "main", [&](interpreter & interp) { return interp.run_main(argv, argc); });
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_eval_const(object * env, object * opts, object * c) {
|
||||
try {
|
||||
return mk_cnstr(1, run_boxed(TO_REF(environment, env), TO_REF(options, opts), TO_REF(name, c), 0, 0)).steal();
|
||||
return mk_cnstr(1, run_boxed(TO_REF(elab_environment, env), TO_REF(options, opts), TO_REF(name, c), 0, 0)).steal();
|
||||
} catch (exception & ex) {
|
||||
return mk_cnstr(0, string_ref(ex.what())).steal();
|
||||
}
|
||||
|
|
@ -1134,7 +1144,7 @@ extern "C" LEAN_EXPORT object * lean_run_mod_init(object * mod, object *) {
|
|||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_run_init(object * env, object * opts, object * decl, object * init_decl, object *) {
|
||||
return interpreter::with_interpreter<object *>(TO_REF(environment, env), TO_REF(options, opts), TO_REF(name, decl), [&](interpreter & interp) {
|
||||
return interpreter::with_interpreter<object *>(TO_REF(elab_environment, env), TO_REF(options, opts), TO_REF(name, decl), [&](interpreter & interp) {
|
||||
return interp.run_init(TO_REF(name, decl), TO_REF(name, init_decl));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Sebastian Ullrich
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "runtime/object.h"
|
||||
|
||||
namespace lean {
|
||||
namespace ir {
|
||||
/** \brief Run `n` using the "boxed" ABI, i.e. with all-owned parameters. */
|
||||
object * run_boxed(environment const & env, options const & opts, name const & fn, unsigned n, object **args);
|
||||
LEAN_EXPORT uint32 run_main(environment const & env, options const & opts, int argv, char * argc[]);
|
||||
object * run_boxed(elab_environment const & env, options const & opts, name const & fn, unsigned n, object **args);
|
||||
LEAN_EXPORT uint32 run_main(elab_environment const & env, options const & opts, int argv, char * argc[]);
|
||||
}
|
||||
void initialize_ir_interpreter();
|
||||
void finalize_ir_interpreter();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ bool is_lambda_lifting_name(name fn) {
|
|||
}
|
||||
|
||||
class lambda_lifting_fn {
|
||||
environment m_env;
|
||||
elab_environment m_env;
|
||||
name_generator m_ngen;
|
||||
local_ctx m_lctx;
|
||||
buffer<comp_decl> m_new_decls;
|
||||
|
|
@ -39,7 +39,7 @@ class lambda_lifting_fn {
|
|||
|
||||
typedef std::unordered_set<name, name_hash_fn> name_set;
|
||||
|
||||
environment const & env() { return m_env; }
|
||||
elab_environment const & env() { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_ngen; }
|
||||
|
||||
|
|
@ -207,10 +207,10 @@ class lambda_lifting_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
lambda_lifting_fn(environment const & env):
|
||||
lambda_lifting_fn(elab_environment const & env):
|
||||
m_env(env) {}
|
||||
|
||||
pair<environment, comp_decls> operator()(comp_decl const & cdecl) {
|
||||
pair<elab_environment, comp_decls> operator()(comp_decl const & cdecl) {
|
||||
m_base_name = cdecl.fst();
|
||||
expr r = visit(cdecl.snd(), true);
|
||||
comp_decl new_cdecl(cdecl.fst(), r);
|
||||
|
|
@ -219,11 +219,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
pair<environment, comp_decls> lambda_lifting(environment const & env, comp_decl const & d) {
|
||||
pair<elab_environment, comp_decls> lambda_lifting(elab_environment const & env, comp_decl const & d) {
|
||||
return lambda_lifting_fn(env)(d);
|
||||
}
|
||||
|
||||
pair<environment, comp_decls> lambda_lifting(environment env, comp_decls const & ds) {
|
||||
pair<elab_environment, comp_decls> lambda_lifting(elab_environment env, comp_decls const & ds) {
|
||||
comp_decls r;
|
||||
for (comp_decl const & d : ds) {
|
||||
comp_decls new_ds;
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/util.h"
|
||||
namespace lean {
|
||||
/** \brief Lift lambda expressions in `ds`. The result also contains new auxiliary declarations that have been generated. */
|
||||
pair<environment, comp_decls> lambda_lifting(environment env, comp_decls const & ds);
|
||||
pair<elab_environment, comp_decls> lambda_lifting(elab_environment env, comp_decls const & ds);
|
||||
/* Return true iff `fn` is the name of an auxiliary function generated by `lambda_lifting`. */
|
||||
bool is_lambda_lifting_name(name fn);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ bool is_do_notation_joinpoint(name const & n) {
|
|||
|
||||
class to_lcnf_fn {
|
||||
typedef rb_expr_map<expr> cache;
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
cache m_cache;
|
||||
|
|
@ -44,10 +45,10 @@ class to_lcnf_fn {
|
|||
name m_x;
|
||||
unsigned m_next_idx{1};
|
||||
public:
|
||||
to_lcnf_fn(environment const & env, local_ctx const & lctx):
|
||||
m_st(env), m_lctx(lctx), m_x("_x") {}
|
||||
to_lcnf_fn(elab_environment const & env, local_ctx const & lctx):
|
||||
m_env(env), m_st(env), m_lctx(lctx), m_x("_x") {}
|
||||
|
||||
environment & env() { return m_st.env(); }
|
||||
elab_environment & env() { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -637,7 +638,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
expr to_lcnf_core(environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
expr to_lcnf_core(elab_environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
expr new_e = unfold_macro_defs(env, e);
|
||||
return to_lcnf_fn(env, lctx)(new_e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
expr to_lcnf_core(environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr to_lcnf(environment const & env, expr const & e) { return to_lcnf_core(env, local_ctx(), e); }
|
||||
expr to_lcnf_core(elab_environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr to_lcnf(elab_environment const & env, expr const & e) { return to_lcnf_core(env, local_ctx(), e); }
|
||||
void initialize_lcnf();
|
||||
void finalize_lcnf();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@ static expr * g_bot = nullptr;
|
|||
|
||||
/* Infer type of expressions in ENF or LLNF. */
|
||||
class ll_infer_type_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
buffer<name> const * m_new_decl_names{nullptr};
|
||||
buffer<expr> const * m_new_decl_types{nullptr};
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
bool may_use_bot() const { return m_new_decl_types != nullptr; }
|
||||
|
|
@ -227,14 +228,14 @@ class ll_infer_type_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
ll_infer_type_fn(environment const & env, buffer<name> const & ns, buffer<expr> const & ts):
|
||||
m_st(env), m_new_decl_names(&ns), m_new_decl_types(&ts) {}
|
||||
ll_infer_type_fn(environment const & env, local_ctx const & lctx):
|
||||
m_st(env), m_lctx(lctx) {}
|
||||
ll_infer_type_fn(elab_environment const & env, buffer<name> const & ns, buffer<expr> const & ts):
|
||||
m_env(env), m_st(env), m_new_decl_names(&ns), m_new_decl_types(&ts) {}
|
||||
ll_infer_type_fn(elab_environment const & env, local_ctx const & lctx):
|
||||
m_env(env), m_st(env), m_lctx(lctx) {}
|
||||
expr operator()(expr const & e) { return infer(e); }
|
||||
};
|
||||
|
||||
void ll_infer_type(environment const & env, comp_decls const & ds, buffer<expr> & ts) {
|
||||
void ll_infer_type(elab_environment const & env, comp_decls const & ds, buffer<expr> & ts) {
|
||||
buffer<name> ns;
|
||||
ts.clear();
|
||||
/* Initialize `ts` */
|
||||
|
|
@ -272,7 +273,7 @@ void ll_infer_type(environment const & env, comp_decls const & ds, buffer<expr>
|
|||
lean_assert(ts.size() == length(ds));
|
||||
}
|
||||
|
||||
expr ll_infer_type(environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
expr ll_infer_type(elab_environment const & env, local_ctx const & lctx, expr const & e) {
|
||||
return ll_infer_type_fn(env, lctx)(e);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
expr ll_infer_type(environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr ll_infer_type(environment const & env, expr const & e) { return ll_infer_type(env, local_ctx(), e); }
|
||||
void ll_infer_type(environment const & env, comp_decls const & ds, buffer<expr> & ts);
|
||||
expr ll_infer_type(elab_environment const & env, local_ctx const & lctx, expr const & e);
|
||||
inline expr ll_infer_type(elab_environment const & env, expr const & e) { return ll_infer_type(env, local_ctx(), e); }
|
||||
void ll_infer_type(elab_environment const & env, comp_decls const & ds, buffer<expr> & ts);
|
||||
void initialize_ll_infer_type();
|
||||
void finalize_ll_infer_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ cnstr_info::cnstr_info(unsigned cidx, list<field_info> const & finfo):
|
|||
}
|
||||
}
|
||||
|
||||
unsigned get_llnf_arity(environment const & env, name const & n) {
|
||||
unsigned get_llnf_arity(elab_environment const & env, name const & n) {
|
||||
/* First, try to infer arity from `_cstage2` auxiliary definition. */
|
||||
name c = mk_cstage2_name(n);
|
||||
optional<constant_info> info = env.find(c);
|
||||
|
|
@ -334,6 +334,7 @@ class to_lambda_pure_fn {
|
|||
typedef name_hash_set name_set;
|
||||
typedef name_hash_map<cnstr_info> cnstr_info_cache;
|
||||
typedef name_hash_map<optional<unsigned>> enum_cache;
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
buffer<expr> m_fvars;
|
||||
|
|
@ -343,7 +344,7 @@ class to_lambda_pure_fn {
|
|||
unsigned m_next_jp_idx{1};
|
||||
cnstr_info_cache m_cnstr_info_cache;
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -803,8 +804,8 @@ class to_lambda_pure_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
to_lambda_pure_fn(environment const & env):
|
||||
m_st(env), m_x("_x"), m_j("j") {
|
||||
to_lambda_pure_fn(elab_environment const & env):
|
||||
m_env(env), m_st(env), m_x("_x"), m_j("j") {
|
||||
}
|
||||
|
||||
expr operator()(expr e) {
|
||||
|
|
@ -815,7 +816,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
expr get_constant_ll_type(environment const & env, name const & c) {
|
||||
expr get_constant_ll_type(elab_environment const & env, name const & c) {
|
||||
if (optional<expr> type = get_extern_constant_ll_type(env, c)) {
|
||||
return *type;
|
||||
} else {
|
||||
|
|
@ -823,7 +824,7 @@ expr get_constant_ll_type(environment const & env, name const & c) {
|
|||
}
|
||||
}
|
||||
|
||||
environment compile_ir(environment const & env, options const & opts, comp_decls const & ds) {
|
||||
elab_environment compile_ir(elab_environment const & env, options const & opts, comp_decls const & ds) {
|
||||
buffer<comp_decl> new_ds;
|
||||
for (comp_decl const & d : ds) {
|
||||
expr new_v = to_lambda_pure_fn(env)(d.snd());
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/util.h"
|
||||
|
||||
namespace lean {
|
||||
environment compile_ir(environment const & env, options const & opts, comp_decls const & ds);
|
||||
elab_environment compile_ir(elab_environment const & env, options const & opts, comp_decls const & ds);
|
||||
|
||||
bool is_llnf_apply(expr const & e);
|
||||
bool is_llnf_closure(expr const & e);
|
||||
|
|
@ -49,8 +49,8 @@ inline bool is_llnf_uset(expr const & e) { unsigned d; return is_llnf_uset(e, d)
|
|||
inline bool is_llnf_box(expr const & e) { unsigned n; return is_llnf_box(e, n); }
|
||||
inline bool is_llnf_unbox(expr const & e) { unsigned n; return is_llnf_unbox(e, n); }
|
||||
|
||||
expr get_constant_ll_type(environment const & env, name const & c);
|
||||
unsigned get_llnf_arity(environment const & env, name const & c);
|
||||
expr get_constant_ll_type(elab_environment const & env, name const & c);
|
||||
unsigned get_llnf_arity(elab_environment const & env, name const & c);
|
||||
|
||||
struct field_info {
|
||||
/* Remark: the position of a scalar value in
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ bool arity_was_reduced(comp_decl const & cdecl) {
|
|||
return is_reduce_arity_aux_fn(n) && n.get_prefix() == cdecl.fst();
|
||||
}
|
||||
|
||||
comp_decls reduce_arity(environment const & env, comp_decl const & cdecl) {
|
||||
comp_decls reduce_arity(elab_environment const & env, comp_decl const & cdecl) {
|
||||
if (has_export_name(env, cdecl.fst()) || cdecl.fst() == "main") {
|
||||
/* We do not modify the arity of entry points (i.e., functions with attribute [export]) */
|
||||
return comp_decls(cdecl);
|
||||
|
|
@ -92,7 +92,7 @@ comp_decls reduce_arity(environment const & env, comp_decl const & cdecl) {
|
|||
return comp_decls(red_decl, comp_decls(new_decl));
|
||||
}
|
||||
|
||||
comp_decls reduce_arity(environment const & env, comp_decls const & ds) {
|
||||
comp_decls reduce_arity(elab_environment const & env, comp_decls const & ds) {
|
||||
comp_decls r;
|
||||
for (comp_decl const & d : ds) {
|
||||
r = append(r, reduce_arity(env, d));
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Author: Leonardo de Moura
|
|||
#pragma once
|
||||
#include "library/compiler/util.h"
|
||||
namespace lean {
|
||||
comp_decls reduce_arity(environment const & env, comp_decls const & cdecls);
|
||||
comp_decls reduce_arity(elab_environment const & env, comp_decls const & cdecls);
|
||||
/* Return true if the `cdecl` is of the form `f := fun xs, f._rarg ...`.
|
||||
That is, `f`s arity "was reduced" and an auxiliary declaration `f._rarg` was created to replace it. */
|
||||
bool arity_was_reduced(comp_decl const & cdecl);
|
||||
|
|
|
|||
|
|
@ -11,13 +11,14 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
/* Make sure every argument of applications and projections is a free variable (or neutral element). */
|
||||
class simp_app_args_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
buffer<expr> m_fvars;
|
||||
name m_x;
|
||||
unsigned m_next_idx{1};
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
name next_name() {
|
||||
|
|
@ -125,14 +126,14 @@ class simp_app_args_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
simp_app_args_fn(environment const & env):m_st(env), m_x("_x") {}
|
||||
simp_app_args_fn(elab_environment const & env):m_env(env), m_st(env), m_x("_x") {}
|
||||
|
||||
expr operator()(expr const & e) {
|
||||
return mk_let(0, visit(e));
|
||||
}
|
||||
};
|
||||
|
||||
expr simp_app_args(environment const & env, expr const & e) {
|
||||
expr simp_app_args(elab_environment const & env, expr const & e) {
|
||||
return simp_app_args_fn(env)(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
namespace lean {
|
||||
expr simp_app_args(environment const & env, expr const & e);
|
||||
expr simp_app_args(elab_environment const & env, expr const & e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ namespace lean {
|
|||
extern "C" uint8 lean_has_specialize_attribute(object* env, object* n);
|
||||
extern "C" uint8 lean_has_nospecialize_attribute(object* env, object* n);
|
||||
|
||||
bool has_specialize_attribute(environment const & env, name const & n) {
|
||||
bool has_specialize_attribute(elab_environment const & env, name const & n) {
|
||||
return lean_has_specialize_attribute(env.to_obj_arg(), n.to_obj_arg());
|
||||
}
|
||||
|
||||
bool has_nospecialize_attribute(environment const & env, name const & n) {
|
||||
bool has_nospecialize_attribute(elab_environment const & env, name const & n) {
|
||||
return lean_has_nospecialize_attribute(env.to_obj_arg(), n.to_obj_arg());
|
||||
}
|
||||
|
||||
|
|
@ -103,11 +103,11 @@ public:
|
|||
extern "C" object* lean_add_specialization_info(object* env, object* fn, object* info);
|
||||
extern "C" object* lean_get_specialization_info(object* env, object* fn);
|
||||
|
||||
static environment save_specialization_info(environment const & env, name const & fn, spec_info const & si) {
|
||||
return environment(lean_add_specialization_info(env.to_obj_arg(), fn.to_obj_arg(), si.to_obj_arg()));
|
||||
static elab_environment save_specialization_info(elab_environment const & env, name const & fn, spec_info const & si) {
|
||||
return elab_environment(lean_add_specialization_info(env.to_obj_arg(), fn.to_obj_arg(), si.to_obj_arg()));
|
||||
}
|
||||
|
||||
static optional<spec_info> get_specialization_info(environment const & env, name const & fn) {
|
||||
static optional<spec_info> get_specialization_info(elab_environment const & env, name const & fn) {
|
||||
return to_optional<spec_info>(lean_get_specialization_info(env.to_obj_arg(), fn.to_obj_arg()));
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ typedef buffer<pair<name, buffer<spec_arg_kind>>> spec_info_buffer;
|
|||
|
||||
Remark: we only create free variables for the header of each declaration. Then, we assume an argument of a
|
||||
recursive call is fixed iff it is a free variable (see `update_spec_info`). */
|
||||
static void update_info_buffer(environment const & env, expr e, name_set const & S, spec_info_buffer & info_buffer) {
|
||||
static void update_info_buffer(elab_environment const & env, expr e, name_set const & S, spec_info_buffer & info_buffer) {
|
||||
while (true) {
|
||||
switch (e.kind()) {
|
||||
case expr_kind::Lambda:
|
||||
|
|
@ -162,7 +162,7 @@ static void update_info_buffer(environment const & env, expr e, name_set const &
|
|||
}
|
||||
}
|
||||
|
||||
bool is_class(environment const & env, expr type) {
|
||||
bool is_class(elab_environment const & env, expr type) {
|
||||
// This is a temporary hack. We do not unfold `type` here, but we should. We will fix it when we reimplement the compiler in Lean.
|
||||
while (is_pi(type)) {
|
||||
type = binding_body(type);
|
||||
|
|
@ -171,7 +171,7 @@ bool is_class(environment const & env, expr type) {
|
|||
return is_constant(type) && is_class(env, const_name(type));
|
||||
}
|
||||
|
||||
environment update_spec_info(environment const & env, comp_decls const & ds) {
|
||||
elab_environment update_spec_info(elab_environment const & env, comp_decls const & ds) {
|
||||
name_set S;
|
||||
spec_info_buffer d_infos;
|
||||
name_generator ngen;
|
||||
|
|
@ -237,7 +237,7 @@ environment update_spec_info(environment const & env, comp_decls const & ds) {
|
|||
update_info_buffer(env, code, S, d_infos);
|
||||
}
|
||||
/* Update extension */
|
||||
environment new_env = env;
|
||||
elab_environment new_env = env;
|
||||
names mutual_decls = map2<name>(ds, [&](comp_decl const & d) { return d.fst(); });
|
||||
for (pair<name, buffer<spec_arg_kind>> const & info : d_infos) {
|
||||
name const & n = info.first;
|
||||
|
|
@ -255,15 +255,16 @@ environment update_spec_info(environment const & env, comp_decls const & ds) {
|
|||
extern "C" object* lean_cache_specialization(object* env, object* e, object* fn);
|
||||
extern "C" object* lean_get_cached_specialization(object* env, object* e);
|
||||
|
||||
static environment cache_specialization(environment const & env, expr const & k, name const & fn) {
|
||||
return environment(lean_cache_specialization(env.to_obj_arg(), k.to_obj_arg(), fn.to_obj_arg()));
|
||||
static elab_environment cache_specialization(elab_environment const & env, expr const & k, name const & fn) {
|
||||
return elab_environment(lean_cache_specialization(env.to_obj_arg(), k.to_obj_arg(), fn.to_obj_arg()));
|
||||
}
|
||||
|
||||
static optional<name> get_cached_specialization(environment const & env, expr const & e) {
|
||||
static optional<name> get_cached_specialization(elab_environment const & env, expr const & e) {
|
||||
return to_optional<name>(lean_get_cached_specialization(env.to_obj_arg(), e.to_obj_arg()));
|
||||
}
|
||||
|
||||
class specialize_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
csimp_cfg m_cfg;
|
||||
local_ctx m_lctx;
|
||||
|
|
@ -274,7 +275,7 @@ class specialize_fn {
|
|||
unsigned m_next_idx{1};
|
||||
name_set m_to_respecialize;
|
||||
|
||||
environment const & env() { return m_st.env(); }
|
||||
elab_environment const & env() { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -969,7 +970,8 @@ class specialize_fn {
|
|||
try {
|
||||
expr type = cheap_beta_reduce(type_checker(m_st).infer(code));
|
||||
declaration aux_ax = mk_axiom(n, names(), type, true /* meta */);
|
||||
m_st.env() = env().add(aux_ax, false);
|
||||
m_env = m_env.add(aux_ax, false);
|
||||
m_st.env() = m_env;
|
||||
} catch (exception &) {
|
||||
/* We may fail to infer the type of code, since it may be recursive
|
||||
This is a workaround. When we re-implement the compiler in Lean,
|
||||
|
|
@ -1149,7 +1151,7 @@ class specialize_fn {
|
|||
for (comp_decl const & new_decl : new_decls) {
|
||||
m_to_respecialize.insert(new_decl.fst());
|
||||
}
|
||||
m_st.env() = update_spec_info(env(), new_decls);
|
||||
m_env = update_spec_info(env(), new_decls);
|
||||
}
|
||||
|
||||
/* It is only safe to cache when `m_params.size == 0`. See comment above. */
|
||||
|
|
@ -1162,7 +1164,7 @@ class specialize_fn {
|
|||
i++;
|
||||
}
|
||||
tout() << ">> key: " << trace_pp_expr(key) << "\n";);
|
||||
m_st.env() = cache_specialization(env(), key, *new_fn_name);
|
||||
m_env = cache_specialization(env(), key, *new_fn_name);
|
||||
}
|
||||
}
|
||||
expr r = mk_constant(*new_fn_name);
|
||||
|
|
@ -1213,10 +1215,10 @@ class specialize_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
specialize_fn(environment const & env, csimp_cfg const & cfg):
|
||||
m_st(env), m_cfg(cfg), m_at("_at"), m_spec("_spec") {}
|
||||
specialize_fn(elab_environment const & env, csimp_cfg const & cfg):
|
||||
m_env(env), m_st(env), m_cfg(cfg), m_at("_at"), m_spec("_spec") {}
|
||||
|
||||
pair<environment, comp_decls> operator()(comp_decl const & d) {
|
||||
pair<elab_environment, comp_decls> operator()(comp_decl const & d) {
|
||||
m_base_name = d.fst();
|
||||
lean_trace(name({"compiler", "specialize"}), tout() << "INPUT: " << d.fst() << "\n" << trace_pp_expr(d.snd()) << "\n";);
|
||||
expr new_v = visit(d.snd());
|
||||
|
|
@ -1225,11 +1227,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
pair<environment, comp_decls> specialize_core(environment const & env, comp_decl const & d, csimp_cfg const & cfg) {
|
||||
pair<elab_environment, comp_decls> specialize_core(elab_environment const & env, comp_decl const & d, csimp_cfg const & cfg) {
|
||||
return specialize_fn(env, cfg)(d);
|
||||
}
|
||||
|
||||
pair<environment, comp_decls> specialize(environment env, comp_decls const & ds, csimp_cfg const & cfg) {
|
||||
pair<elab_environment, comp_decls> specialize(elab_environment env, comp_decls const & ds, csimp_cfg const & cfg) {
|
||||
env = update_spec_info(env, ds);
|
||||
comp_decls r;
|
||||
for (comp_decl const & d : ds) {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/util.h"
|
||||
#include "library/compiler/csimp.h"
|
||||
namespace lean {
|
||||
pair<environment, comp_decls> specialize(environment env, comp_decls const & ds, csimp_cfg const & cfg);
|
||||
pair<elab_environment, comp_decls> specialize(elab_environment env, comp_decls const & ds, csimp_cfg const & cfg);
|
||||
void initialize_specialize();
|
||||
void finalize_specialize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ Author: Leonardo de Moura
|
|||
|
||||
namespace lean {
|
||||
class struct_cases_on_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
name_set m_scrutinies; /* Set of variables `x` such that there is `casesOn x ...` in the context */
|
||||
|
|
@ -23,7 +24,7 @@ class struct_cases_on_fn {
|
|||
name m_fld{"_d"};
|
||||
unsigned m_next_idx{1};
|
||||
|
||||
environment const & env() { return m_st.env(); }
|
||||
elab_environment const & env() { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -203,8 +204,8 @@ class struct_cases_on_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
struct_cases_on_fn(environment const & env):
|
||||
m_st(env) {
|
||||
struct_cases_on_fn(elab_environment const & env):
|
||||
m_env(env), m_st(env) {
|
||||
}
|
||||
|
||||
expr operator()(expr const & e) {
|
||||
|
|
@ -212,7 +213,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
expr struct_cases_on(environment const & env, expr const & e) {
|
||||
expr struct_cases_on(elab_environment const & env, expr const & e) {
|
||||
return struct_cases_on_fn(env)(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
/* Insert `S.casesOn` applications for a structure `S` when
|
||||
|
|
@ -50,5 +50,5 @@ namespace lean {
|
|||
The missing definitional equalities is problematic. For example, the whole algebraic hierarchy
|
||||
in Lean relies on them.
|
||||
*/
|
||||
expr struct_cases_on(environment const & env, expr const & e);
|
||||
expr struct_cases_on(elab_environment const & env, expr const & e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,13 +94,13 @@ extern "C" uint8 lean_has_inline_if_reduce_attribute(object* env, object* n);
|
|||
extern "C" uint8 lean_has_macro_inline_attribute(object* env, object* n);
|
||||
extern "C" uint8 lean_has_noinline_attribute(object* env, object* n);
|
||||
|
||||
bool has_inline_attribute(environment const & env, name const & n) { return lean_has_inline_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_inline_if_reduce_attribute(environment const & env, name const & n) { return lean_has_inline_if_reduce_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_macro_inline_attribute(environment const & env, name const & n) { return lean_has_macro_inline_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_noinline_attribute(environment const & env, name const & n) { return lean_has_noinline_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_inline_attribute(elab_environment const & env, name const & n) { return lean_has_inline_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_inline_if_reduce_attribute(elab_environment const & env, name const & n) { return lean_has_inline_if_reduce_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_macro_inline_attribute(elab_environment const & env, name const & n) { return lean_has_macro_inline_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_noinline_attribute(elab_environment const & env, name const & n) { return lean_has_noinline_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
|
||||
extern "C" uint8 lean_has_never_extract_attribute(object* env, object *n);
|
||||
bool has_never_extract_attribute(environment const & env, name const & n) { return lean_has_never_extract_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
bool has_never_extract_attribute(elab_environment const & env, name const & n) { return lean_has_never_extract_attribute(env.to_obj_arg(), n.to_obj_arg()); }
|
||||
|
||||
bool is_lcnf_atom(expr const & e) {
|
||||
switch (e.kind()) {
|
||||
|
|
@ -126,8 +126,8 @@ expr elim_trivial_let_decls(expr const & e) {
|
|||
}
|
||||
|
||||
struct unfold_macro_defs_fn : public replace_visitor {
|
||||
environment const & m_env;
|
||||
unfold_macro_defs_fn(environment const & env):m_env(env) {}
|
||||
elab_environment const & m_env;
|
||||
unfold_macro_defs_fn(elab_environment const & env):m_env(env) {}
|
||||
|
||||
|
||||
bool should_macro_inline(name const & n) {
|
||||
|
|
@ -175,15 +175,15 @@ struct unfold_macro_defs_fn : public replace_visitor {
|
|||
}
|
||||
};
|
||||
|
||||
expr unfold_macro_defs(environment const & env, expr const & e) {
|
||||
expr unfold_macro_defs(elab_environment const & env, expr const & e) {
|
||||
return unfold_macro_defs_fn(env)(e);
|
||||
}
|
||||
|
||||
bool is_cases_on_recursor(environment const & env, name const & n) {
|
||||
bool is_cases_on_recursor(elab_environment const & env, name const & n) {
|
||||
return ::lean::is_aux_recursor(env, n) && n.get_string() == g_cases_on;
|
||||
}
|
||||
|
||||
unsigned get_cases_on_arity(environment const & env, name const & c, bool before_erasure) {
|
||||
unsigned get_cases_on_arity(elab_environment const & env, name const & c, bool before_erasure) {
|
||||
lean_assert(is_cases_on_recursor(env, c));
|
||||
inductive_val I_val = get_cases_on_inductive_val(env, c);
|
||||
unsigned nminors = I_val.get_ncnstrs();
|
||||
|
|
@ -196,7 +196,7 @@ unsigned get_cases_on_arity(environment const & env, name const & c, bool before
|
|||
}
|
||||
}
|
||||
|
||||
unsigned get_cases_on_major_idx(environment const & env, name const & c, bool before_erasure) {
|
||||
unsigned get_cases_on_major_idx(elab_environment const & env, name const & c, bool before_erasure) {
|
||||
if (before_erasure) {
|
||||
inductive_val I_val = get_cases_on_inductive_val(env, c);
|
||||
return I_val.get_nparams() + 1 /* motive */ + I_val.get_nindices();
|
||||
|
|
@ -205,14 +205,14 @@ unsigned get_cases_on_major_idx(environment const & env, name const & c, bool be
|
|||
}
|
||||
}
|
||||
|
||||
expr get_cases_on_app_major(environment const & env, expr const & c, bool before_erasure) {
|
||||
expr get_cases_on_app_major(elab_environment const & env, expr const & c, bool before_erasure) {
|
||||
lean_assert(is_cases_on_app(env, c));
|
||||
buffer<expr> args;
|
||||
expr const & fn = get_app_args(c, args);
|
||||
return args[get_cases_on_major_idx(env, const_name(fn), before_erasure)];
|
||||
}
|
||||
|
||||
pair<unsigned, unsigned> get_cases_on_minors_range(environment const & env, name const & c, bool before_erasure) {
|
||||
pair<unsigned, unsigned> get_cases_on_minors_range(elab_environment const & env, name const & c, bool before_erasure) {
|
||||
inductive_val I_val = get_cases_on_inductive_val(env, c);
|
||||
unsigned nminors = I_val.get_ncnstrs();
|
||||
if (before_erasure) {
|
||||
|
|
@ -294,7 +294,7 @@ void sort_fvars(local_ctx const & lctx, buffer<expr> & fvars) {
|
|||
});
|
||||
}
|
||||
|
||||
unsigned get_lcnf_size(environment const & env, expr e) {
|
||||
unsigned get_lcnf_size(elab_environment const & env, expr e) {
|
||||
unsigned r = 0;
|
||||
switch (e.kind()) {
|
||||
case expr_kind::BVar: case expr_kind::MVar:
|
||||
|
|
@ -558,16 +558,16 @@ expr mk_runtime_type(type_checker::state & st, local_ctx const & lctx, expr e) {
|
|||
}
|
||||
}
|
||||
|
||||
environment register_stage1_decl(environment const & env, name const & n, names const & ls, expr const & t, expr const & v) {
|
||||
elab_environment register_stage1_decl(elab_environment const & env, name const & n, names const & ls, expr const & t, expr const & v) {
|
||||
declaration aux_decl = mk_definition(mk_cstage1_name(n), ls, t, v, reducibility_hints::mk_opaque(), definition_safety::unsafe);
|
||||
return env.add(aux_decl, false);
|
||||
}
|
||||
|
||||
bool is_stage2_decl(environment const & env, name const & n) {
|
||||
bool is_stage2_decl(elab_environment const & env, name const & n) {
|
||||
return static_cast<bool>(env.find(mk_cstage2_name(n)));
|
||||
}
|
||||
|
||||
environment register_stage2_decl(environment const & env, name const & n, expr const & t, expr const & v) {
|
||||
elab_environment register_stage2_decl(elab_environment const & env, name const & n, expr const & t, expr const & v) {
|
||||
declaration aux_decl = mk_definition(mk_cstage2_name(n), names(), t,
|
||||
v, reducibility_hints::mk_opaque(), definition_safety::unsafe);
|
||||
return env.add(aux_decl, false);
|
||||
|
|
@ -608,10 +608,11 @@ we can get an irrelevant `ty`.
|
|||
We disabled this validator since we will delete the code generator written in C++.
|
||||
*/
|
||||
class lcnf_valid_let_decls_fn {
|
||||
elab_environment m_env;
|
||||
type_checker::state m_st;
|
||||
local_ctx m_lctx;
|
||||
|
||||
environment const & env() const { return m_st.env(); }
|
||||
elab_environment const & env() const { return m_env; }
|
||||
|
||||
name_generator & ngen() { return m_st.ngen(); }
|
||||
|
||||
|
|
@ -675,19 +676,19 @@ class lcnf_valid_let_decls_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
lcnf_valid_let_decls_fn(environment const & env, local_ctx const & lctx):
|
||||
m_st(env), m_lctx(lctx) {}
|
||||
lcnf_valid_let_decls_fn(elab_environment const & env, local_ctx const & lctx):
|
||||
m_env(env), m_st(env), m_lctx(lctx) {}
|
||||
|
||||
optional<expr> operator()(expr const & e) {
|
||||
return visit(e);
|
||||
}
|
||||
};
|
||||
|
||||
optional<expr> lcnf_valid_let_decls(environment const & env, expr const & e) {
|
||||
optional<expr> lcnf_valid_let_decls(elab_environment const & env, expr const & e) {
|
||||
return lcnf_valid_let_decls_fn(env, local_ctx())(e);
|
||||
}
|
||||
|
||||
bool lcnf_check_let_decls(environment const & env, comp_decl const & d) {
|
||||
bool lcnf_check_let_decls(elab_environment const & env, comp_decl const & d) {
|
||||
if (optional<expr> v = lcnf_valid_let_decls(env, d.snd())) {
|
||||
tout() << "LCNF violation at " << d.fst() << "\n" << *v << "\n";
|
||||
return false;
|
||||
|
|
@ -696,7 +697,7 @@ bool lcnf_check_let_decls(environment const & env, comp_decl const & d) {
|
|||
}
|
||||
}
|
||||
|
||||
bool lcnf_check_let_decls(environment const & env, comp_decls const & ds) {
|
||||
bool lcnf_check_let_decls(elab_environment const & env, comp_decls const & ds) {
|
||||
for (comp_decl const & d : ds) {
|
||||
if (!lcnf_check_let_decls(env, d))
|
||||
return false;
|
||||
|
|
@ -771,12 +772,12 @@ expr lcnf_eta_expand(type_checker::state & st, local_ctx lctx, expr e) {
|
|||
}
|
||||
}
|
||||
|
||||
bool is_quot_primitive_app(environment const & env, expr const & e) {
|
||||
bool is_quot_primitive_app(elab_environment const & env, expr const & e) {
|
||||
expr const & f = get_app_fn(e);
|
||||
return is_constant(f) && is_quot_primitive(env, const_name(f));
|
||||
}
|
||||
|
||||
bool must_be_eta_expanded(environment const & env, expr const & e) {
|
||||
bool must_be_eta_expanded(elab_environment const & env, expr const & e) {
|
||||
return
|
||||
is_constructor_app(env, e) ||
|
||||
is_proj(e) ||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
|||
#include "kernel/type_checker.h"
|
||||
#include "library/constants.h"
|
||||
#include "library/util.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
/* Return the `some(n)` if `I` is the name of an inductive datatype that contains only constructors with 0-arguments,
|
||||
|
|
@ -35,19 +36,19 @@ bool is_lcnf_atom(expr const & e);
|
|||
|
||||
expr elim_trivial_let_decls(expr const & e);
|
||||
|
||||
bool has_inline_attribute(environment const & env, name const & n);
|
||||
bool has_noinline_attribute(environment const & env, name const & n);
|
||||
bool has_inline_if_reduce_attribute(environment const & env, name const & n);
|
||||
bool has_never_extract_attribute(environment const & env, name const & n);
|
||||
bool has_inline_attribute(elab_environment const & env, name const & n);
|
||||
bool has_noinline_attribute(elab_environment const & env, name const & n);
|
||||
bool has_inline_if_reduce_attribute(elab_environment const & env, name const & n);
|
||||
bool has_never_extract_attribute(elab_environment const & env, name const & n);
|
||||
|
||||
expr unfold_macro_defs(environment const & env, expr const & e);
|
||||
expr unfold_macro_defs(elab_environment const & env, expr const & e);
|
||||
|
||||
/* Return true if the given argument is mdata relevant to the compiler
|
||||
|
||||
Remark: we currently don't keep any metadata in the compiler. */
|
||||
inline bool is_lc_mdata(expr const &) { return false; }
|
||||
|
||||
bool is_cases_on_recursor(environment const & env, name const & n);
|
||||
bool is_cases_on_recursor(elab_environment const & env, name const & n);
|
||||
/* We defined the "arity" of a cases_on application as the sum:
|
||||
```
|
||||
number of inductive parameters +
|
||||
|
|
@ -57,30 +58,30 @@ bool is_cases_on_recursor(environment const & env, name const & n);
|
|||
number of constructors // cases_on has a minor premise for each constructor
|
||||
```
|
||||
\pre is_cases_on_recursor(env, c) */
|
||||
unsigned get_cases_on_arity(environment const & env, name const & c, bool before_erasure = true);
|
||||
unsigned get_cases_on_arity(elab_environment const & env, name const & c, bool before_erasure = true);
|
||||
/* Return the `inductive_val` for the cases_on constant `c`. */
|
||||
inline inductive_val get_cases_on_inductive_val(environment const & env, name const & c) {
|
||||
inline inductive_val get_cases_on_inductive_val(elab_environment const & env, name const & c) {
|
||||
lean_assert(is_cases_on_recursor(env, c));
|
||||
return env.get(c.get_prefix()).to_inductive_val();
|
||||
}
|
||||
inline inductive_val get_cases_on_inductive_val(environment const & env, expr const & c) {
|
||||
inline inductive_val get_cases_on_inductive_val(elab_environment const & env, expr const & c) {
|
||||
lean_assert(is_constant(c));
|
||||
return get_cases_on_inductive_val(env, const_name(c));
|
||||
}
|
||||
inline bool is_cases_on_app(environment const & env, expr const & e) {
|
||||
inline bool is_cases_on_app(elab_environment const & env, expr const & e) {
|
||||
expr const & fn = get_app_fn(e);
|
||||
return is_constant(fn) && is_cases_on_recursor(env, const_name(fn));
|
||||
}
|
||||
/* Return the major premise of a cases_on-application.
|
||||
\pre is_cases_on_app(env, c) */
|
||||
expr get_cases_on_app_major(environment const & env, expr const & c, bool before_erasure = true);
|
||||
unsigned get_cases_on_major_idx(environment const & env, name const & c, bool before_erasure = true);
|
||||
expr get_cases_on_app_major(elab_environment const & env, expr const & c, bool before_erasure = true);
|
||||
unsigned get_cases_on_major_idx(elab_environment const & env, name const & c, bool before_erasure = true);
|
||||
/* Return the pair `(b, e)` such that `i in [b, e)` is argument `i` in a `c` cases_on
|
||||
application is a minor premise.
|
||||
\pre is_cases_on_recursor(env, c) */
|
||||
pair<unsigned, unsigned> get_cases_on_minors_range(environment const & env, name const & c, bool before_erasure = true);
|
||||
pair<unsigned, unsigned> get_cases_on_minors_range(elab_environment const & env, name const & c, bool before_erasure = true);
|
||||
|
||||
inline bool is_quot_primitive(environment const & env, name const & n) {
|
||||
inline bool is_quot_primitive(elab_environment const & env, name const & n) {
|
||||
optional<constant_info> info = env.find(n);
|
||||
return info && info->is_quot();
|
||||
}
|
||||
|
|
@ -119,7 +120,7 @@ expr replace_fvar(expr const & e, expr const & fvar, expr const & new_term);
|
|||
void sort_fvars(local_ctx const & lctx, buffer<expr> & fvars);
|
||||
|
||||
/* Return the "code" size for `e` */
|
||||
unsigned get_lcnf_size(environment const & env, expr e);
|
||||
unsigned get_lcnf_size(elab_environment const & env, expr e);
|
||||
|
||||
// =======================================
|
||||
// Auxiliary expressions for erasure.
|
||||
|
|
@ -165,9 +166,9 @@ void collect_used(expr const & e, name_hash_set & S);
|
|||
/* Return true iff `e` contains a free variable in `s` */
|
||||
bool depends_on(expr const & e, name_hash_set const & s);
|
||||
|
||||
bool is_stage2_decl(environment const & env, name const & n);
|
||||
environment register_stage1_decl(environment const & env, name const & n, names const & ls, expr const & t, expr const & v);
|
||||
environment register_stage2_decl(environment const & env, name const & n, expr const & t, expr const & v);
|
||||
bool is_stage2_decl(elab_environment const & env, name const & n);
|
||||
elab_environment register_stage1_decl(elab_environment const & env, name const & n, names const & ls, expr const & t, expr const & v);
|
||||
elab_environment register_stage2_decl(elab_environment const & env, name const & n, expr const & t, expr const & v);
|
||||
|
||||
/* Return `some n` iff `e` is of the forms `expr.lit (literal.nat n)` or `uint*.of_nat (expr.lit (literal.nat n))` */
|
||||
optional<nat> get_num_lit_ext(expr const & e);
|
||||
|
|
@ -181,8 +182,8 @@ optional<unsigned> is_fix_core(name const & c);
|
|||
Remark: this function assumes universe levels have already been erased. */
|
||||
optional<expr> mk_enf_fix_core(unsigned n);
|
||||
|
||||
bool lcnf_check_let_decls(environment const & env, comp_decl const & d);
|
||||
bool lcnf_check_let_decls(environment const & env, comp_decls const & ds);
|
||||
bool lcnf_check_let_decls(elab_environment const & env, comp_decl const & d);
|
||||
bool lcnf_check_let_decls(elab_environment const & env, comp_decls const & ds);
|
||||
|
||||
// =======================================
|
||||
/* Similar to `type_checker::eta_expand`, but preserves LCNF */
|
||||
|
|
@ -200,11 +201,11 @@ optional<unsigned> is_enum_type(environment const & env, expr const & type);
|
|||
|
||||
extern "C" uint8 lean_is_matcher(object* env, object* n);
|
||||
|
||||
inline bool is_matcher(environment const & env, name const & n) {
|
||||
inline bool is_matcher(elab_environment const & env, name const & n) {
|
||||
return lean_is_matcher(env.to_obj_arg(), n.to_obj_arg());
|
||||
}
|
||||
|
||||
inline bool is_matcher_app(environment const & env, expr const & e) {
|
||||
inline bool is_matcher_app(elab_environment const & env, expr const & e) {
|
||||
expr const & f = get_app_fn(e);
|
||||
return is_constant(f) && is_matcher(env, const_name(f));
|
||||
}
|
||||
|
|
@ -213,7 +214,7 @@ inline bool is_matcher_app(environment const & env, expr const & e) {
|
|||
Return true if the given expression must be in eta-expanded form during compilation.
|
||||
Example: constructors, `casesOn` applications must always be in eta-expanded form.
|
||||
*/
|
||||
bool must_be_eta_expanded(environment const & env, expr const & e);
|
||||
bool must_be_eta_expanded(elab_environment const & env, expr const & e);
|
||||
|
||||
void initialize_compiler_util();
|
||||
void finalize_compiler_util();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#include "runtime/sstream.h"
|
||||
#include "kernel/kernel_exception.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "kernel/instantiate.h"
|
||||
#include "kernel/abstract.h"
|
||||
#include "kernel/type_checker.h"
|
||||
|
|
@ -22,7 +22,7 @@ static void throw_corrupted(name const & n) {
|
|||
throw exception(sstream() << "error in '" << g_no_confusion << "' generation, '" << n << "' inductive datatype declaration is corrupted");
|
||||
}
|
||||
|
||||
static declaration mk_no_confusion_type(environment const & env, name const & n) {
|
||||
static declaration mk_no_confusion_type(elab_environment const & env, name const & n) {
|
||||
constant_info ind_info = env.get(n);
|
||||
inductive_val ind_val = ind_info.to_inductive_val();
|
||||
local_ctx lctx;
|
||||
|
|
@ -122,10 +122,10 @@ static declaration mk_no_confusion_type(environment const & env, name const & n)
|
|||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_mk_no_confusion_type(object * env, object * n) {
|
||||
return catch_kernel_exceptions<declaration>([&]() { return mk_no_confusion_type(environment(env), name(n, true)); });
|
||||
return catch_kernel_exceptions<declaration>([&]() { return mk_no_confusion_type(elab_environment(env), name(n, true)); });
|
||||
}
|
||||
|
||||
declaration mk_no_confusion(environment const & env, name const & n) {
|
||||
declaration mk_no_confusion(elab_environment const & env, name const & n) {
|
||||
local_ctx lctx;
|
||||
name_generator ngen = mk_constructions_name_generator();
|
||||
constant_info ind_info = env.get(n);
|
||||
|
|
@ -229,6 +229,6 @@ declaration mk_no_confusion(environment const & env, name const & n) {
|
|||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_mk_no_confusion(object * env, object * n) {
|
||||
return catch_kernel_exceptions<declaration>([&]() { return mk_no_confusion(environment(env), name(n, true)); });
|
||||
return catch_kernel_exceptions<declaration>([&]() { return mk_no_confusion(elab_environment(env), name(n, true)); });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Given an inductive datatype \c n (which is not a proposition) in \c env,
|
||||
|
|
@ -15,7 +15,7 @@ namespace lean {
|
|||
If the environment has an impredicative Prop, it also assumes heq is defined.
|
||||
If the environment does not have an impredicative Prop, then it also assumes lift is defined.
|
||||
*/
|
||||
declaration mk_no_confusion_type(environment const & env, name const & n);
|
||||
declaration mk_no_confusion_type(elab_environment const & env, name const & n);
|
||||
|
||||
/** \brief Given an inductive datatype \c n (which is not a proposition) in \c env,
|
||||
returns the declaration for <tt>n.no_confusion</tt>.
|
||||
|
|
@ -24,5 +24,5 @@ declaration mk_no_confusion_type(environment const & env, name const & n);
|
|||
If the environment has an impredicative Prop, it also assumes heq is defined.
|
||||
If the environment does not have an impredicative Prop, then it also assumes lift is defined.
|
||||
*/
|
||||
declaration mk_no_confusion(environment const & env, name const & n);
|
||||
declaration mk_no_confusion(elab_environment const & env, name const & n);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static bool is_prop(expr type) {
|
|||
return is_sort(type) && is_zero(sort_level(type));
|
||||
}
|
||||
|
||||
environment mk_projections(environment const & env, name const & n, buffer<name> const & proj_names, bool inst_implicit) {
|
||||
elab_environment mk_projections(elab_environment const & env, name const & n, buffer<name> const & proj_names, bool inst_implicit) {
|
||||
local_ctx lctx;
|
||||
name_generator ngen = mk_constructions_name_generator();
|
||||
constant_info ind_info = env.get(n);
|
||||
|
|
@ -82,7 +82,7 @@ environment mk_projections(environment const & env, name const & n, buffer<name>
|
|||
it = instantiate(binding_body(it), local);
|
||||
}
|
||||
unsigned i = 0;
|
||||
environment new_env = env;
|
||||
elab_environment new_env = env;
|
||||
for (name const & proj_name : proj_names) {
|
||||
if (!is_pi(cnstr_type))
|
||||
throw exception(sstream() << "generating projection '" << proj_name << "', '"
|
||||
|
|
@ -126,14 +126,14 @@ environment mk_projections(environment const & env, name const & n, buffer<name>
|
|||
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_mk_projections(object * env, object * struct_name, object * proj_infos, uint8 inst_implicit) {
|
||||
environment new_env(env);
|
||||
elab_environment new_env(env);
|
||||
name n(struct_name);
|
||||
list_ref<name> ps(proj_infos);
|
||||
buffer<name> proj_names;
|
||||
for (auto p : ps) {
|
||||
proj_names.push_back(p);
|
||||
}
|
||||
return catch_kernel_exceptions<environment>([&]() { return mk_projections(new_env, n, proj_names, inst_implicit != 0); });
|
||||
return catch_kernel_exceptions<elab_environment>([&]() { return mk_projections(new_env, n, proj_names, inst_implicit != 0); });
|
||||
}
|
||||
|
||||
void initialize_def_projection() {
|
||||
|
|
|
|||
74
src/library/elab_environment.cpp
Normal file
74
src/library/elab_environment.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Authors: Leonardo de Moura, Sebastian Ullrich
|
||||
*/
|
||||
#include "runtime/interrupt.h"
|
||||
#include "kernel/type_checker.h"
|
||||
#include "kernel/kernel_exception.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/compiler/ir_interpreter.h"
|
||||
|
||||
namespace lean {
|
||||
/* updateBaseAfterKernelAdd (env : Environment) (added : Declaration) (base : Kernel.Environment) :
|
||||
Environment
|
||||
|
||||
Updates an elab environment with a given kernel environment after the declaration `d` has been
|
||||
added to it. `d` is used to adjust further elab env data such as registering new namespaces.
|
||||
|
||||
NOTE: Ideally this language switching would not be necessary and we could do all this in Lean
|
||||
only but the old code generator and `mk_projections` still need a C++ `elab_environment::add`. */
|
||||
extern "C" obj_res lean_elab_environment_update_base_after_kernel_add(obj_arg env, obj_arg d, obj_arg kenv);
|
||||
|
||||
elab_environment elab_environment::add(declaration const & d, bool check) const {
|
||||
environment kenv = to_kernel_env().add(d, check);
|
||||
return elab_environment(lean_elab_environment_update_base_after_kernel_add(this->to_obj_arg(), d.to_obj_arg(), kenv.to_obj_arg()));
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_elab_add_decl(object * env, size_t max_heartbeat, object * decl,
|
||||
object * opt_cancel_tk) {
|
||||
scope_max_heartbeat s(max_heartbeat);
|
||||
scope_cancel_tk s2(is_scalar(opt_cancel_tk) ? nullptr : cnstr_get(opt_cancel_tk, 0));
|
||||
return catch_kernel_exceptions<elab_environment>([&]() {
|
||||
return elab_environment(env).add(declaration(decl, true));
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT object * lean_elab_add_decl_without_checking(object * env, object * decl) {
|
||||
return catch_kernel_exceptions<elab_environment>([&]() {
|
||||
return elab_environment(env).add(declaration(decl, true), false);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" obj_res lean_elab_environment_to_kernel_env(obj_arg);
|
||||
environment elab_environment::to_kernel_env() const {
|
||||
return environment(lean_elab_environment_to_kernel_env(to_obj_arg()));
|
||||
}
|
||||
|
||||
extern "C" obj_res lean_display_stats(obj_arg env, obj_arg w);
|
||||
void elab_environment::display_stats() const {
|
||||
dec_ref(lean_display_stats(to_obj_arg(), io_mk_world()));
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT lean_object * lean_kernel_is_def_eq(lean_object * obj_env, lean_object * lctx, lean_object * a, lean_object * b) {
|
||||
elab_environment env(obj_env);
|
||||
return catch_kernel_exceptions<object*>([&]() {
|
||||
return lean_box(type_checker(env.to_kernel_env(), local_ctx(lctx)).is_def_eq(expr(a), expr(b)));
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT lean_object * lean_kernel_whnf(lean_object * obj_env, lean_object * lctx, lean_object * a) {
|
||||
elab_environment env(obj_env);
|
||||
return catch_kernel_exceptions<object*>([&]() {
|
||||
return type_checker(env.to_kernel_env(), local_ctx(lctx)).whnf(expr(a)).steal();
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" LEAN_EXPORT lean_object * lean_kernel_check(lean_object * obj_env, lean_object * lctx, lean_object * a) {
|
||||
elab_environment env(obj_env);
|
||||
return catch_kernel_exceptions<object*>([&]() {
|
||||
return type_checker(env.to_kernel_env(), local_ctx(lctx)).check(expr(a)).steal();
|
||||
});
|
||||
}
|
||||
}
|
||||
43
src/library/elab_environment.h
Normal file
43
src/library/elab_environment.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright (c) 2024 Lean FRO. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Authors: Leonardo de Moura, Sebastian Ullrich
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
|
||||
namespace lean {
|
||||
/* Wrapper for `Lean.Environment` */
|
||||
class LEAN_EXPORT elab_environment : public object_ref {
|
||||
public:
|
||||
elab_environment(elab_environment const & other):object_ref(other) {}
|
||||
elab_environment(elab_environment && other):object_ref(other) {}
|
||||
explicit elab_environment(b_obj_arg o, bool b):object_ref(o, b) {}
|
||||
explicit elab_environment(obj_arg o):object_ref(o) {}
|
||||
~elab_environment() {}
|
||||
|
||||
elab_environment & operator=(elab_environment const & other) { object_ref::operator=(other); return *this; }
|
||||
elab_environment & operator=(elab_environment && other) { object_ref::operator=(other); return *this; }
|
||||
|
||||
/** \brief Return information for the constant with name \c n (if it is defined in this environment). */
|
||||
optional<constant_info> find(name const & n) const { return to_kernel_env().find(n); };
|
||||
|
||||
/** \brief Return information for the constant with name \c n. Throws and exception if constant declaration does not exist in this environment. */
|
||||
constant_info get(name const & n) const { return to_kernel_env().get(n); };
|
||||
|
||||
/** \brief Extends the current environment with the given declaration */
|
||||
elab_environment add(declaration const & d, bool check = true) const;
|
||||
|
||||
/** \brief Pointer equality */
|
||||
friend bool is_eqp(elab_environment const & e1, elab_environment const & e2) {
|
||||
return e1.raw() == e2.raw();
|
||||
}
|
||||
|
||||
void display_stats() const;
|
||||
|
||||
environment to_kernel_env() const;
|
||||
|
||||
operator environment() const { return to_kernel_env(); }
|
||||
};
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@ extern "C" LEAN_EXPORT object * lean_read_module_data(object * fname, object *)
|
|||
def writeModule (env : Environment) (fname : String) : IO Unit := */
|
||||
extern "C" object * lean_write_module(object * env, object * fname, object *);
|
||||
|
||||
void write_module(environment const & env, std::string const & olean_fn) {
|
||||
void write_module(elab_environment const & env, std::string const & olean_fn) {
|
||||
consume_io_result(lean_write_module(env.to_obj_arg(), mk_string(olean_fn), io_mk_world()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ Authors: Leonardo de Moura, Gabriel Ebner, Sebastian Ullrich
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
#include "runtime/optional.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Store module using \c env. */
|
||||
LEAN_EXPORT void write_module(environment const & env, std::string const & olean_fn);
|
||||
LEAN_EXPORT void write_module(elab_environment const & env, std::string const & olean_fn);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ bool projection_info::is_inst_implicit() const { return lean_projection_info_fro
|
|||
extern "C" object* lean_add_projection_info(object* env, object* p, object* ctor, object* nparams, object* i, uint8 fromClass);
|
||||
extern "C" object* lean_get_projection_info(object* env, object* p);
|
||||
|
||||
environment save_projection_info(environment const & env, name const & p, name const & mk, unsigned nparams, unsigned i, bool inst_implicit) {
|
||||
return environment(lean_add_projection_info(env.to_obj_arg(), p.to_obj_arg(), mk.to_obj_arg(), mk_nat_obj(nparams), mk_nat_obj(i), inst_implicit));
|
||||
elab_environment save_projection_info(elab_environment const & env, name const & p, name const & mk, unsigned nparams, unsigned i, bool inst_implicit) {
|
||||
return elab_environment(lean_add_projection_info(env.to_obj_arg(), p.to_obj_arg(), mk.to_obj_arg(), mk_nat_obj(nparams), mk_nat_obj(i), inst_implicit));
|
||||
}
|
||||
|
||||
optional<projection_info> get_projection_info(environment const & env, name const & p) {
|
||||
optional<projection_info> get_projection_info(elab_environment const & env, name const & p) {
|
||||
return to_optional<projection_info>(lean_get_projection_info(env.to_obj_arg(), p.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Auxiliary information attached to projections. This information
|
||||
|
|
@ -37,20 +37,20 @@ public:
|
|||
bool is_inst_implicit() const;
|
||||
};
|
||||
|
||||
/** \brief Mark \c p as a projection in the given environment and store that
|
||||
/** \brief Mark \c p as a projection in the given elab_environment and store that
|
||||
\c mk is the constructor associated with it, \c nparams is the number of parameters, and
|
||||
\c i says that \c p is the i-th projection.
|
||||
*/
|
||||
environment save_projection_info(environment const & env, name const & p, name const & mk, unsigned nparams, unsigned i,
|
||||
elab_environment save_projection_info(elab_environment const & env, name const & p, name const & mk, unsigned nparams, unsigned i,
|
||||
bool inst_implicit);
|
||||
|
||||
/** \brief If \c p is a projection in the given environment, then return the information
|
||||
/** \brief If \c p is a projection in the given elab_environment, then return the information
|
||||
associated with it (constructor, number of parameters, and index).
|
||||
If \c p is not a projection, then return nullptr.
|
||||
*/
|
||||
optional<projection_info> get_projection_info(environment const & env, name const & p);
|
||||
optional<projection_info> get_projection_info(elab_environment const & env, name const & p);
|
||||
|
||||
inline bool is_projection(environment const & env, name const & n) {
|
||||
inline bool is_projection(elab_environment const & env, name const & n) {
|
||||
return static_cast<bool>(get_projection_info(env, n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include <string>
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "library/reducible.h"
|
||||
|
||||
namespace lean {
|
||||
extern "C" uint8 lean_get_reducibility_status(object * env, object * n);
|
||||
extern "C" object * lean_set_reducibility_status(object * env, object * n, uint8 s);
|
||||
|
||||
environment set_reducible(environment const & env, name const & n, reducible_status s, bool persistent) {
|
||||
elab_environment set_reducible(elab_environment const & env, name const & n, reducible_status s, bool persistent) {
|
||||
if (!persistent)
|
||||
throw exception("reducibility attributes must be persistent for now, we will relax this restriction in a near future");
|
||||
return environment(lean_set_reducibility_status(env.to_obj_arg(), n.to_obj_arg(), static_cast<uint8>(s)));
|
||||
return elab_environment(lean_set_reducibility_status(env.to_obj_arg(), n.to_obj_arg(), static_cast<uint8>(s)));
|
||||
}
|
||||
|
||||
reducible_status get_reducible_status(environment const & env, name const & n) {
|
||||
reducible_status get_reducible_status(elab_environment const & env, name const & n) {
|
||||
return static_cast<reducible_status>(lean_get_reducibility_status(env.to_obj_arg(), n.to_obj_arg()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include "library/util.h"
|
||||
#include "library/elab_environment.h"
|
||||
|
||||
namespace lean {
|
||||
enum class reducible_status { Reducible, Semireducible, Irreducible };
|
||||
|
|
@ -20,10 +21,10 @@ enum class reducible_status { Reducible, Semireducible, Irreducible };
|
|||
"Reducible" definitions can be freely unfolded by automation (i.e., elaborator, simplifier, etc).
|
||||
We should view it as a hint to automation.
|
||||
*/
|
||||
environment set_reducible(environment const & env, name const & n, reducible_status s, bool persistent);
|
||||
elab_environment set_reducible(elab_environment const & env, name const & n, reducible_status s, bool persistent);
|
||||
|
||||
reducible_status get_reducible_status(environment const & env, name const & n);
|
||||
reducible_status get_reducible_status(elab_environment const & env, name const & n);
|
||||
|
||||
inline bool is_reducible(environment const & env, name const & n) { return get_reducible_status(env, n) == reducible_status::Reducible; }
|
||||
inline bool is_semireducible(environment const & env, name const & n) { return get_reducible_status(env, n) == reducible_status::Semireducible; }
|
||||
inline bool is_reducible(elab_environment const & env, name const & n) { return get_reducible_status(env, n) == reducible_status::Reducible; }
|
||||
inline bool is_semireducible(elab_environment const & env, name const & n) { return get_reducible_status(env, n) == reducible_status::Semireducible; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Author: Leonardo de Moura
|
|||
#include "util/io.h"
|
||||
#include "util/options.h"
|
||||
#include "util/option_declarations.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "library/elab_environment.h"
|
||||
#include "kernel/kernel_exception.h"
|
||||
#include "kernel/trace.h"
|
||||
#include "library/formatter.h"
|
||||
|
|
@ -338,7 +338,7 @@ extern "C" object * lean_run_frontend(
|
|||
object * error_kinds,
|
||||
object * w
|
||||
);
|
||||
pair_ref<environment, object_ref> run_new_frontend(
|
||||
pair_ref<elab_environment, object_ref> run_new_frontend(
|
||||
std::string const & input,
|
||||
options const & opts, std::string const & file_name,
|
||||
name const & main_module_name,
|
||||
|
|
@ -351,7 +351,7 @@ pair_ref<environment, object_ref> run_new_frontend(
|
|||
if (ilean_file_name) {
|
||||
oilean_file_name = mk_option_some(mk_string(*ilean_file_name));
|
||||
}
|
||||
return get_io_result<pair_ref<environment, object_ref>>(lean_run_frontend(
|
||||
return get_io_result<pair_ref<elab_environment, object_ref>>(lean_run_frontend(
|
||||
mk_string(input),
|
||||
opts.to_obj_arg(),
|
||||
mk_string(file_name),
|
||||
|
|
@ -415,7 +415,7 @@ void print_imports_json(array_ref<string_ref> const & fnames) {
|
|||
}
|
||||
|
||||
extern "C" object* lean_environment_free_regions(object * env, object * w);
|
||||
void environment_free_regions(environment && env) {
|
||||
void environment_free_regions(elab_environment && env) {
|
||||
consume_io_result(lean_environment_free_regions(env.steal(), io_mk_world()));
|
||||
}
|
||||
}
|
||||
|
|
@ -652,7 +652,6 @@ extern "C" LEAN_EXPORT int lean_main(int argc, char ** argv) {
|
|||
report_profiling_time("initialization", init_time);
|
||||
}
|
||||
|
||||
environment env(trust_lvl);
|
||||
scoped_task_manager scope_task_man(num_threads);
|
||||
optional<name> main_module_name;
|
||||
|
||||
|
|
@ -729,8 +728,8 @@ extern "C" LEAN_EXPORT int lean_main(int argc, char ** argv) {
|
|||
|
||||
if (!main_module_name)
|
||||
main_module_name = name("_stdin");
|
||||
pair_ref<environment, object_ref> r = run_new_frontend(contents, opts, mod_fn, *main_module_name, trust_lvl, ilean_fn, json_output, error_kinds);
|
||||
env = r.fst();
|
||||
pair_ref<elab_environment, object_ref> r = run_new_frontend(contents, opts, mod_fn, *main_module_name, trust_lvl, ilean_fn, json_output, error_kinds);
|
||||
elab_environment env = r.fst();
|
||||
bool ok = unbox(r.snd().raw());
|
||||
|
||||
if (stats) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ options get_default_options() {
|
|||
opts = opts.update({"debug", "proofAsSorry"}, false);
|
||||
// switch to `true` for ABI-breaking changes affecting meta code;
|
||||
// see also next option!
|
||||
opts = opts.update({"interpreter", "prefer_native"}, false);
|
||||
opts = opts.update({"interpreter", "prefer_native"}, true);
|
||||
// switch to `false` when enabling `prefer_native` should also affect use
|
||||
// of built-in parsers in quotations; this is usually the case, but setting
|
||||
// both to `true` may be necessary for handling non-builtin parsers with
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ scalar#1@0:u8
|
|||
obj@2
|
||||
---
|
||||
scalar#4@0:u32
|
||||
scalar#1@4:u8
|
||||
obj@0
|
||||
obj@1
|
||||
obj@2
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ open Lean in
|
|||
open Lean in
|
||||
#eval id (α := CoreM Unit) do
|
||||
-- this implementation is no longer allowed because of a private constructor
|
||||
modifyEnv fun env => { env with header.mainModule := `foo }
|
||||
modifyEnv fun env => { env with base.header.mainModule := `foo }
|
||||
|
||||
#check a -- Error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
a : Nat
|
||||
prvCtor.lean:25:23-25:61: error: invalid {...} notation, constructor for `Lean.Environment` is marked as private
|
||||
prvCtor.lean:25:23-25:66: error: invalid {...} notation, constructor for `Lean.Environment` is marked as private
|
||||
prvCtor.lean:27:7-27:8: error: unknown identifier 'a'
|
||||
prvCtor.lean:29:25-29:27: error: overloaded, errors
|
||||
failed to synthesize
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ inductive D
|
|||
| mk (x y z : Nat) : D
|
||||
|
||||
/--
|
||||
info: #[const2ModIdx, constants, extensions, extraConstNames, header]
|
||||
info: #[constants, quotInit, diagnostics, const2ModIdx, extensions, extraConstNames, header]
|
||||
#[toS2, toS1, x, y, z, toS3, w, s]
|
||||
(some [S4.toS2, S2.toS1])
|
||||
#[S2, S3]
|
||||
|
|
@ -33,7 +33,7 @@ info: #[const2ModIdx, constants, extensions, extraConstNames, header]
|
|||
#guard_msgs in
|
||||
#eval show CoreM Unit from do
|
||||
let env ← getEnv
|
||||
IO.println (getStructureFields env `Lean.Environment)
|
||||
IO.println (getStructureFields env ``Kernel.Environment)
|
||||
check $ getStructureFields env `S4 == #[`toS2, `toS3, `s]
|
||||
check $ getStructureFields env `S1 == #[`x, `y]
|
||||
check $ isSubobjectField? env `S4 `toS2 == some `S2
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue