Note [Environment Branches] #
The kernel environment type Lean.Kernel.Environment enforces a linear order on the addition of
declarations: addDeclCore takes an environment and returns a new one, assuming type checking
succeeded. On the other hand, the metaprogramming-level Lean.Environment wrapper must allow for
branching environment transformations so that multiple declarations can be elaborated
concurrently while still being able to access information about preceding declarations that have
also been branched out as soon as they are available.
The basic function to introduce such branches is addConstAsync, which takes an environment and
returns a structure containing two environments: one for the "main" branch that can be used in
further branching and eventually contains all the declarations of the file and one for the "async"
branch that can be used concurrently to the main branch to elaborate and add the declaration for
which the branch was introduced. Branches are "joined" back together implicitly via the kernel
environment, which as mentioned cannot be changed concurrently: when the main branch first tries to
access it, evaluation is blocked until the kernel environment on the async branch is complete.
Thus adding two declarations A and B concurrently can be visualized like this:
o addConstAsync A
|\
| \
| \
o addConstAsync B
|\ \
| \ o elaborate A
| \ |
| o elaborate B
| | |
| | o addDeclCore A
| |/
| o addDeclCore B
| /
| /
|/
o .olean serialization calls Environment.toKernelEnv
While each edge represents a Lean.Environment that has its own view of the state of the module,
the kernel environment really lives only in the right-most path, with all other paths merely holding
an unfulfilled Task representing it and where forcing that task leads to the back-edges joining
paths back together.
Opaque environment extension state.
Instances For
Equations
Equations
Equations
- Lean.instInhabitedModuleIdx = { default := 0 }
Equations
Instances For
A compacted region holds multiple Lean objects in a contiguous memory region, which can be read/written to/from disk. Objects inside the region do not have reference counters and cannot be freed individually. The contents of .olean files are compacted regions.
Equations
Instances For
Size in bytes.
Free a compacted region and its contents. No live references to the contents may exist at the time of invocation.
Instances For
Content of a .olean file.
We use compact.cpp to generate the image of this object in disk.
- isModule : Bool
Participating in the module system?
constNamescontains all constant names inconstants. This information is redundant. It is equal toconstants.map fun c => c.name, but it improves the performance ofimportModules.perfreports that 12% of the runtime was being spent onConstantInfo.namewhen importing a file containing onlyimport Lean- constants : Array ConstantInfo
Extra entries for the
const2ModIdxmap in theEnvironmentobject. The code generator creates auxiliary declarations that are not in the mappingconstants, but we want to know in which module they were generated.- entries : Array (Name × Array EnvExtensionEntry)
Instances For
Equations
Instances For
Equations
Equations
Instances For
Equations
- Lean.instBEqIRPhases.beq x✝ y✝ = (x✝.ctorIdx == y✝.ctorIdx)
Instances For
Equations
Equations
- Lean.instReprIRPhases = { reprPrec := Lean.instReprIRPhases.repr }
Equations
- Lean.instReprIRPhases.repr Lean.IRPhases.runtime prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.IRPhases.runtime")).group prec✝
- Lean.instReprIRPhases.repr Lean.IRPhases.comptime prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.IRPhases.comptime")).group prec✝
- Lean.instReprIRPhases.repr Lean.IRPhases.all prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.IRPhases.all")).group prec✝
Instances For
Import including information resulting from processing of the entire import DAG.
- irPhases : IRPhases
Phases for which the import's IR is available.
Instances For
Environment fields that are not used often.
- trustLevel : UInt32
The trust level used by the kernel. For example, the kernel assumes imported constants are type correct when the trust level is greater than zero.
- mainModule : Name
Name of the module being compiled.
- isModule : Bool
Participating in the module system?
Direct imports
- regions : Array CompactedRegion
Compacted regions for all imported modules. Objects in compacted memory regions do no require any memory management.
- modules : Array EffectiveImport
Direct and transitive imports. Modules are given with their effective import modifiers, not their original ones. Each module is listed at most once. The index of a module in the array equals the
ModuleIdxfor the same module. - moduleData : Array ModuleData
Module data for all imported modules.
Instances For
Name of all imported modules (directly and indirectly).
The index of a module name in the array equals the ModuleIdx for the same module.
Equations
- header.moduleNames = Array.map (fun (x : Lean.EffectiveImport) => x.module) header.modules
Instances For
Equations
Instances For
An environment stores declarations provided by the user. The kernel
currently supports different kinds of declarations such as definitions, theorems,
and inductive families. Each has a unique identifier (i.e., Name), and can be
parameterized by a sequence of universe parameters.
A constant in Lean is just a reference to a ConstantInfo object. The main task of
the kernel is to type check these declarations and refuse type incorrect ones. The
kernel does not allow declarations containing metavariables and/or free variables
to be added to an environment. Environments are never destructively updated.
The environment also contains a collection of extensions. For example, the simp theorems
declared by users are stored in an environment extension. Users can declare new extensions
using meta-programming.
- constants : ConstMap
Mapping from constant name to
ConstantInfo. It contains all constants (definitions, theorems, axioms, etc) that have been already type checked by the kernel. - quotInit : Bool
- diagnostics : Diagnostics
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.isDefEqandKernel.whnfdo not update the statistics. We claim this is ok since these methods are mainly used for debugging. - const2ModIdx : Std.HashMap Name ModuleIdx
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. Many extensions use theModuleIdxto efficiently retrieve information stored in imported modules.Remark: this mapping also contains auxiliary constants, created by the code generator, that are not in the field
constants. These auxiliary constants are invisible to the Lean kernel and elaborator. Only the code generator uses them. - extensions : Array Lean.EnvExtensionState
- irBaseExts : Array Lean.EnvExtensionState
- header : EnvironmentHeader
The header contains additional information that is set at import time.
Instances For
Exceptions that can be raised by the kernel when type checking new declarations.
- unknownConstant (env : Environment) (name : Name) : Exception
- alreadyDeclared (env : Environment) (name : Name) : Exception
- declTypeMismatch (env : Environment) (decl : Declaration) (givenType : Expr) : Exception
- declHasMVars (env : Environment) (name : Name) (expr : Expr) : Exception
- declHasFVars (env : Environment) (name : Name) (expr : Expr) : Exception
- funExpected (env : Environment) (lctx : LocalContext) (expr : Expr) : Exception
- typeExpected (env : Environment) (lctx : LocalContext) (expr : Expr) : Exception
- letTypeMismatch (env : Environment) (lctx : LocalContext) (name : Name) (givenType expectedType : Expr) : Exception
- exprTypeMismatch (env : Environment) (lctx : LocalContext) (expr expectedType : Expr) : Exception
- appTypeMismatch (env : Environment) (lctx : LocalContext) (app funType argType : Expr) : Exception
- invalidProj (env : Environment) (lctx : LocalContext) (proj : Expr) : Exception
- thmTypeIsNotProp (env : Environment) (name : Name) (type : Expr) : Exception
- other (msg : String) : Exception
- deterministicTimeout : Exception
- excessiveMemory : Exception
- deepRecursion : Exception
- interrupted : Exception
Instances For
Equations
- env.find? n = Lean.SMap.find?' env.constants n
Instances For
Type check given declaration and add it to the 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.
Equations
Instances For
Enables/disables kernel diagnostics.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- env.isDiagnosticsEnabled = env.diagnostics.enabled
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
- defn : ConstantKind
- thm : ConstantKind
- axiom : ConstantKind
- opaque : ConstantKind
- quot : ConstantKind
- induct : ConstantKind
- ctor : ConstantKind
- recursor : ConstantKind
Instances For
Instances For
Equations
Equations
- Lean.instBEqConstantKind.beq x✝ y✝ = (x✝.ctorIdx == y✝.ctorIdx)
Instances For
Equations
Equations
- Lean.instReprConstantKind = { reprPrec := Lean.instReprConstantKind.repr }
Equations
- Lean.instReprConstantKind.repr Lean.ConstantKind.defn prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.defn")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.thm prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.thm")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.axiom prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.axiom")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.opaque prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.opaque")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.quot prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.quot")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.induct prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.induct")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.ctor prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.ctor")).group prec✝
- Lean.instReprConstantKind.repr Lean.ConstantKind.recursor prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.ConstantKind.recursor")).group prec✝
Instances For
Equations
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.defnInfo val) = Lean.ConstantKind.defn
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.thmInfo val) = Lean.ConstantKind.thm
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.axiomInfo val) = Lean.ConstantKind.axiom
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.opaqueInfo val) = Lean.ConstantKind.opaque
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.quotInfo val) = Lean.ConstantKind.quot
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.inductInfo val) = Lean.ConstantKind.induct
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.ctorInfo val) = Lean.ConstantKind.ctor
- Lean.ConstantKind.ofConstantInfo (Lean.ConstantInfo.recInfo val) = Lean.ConstantKind.recursor
Instances For
ConstantInfo variant that allows for asynchronous filling of components via tasks.
- name : Name
The declaration name, known immediately.
- kind : ConstantKind
The kind of the constant, known immediately.
- sig : Task ConstantVal
The "signature" including level params and type, potentially filled asynchronously.
- constInfo : Task ConstantInfo
The final, complete constant info, potentially filled asynchronously.
Instances For
Equations
Instances For
Equations
- c.toConstantVal = c.sig.get
Instances For
Equations
- c.toConstantInfo = c.constInfo.get
Instances For
Equations
- Lean.AsyncConstantInfo.ofConstantInfo c = { name := c.name, kind := Lean.ConstantKind.ofConstantInfo c, sig := { get := c.toConstantVal }, constInfo := { get := c } }
Instances For
Equations
- c.isUnsafe = match c.kind with | Lean.ConstantKind.thm => false | x => c.toConstantInfo.isUnsafe
Instances For
Elaboration-specific extension of Kernel.Environment that adds tracking of asynchronously
elaborated declarations.
- serverBaseExts : Array Lean.EnvExtensionState
- checked : Task Kernel.Environment
Kernel environment task that is fulfilled when all asynchronously elaborated declarations are finished, containing the resulting environment. Also collects the environment extension state of all environment branches that contributed contained declarations.
- asyncConstsMap : Lean.VisibilityMap✝ Lean.AsyncConsts✝
- asyncCtx? : Option Lean.AsyncContext✝
- importRealizationCtx? : Option Lean.RealizationContext✝
- localRealizationCtxMap : Lean.NameMap Lean.RealizationContext✝
- allRealizations : Task (Lean.NameMap Lean.AsyncConst✝)
- isExporting : Bool
Indicates whether the environment is being used in an exported context, i.e. whether it should provide access to only the data to be imported by other modules participating in the module system.
Instances For
Equations
- env.header = (Lean.VisibilityMap.private✝ (Lean.Environment.base✝ env)).header
Instances For
Instances For
Equations
- env.allImportedModuleNames = env.header.moduleNames
Instances For
Equations
Instances For
Equations
- env.toKernelEnv = env.checked.get
Instances For
Updates env.isExporting. Ignored if env.header.isModule is false.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The declaration prefix to which the environment is restricted to, if any.
Equations
- env.asyncPrefix? = Option.map (fun (x : Lean.AsyncContext✝) => Lean.AsyncContext.declPrefix✝ x) (Lean.Environment.asyncCtx?✝ env)
Instances For
True while inside realizeConst's realize.
Equations
- env.isRealizing = Option.any (fun (x : Lean.AsyncContext✝) => !(Lean.AsyncContext.realizingStack✝ x).isEmpty) (Lean.Environment.asyncCtx?✝ env)
Instances For
Returns the environment just after importing. none if finalizeImport has never been called on
it.
Equations
Instances For
Forgets about the asynchronous context restrictions. Used only for withoutModifyingEnv.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Adds given declaration to the environment, type checking it unless doCheck is false.
This is a plumbing function for the implementation of Lean.addDecl, most users should use it
instead.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Mapping from constant name to ConstantInfo. It contains all constants (definitions, theorems,
axioms, etc) that have been already type checked by the kernel.
Equations
- env.constants = env.toKernelEnv.constants
Instances For
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.
Many extensions use the ModuleIdx to efficiently retrieve information stored in imported modules.
Remark: this mapping also contains auxiliary constants, created by the code generator, that are not in
the field constants. These auxiliary constants are invisible to the Lean kernel and elaborator.
Only the code generator uses them.
Equations
- env.const2ModIdx = env.toKernelEnv.const2ModIdx
Instances For
Looks up the given declaration name in the environment, avoiding forcing any in-progress elaboration
tasks unless necessary. This can usually be done efficiently because addConstAsync ensures that
declarations added in an environment branch have that branch's declaration name as a prefix, so we
know exactly what tasks to wait for to find a declaration. However, this is not true for
declarations from realizeConst, which are not restricted to the current prefix, and reference to
which may escape the branch(es) they have been realized on such as when looking into the type Expr
of a declaration found on another branch. Thus when we cannot find the declaration using the fast
prefix-based lookup, we fall back to waiting for and looking at the realizations from all branches.
To avoid this expensive search for realizations from other branches, skipRealize can be set to ensure
negative lookups are as fast as positive ones.
Use findTask instead if any blocking should be avoided.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Like findAsync? but returns a task instead of resorting to blocking.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Like findAsync but blocks on everything but the constant's body (if any), which is not accessible
through the result.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Like findAsync?, but blocks until the constant's info is fully available.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Allows realizeConst calls for the given declaration in all derived environment branches.
Realizations will run using the given environment and options to ensure deterministic results. Note
that while we check that the function isn't called before the declaration is actually added to the
environment, we cannot automatically check that it isn't otherwise called too early in the sense
that helper declarations and environment extension state that may be relevant to realizations may
not have been added yet. We do check that we are not calling it from a different branch than c was
added on, which would be definitely too late. Thus, this function should generally be called in
elaborators calling addDecl (when that declaration is a plausible target for realization) at the
latest possible point, i.e. at the very end of the elaborator or just before a first realization may
be triggered if any.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- env.areRealizationsEnabledForConst c = ((Lean.VisibilityMap.get✝ (Lean.Environment.base✝ env) env).const2ModIdx.contains c || (Lean.Environment.localRealizationCtxMap✝ env).contains c)
Instances For
Returns debug output about the asynchronous state of the environment.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Returns debug output about the synchronous state of the environment.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Result of Lean.Environment.promiseChecked.
- mainEnv : Environment
Resulting "main branch" environment. Accessing the kernel environment will block until
PromiseCheckedResult.commitCheckedhas been called. - asyncEnv : Environment
Resulting "async branch" environment which should be used in a new task and then to call
PromiseCheckedResult.commitCheckedto commit results back to the main environment. If it is not called and thePromiseCheckedResultobject is dropped, the kernel environment will be left unchanged. - checkedEnvPromise : IO.Promise Lean.Kernel.Environment
Instances For
Equations
- env.realizingStack = (Option.map (fun (x : Lean.AsyncContext✝) => Lean.AsyncContext.realizingStack✝ x) (Lean.Environment.asyncCtx?✝ env)).getD []
Instances For
Starts an asynchronous modification of the kernel environment. The environment is split into a
"main" branch that will block on access to the kernel environment until
PromiseCheckedResult.commitChecked has been called on the "async" environment branch.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Commits the kernel environment of the given environment back to the main branch.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Result of Lean.Environment.addConstAsync which is necessary to complete the asynchronous addition.
- mainEnv : Environment
Resulting "main branch" environment which contains the declaration name as an asynchronous constant. Accessing the constant or kernel environment will block until the corresponding
AddConstAsyncResult.commit*function has been called. - asyncEnv : Environment
Resulting "async branch" environment which should be used to add the desired declaration in a new task and then call
AddConstAsyncResult.commit*to commit results back to the main environment.commitCheckEnvcompletes the addition; if it is not called and theAddConstAsyncResultobject is dropped,sorryed default values will be reported instead and the kernel environment will be left unchanged. - constName : Lean.Name
- kind : Lean.ConstantKind
- exportedKind? : Option Lean.ConstantKind
- sigPromise : IO.Promise Lean.ConstantVal
- constPromise : IO.Promise Lean.Environment.ConstPromiseVal✝
- checkedEnvPromise : IO.Promise Lean.Kernel.Environment
- allRealizationsPromise : IO.Promise (Lean.NameMap Lean.AsyncConst✝)
Instances For
Starts the asynchronous addition of a constant to the environment. The environment is split into a
"main" branch that holds a reference to the constant to be added but will block on access until the
corresponding information has been added on the "async" environment branch and committed there; see
the respective fields of AddConstAsyncResult as well as the [Environment Branches] note for more
information.
exportedKind? must be passed if the eventual kind of the constant in the exported constant map
will differ from that of the private version. It must be none if the constant will not be
exported.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Commits the signature of the constant to the main environment branch. The declaration name must
match the name originally given to addConstAsync. It is optional to call this function but can
help in unblocking corresponding accesses to the constant on the main branch.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Commits the full constant info as well as the current environment extension state and set of nested
asynchronous constants to the main environment branch. If info? is none, it is taken from the
given environment. The declaration name and kind must match the original values given to
addConstAsync. The signature must match the previous commitSignature call, if any.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Assuming Lean.addDecl has been run for the constant to be added on the async environment branch,
commits the full constant info from that call to the main environment, (asynchronously) waits for
the final kernel environment resulting from the addDecl call, and commits it to the main branch as
well, unblocking kernel additions there. All commitConst preconditions apply.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Checks whether findAsync? would return a result.
NOTE: Unlike findAsync, this function defaults skipRealize to true to avoid unnecessary
blocking on realizations, which should always be brought into scope by running realizeConst, which
does its own, optimized existence check.
Equations
- env.contains n skipRealize = (env.findAsync? n skipRealize).isSome
Instances For
Checks whether the given declaration is known on the current branch, in which case findAsync? will
not block.
Equations
- env.containsOnBranch n = ((Lean.AsyncConsts.find?✝ (Lean.Environment.asyncConsts✝ env) n).isSome || Lean.SMap.contains (Lean.VisibilityMap.get✝ (Lean.Environment.base✝ env) env).constants n)
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- env.mainModule = env.header.mainModule
Instances For
Equations
- env.getModuleIdxFor? declName = (Lean.VisibilityMap.get✝ (Lean.Environment.base✝ env) env).const2ModIdx[declName]?
Instances For
Equations
- env.isImportedConst declName = (env.getModuleIdxFor? declName).isSome
Instances For
Equations
- env.isConstructor declName = Option.any (fun (x : Lean.AsyncConstantInfo) => x.kind == Lean.ConstantKind.ctor) (env.findAsync? declName)
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- env.getModuleIdx? moduleName = Array.findIdx? (fun (x : Lean.EffectiveImport) => x.module == moduleName) env.header.modules
Instances For
Equations
- c.instantiateTypeLevelParams ls = c.type.instantiateLevelParams c.levelParams ls
Instances For
Equations
Instances For
Equations
Instances For
Branch specification for asynchronous environment extension access.
Note: For declarations not created via addConstAsync, including those created via realizeConst,
the two specifiers are equivalent.
- mainEnv : AsyncBranch
The main branch that initiated adding a declaration, i.e.
AddConstAsyncResult.mainEnv.This is the more common case and true for e.g. all accesses from attributes.
- asyncEnv : AsyncBranch
The async branch that finished adding a declaration, i.e.
AddConstAsyncResult.asyncEnv.
Instances For
Equations
Equations
- Lean.instBEqAsyncBranch.beq x✝ y✝ = (x✝.ctorIdx == y✝.ctorIdx)
Instances For
Async access mode for environment extensions used in EnvExtension.get/set/modifyState.
When modified in concurrent contexts, extensions may need to switch to a different mode than the
default mainOnly, which will panic in such cases. The access mode is set at environment extension
registration time but can be overridden when calling the mentioned functions in order to weaken it
for specific accesses.
In all modes, the state stored into the .olean file for persistent environment extensions is the
result of getState (asyncMode := .sync) called on the main environment branch at the end of the
file, i.e. it encompasses all modifications on all branches except for local modifications for
which only the main branch is included.
- sync : AsyncMode
Safest access mode, writes and reads the extension state to/from the full
checkedenvironment. This mode ensures the observed state is identical independently of whether or how parallel elaboration is used butgetStatewill block on all prior environment branches by waiting forchecked.setStateandmodifyStatedo not block.While a safe fallback for when
mainOnlyis not sufficient, any extension that reasonably could be used in parallel elaboration contexts should opt for a weaker mode to avoid blocking unless there is no way to access the correct state without waiting for all prior environment branches, in which case its data management should be restructured if at all possible. - local : AsyncMode
Accesses only the state of the current environment branch. Modifications on other branches are not visible and are ultimately discarded except for the main branch. Provides the fastest accessors, will never block.
This mode is particularly suitable for extensions where state does not escape from lexical scopes even without parallelism, e.g.
ScopedEnvExtensions when setting local entries. - mainOnly : AsyncMode
Default access mode. Like
localbut panics when trying to modify the state on anything but the main environment branch. For extensions that fulfill this requirement, all modes functionally coincide withlocalbut this is the safest and most efficient choice in that case, preventing accidental misuse.This mode is suitable for extensions that are modified only at the command elaboration level before any environment forks in the command, and in particular for extensions that are modified only at the very beginning of the file.
- async
(branch : AsyncBranch)
: AsyncMode
Accumulates modifications in the
checkedenvironment likesync, butget/modify/setStatewill panic instead of blocking unless theirasyncDeclparameter is specified, which will access the state of the environment branch corresponding to the passed declaration name, if any; seeAsyncBranchfor a description of the specific state accessed. In other words, at most the environment branch corresponding to that declaration will be blocked on instead of all prior branches. The local state can still be accessed by callinggetStatewith modelocalexplicitly.This mode is suitable for extensions with map-like state where the key uniquely identifies the top-level declaration where it could have been set, e.g. because the key on modification is always the surrounding declaration's name. In particular, this mode is closest to how the environment's own constant map works which provides
findAsync?for block-avoiding access.
Instances For
Environment extension, can only be generated by registerEnvExtension that allocates a unique index
for this extension into each environment's extension state's array.
- idx : Nat
- mkInitial : IO σ
- asyncMode : AsyncMode
Optional function that, given state before and after realization and newly added constants, replays this change onto a state from another (derived) environment. This function is used only when making changes to an extension inside a
realizeConstcall, in which case it must be present.
Instances For
Equations
Equations
Instances For
User-defined environment extensions are declared using the initialize command.
This command is just syntax sugar for the init attribute.
When we import lean modules, the vector stored at envExtensionsRef may increase in size because of
user-defined environment extensions. When this happens, we must adjust the size of the env.extensions.
This method is invoked when processing imports.
Equations
Instances For
Equations
- Lean.EnvExtension.mkInitialExtStates = do let exts ← ST.Ref.get Lean.EnvExtension.envExtensionsRef✝ Array.mapM (fun (ext : Lean.EnvExtension Lean.EnvExtensionState) => ext.mkInitial) exts
Instances For
Checks whether modifyState (asyncDecl := declName) may be called on an async environment
extension; see AsyncMode.async for details.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Applies the given function to the extension state. See AsyncMode for details on how modifications
from different environment branches are reconciled.
Note that in modes sync and async, f will be called twice, on the local and on the checked
state.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Sets the extension state to the given value. See AsyncMode for details on how modifications from
different environment branches are reconciled.
Equations
- ext.setState env s asyncMode = inline (ext.modifyState env (fun (x : σ) => s) asyncMode)
Instances For
Returns the current extension state. See AsyncMode for details on how modifications from
different environment branches are reconciled.
Overriding the extension's default AsyncMode is usually not recommended and should be considered
only for important optimizations.
Environment extensions can only be registered during initialization.
Reasons:
1- Our implementation assumes the number of extensions does not change after an environment object is created.
2- We do not use any synchronization primitive to access envExtensionsRef.
Note that by default, extension state is not stored in .olean files and will not propagate across imports.
For that, you need to register a persistent environment extension.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Instances For
The level of information to save/load. Each level includes all previous ones.
- exported : OLeanLevel
Information from exported contexts.
- server : OLeanLevel
Environment extension state for the language server.
- private : OLeanLevel
Private module data.
Instances For
Equations
- Lean.instOrdOLeanLevel = { compare := Lean.instOrdOLeanLevel.ord }
Equations
- Lean.instOrdOLeanLevel.ord Lean.OLeanLevel.exported Lean.OLeanLevel.exported = Ordering.eq
- Lean.instOrdOLeanLevel.ord Lean.OLeanLevel.exported x✝ = Ordering.lt
- Lean.instOrdOLeanLevel.ord x Lean.OLeanLevel.exported = Ordering.gt
- Lean.instOrdOLeanLevel.ord Lean.OLeanLevel.server Lean.OLeanLevel.server = Ordering.eq
- Lean.instOrdOLeanLevel.ord Lean.OLeanLevel.server x✝ = Ordering.lt
- Lean.instOrdOLeanLevel.ord x Lean.OLeanLevel.server = Ordering.gt
- Lean.instOrdOLeanLevel.ord Lean.OLeanLevel.private Lean.OLeanLevel.private = Ordering.eq
Instances For
Equations
- Lean.instReprOLeanLevel.repr Lean.OLeanLevel.exported prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.OLeanLevel.exported")).group prec✝
- Lean.instReprOLeanLevel.repr Lean.OLeanLevel.server prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.OLeanLevel.server")).group prec✝
- Lean.instReprOLeanLevel.repr Lean.OLeanLevel.private prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "Lean.OLeanLevel.private")).group prec✝
Instances For
Equations
- Lean.instReprOLeanLevel = { reprPrec := Lean.instReprOLeanLevel.repr }
An environment extension with support for storing/retrieving entries from a .olean file.
- α is the type of the entries that are stored in .olean files.
- β is the type of values used to update the state.
- σ is the actual state.
For most extensions, α and β coincide. α and β do not coincide for extensions where the data
used to update the state contains elements which cannot be stored in files (for example, closures).
During elaboration of a module, state of type σ can be both read and written. When elaboration is
complete, the state of type σ is converted to serialized state of type Array α by
exportEntriesFn. To read the current module's state, use PersistentEnvExtension.getState. To
modify it, use PersistentEnvExtension.addEntry, with an addEntryFn that performs the appropriate
modification.
When a module is loaded, the values saved by all of its dependencies for this
PersistentEnvExtension are available as an Array (Array α) via the environment extension,
with one array per transitively imported module. The state of type σ used in the current module
can be initialized from these imports by specifying a suitable addImportedFn. The addImportedFn
runs at the beginning of elaboration for every module, so it's usually better for performance to
query the array of imported modules directly, because only a fraction of imported entries is usually
queried during elaboration of a module.
The most typical pattern for using PersistentEnvExtension is to set σ to a datatype such as
NameMap that efficiently tracks data for the current module. Then, in exportEntriesFn, this type
is converted to an array of pairs, sorted by the key. Given ext : PersistentEnvExtension α β σ and
env : Environment, the complete array of imported entries sorted by module index can be obtained
using (ext.toEnvExtension.getState env).importedEntries. To query the extension for some constant
name n, first use env.getModuleIdxFor? n. If it returns none, look up n in the current
module's state (the NameMap). If it returns some idx, use ext.getModuleEntries env idx to get
the array of entries for n's defining module, and query it using Array.binSearch. This pattern
imposes a constraint that the extension can only track metadata that is declared in the same module
as the definition to which it applies; relaxing this restriction can make queries slower due to
needing to search all modules. If it is necessary to search all modules, it is usually better to
initialize the state of type σ once from all imported entries and choose a more efficient search
datastructure for it.
Note that addEntryFn is not in IO. This is intentional, and allows us to write simple functions
such as
def addAlias (env : Environment) (a : Name) (e : Name) : Environment :=
aliasExtension.addEntry env (a, e)
without using IO. We have many functions like addAlias.
- toEnvExtension : EnvExtension (PersistentEnvExtensionState α σ)
- name : Name
- addEntryFn : σ → β → σ
- exportEntriesFn : Environment → σ → OLeanLevel → Array α
Function to transform state into data that should be imported into other modules. When using the module system without
import all,OLeanLevel.exportedis imported, elseOLeanLevel.private. Additionally, when using the module system in the language server, theOLeanLevel.serverdata is accessible viagetModuleEntries (level := .server). By convention, each level should include all data of previous levels.This function is run after elaborating the file and joining all asynchronous threads. It is run once for each level when the module system is enabled, otherwise once for
private. - statsFn : σ → Format
Instances For
Equations
- One or more equations did not get rendered due to their size.
Returns the data saved by ext.exportEntriesFn when m was elaborated. See docs on the function for
details. When using the module system, level can be used to select the level of data to retrieve,
but is limited to the maximum level actually imported: exported on the cmdline and server in the
language server. Higher levels will return the data of the maximum imported level.
Equations
- ext.getModuleEntries env m = Lean.PersistentEnvExtension.getModuleEntries.unsafe_impl_3✝ ext m (Lean.Kernel.Environment.extensions✝ (Lean.VisibilityMap.private✝ (Lean.Environment.base✝ env)))
- ext.getModuleEntries env m level = Lean.PersistentEnvExtension.getModuleEntries.unsafe_impl_3✝ ext m (Lean.Environment.serverBaseExts✝ env)
Instances For
Retrieves additional IR extension state for the interpreter.
Equations
- ext.getModuleIREntries env m = Lean.PersistentEnvExtension.getModuleIREntries.unsafe_impl_3✝ ext env m
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Get the current state of the given extension in the given environment.
Equations
- ext.getState env asyncMode asyncDecl = (ext.toEnvExtension.getState env asyncMode asyncDecl).state
Instances For
Set the current state of the given extension in the given environment.
Equations
- ext.setState env s = ext.toEnvExtension.modifyState env fun (ps : Lean.PersistentEnvExtensionState α σ) => { importedEntries := ps.importedEntries, state := s }
Instances For
Modify the state of the given extension in the given environment by applying the given function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
- name : Name
- mkInitial : IO σ
- addEntryFn : σ → β → σ
- exportEntriesFnEx : Environment → σ → OLeanLevel → Array α
Function to transform state into data that should be imported into other modules. When using the module system without
import all,OLeanLevel.exportedis imported, elseOLeanLevel.private. Additionally, when using the module system in the language server, theOLeanLevel.serverdata is accessible viagetModuleEntries (level := .server). By convention, each level should include all data of previous levels.This function is run after elaborating the file and joining all asynchronous threads. It is run once for each level when the module system is enabled, otherwise once for
private. - statsFn : σ → Format
- asyncMode : EnvExtension.AsyncMode
Instances For
Auxiliary function to signal to the structure instance elaborator that default should be used as
the default value for a field but only if _otherField has been given, which is added as an
artificial dependency.
Equations
- Lean.useDefaultIfOtherFieldGiven default _otherField = default
Instances For
- addImportedFn : Array (Array α) → ImportM σ
- addEntryFn : σ → β → σ
- exportEntriesFnEx : Environment → σ → OLeanLevel → Array α
- exportEntriesFn : σ → Array α
Obsolete simpler version of
exportEntriesFnEx. Its value is ignored if the latter is also specified.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Stores each given module data in the respective file name. Objects shared with prior parts are not
duplicated. Thus the data cannot be loaded with individual readModuleData calls but must loaded by
passing (a prefix of) the file names to readModuleDataParts. mod is used to determine an
arbitrary but deterministic base address for mmap.
Loads the module data from the given file names. The files must be (a prefix of) the result of a
saveModuleDataParts call.
Equations
- Lean.saveModuleData fname mod data = Lean.saveModuleDataParts mod #[(fname, data)]
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Free compacted regions of imports. No live references to imported objects may exist at the time of invocation; in
particular, env should be the last reference to any Environment derived from these imports.
Equations
Instances For
Equations
- Lean.OLeanLevel.adjustFileName base Lean.OLeanLevel.exported = base
- Lean.OLeanLevel.adjustFileName base Lean.OLeanLevel.server = base.addExtension "server"
- Lean.OLeanLevel.adjustFileName base Lean.OLeanLevel.private = base.addExtension "private"
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Construct a mapping from persistent extension name to extension index at the array of persistent extensions.
We only consider extensions starting with index >= startingAt.
Equations
- One or more equations did not get rendered due to their size.
Instances For
"Forward declaration" needed for updating the attribute table with user-defined attributes.
User-defined attributes are declared using the initialize command. The initialize command is just syntax sugar for the init attribute.
The init attribute is initialized after the attributeExtension is initialized. We cannot change the order since the init attribute is an attribute,
and requires this extension.
The attributeExtension initializer uses attributeMapRef to initialize the attribute mapping.
When we a new user-defined attribute declaration is imported, attributeMapRef is updated.
Later, we set this method with code that adds the user-defined attributes that were imported after we initialized attributeExtension.
"Forward declaration" for retrieving the number of builtin attributes.
- moduleNameMap : Std.HashMap Lean.Name Lean.ImportedModule✝
Instances For
Equations
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Equations
- x.run s = StateRefT'.run x s
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Constructs environment from importModulesCore results.
See also importModules for parameter documentation.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Creates environment object from given imports.
If leakEnv is true, we mark the environment as persistent, which means it will not be freed. We
set this when the object would survive until the end of the process anyway. In exchange, RC updates
are avoided, which is especially important when they would be atomic because the environment is
shared across threads (potentially, storing it in an IO.Ref is sufficient for marking it as such).
If loadExts is true, we initialize the environment extensions using the imported data. Doing so
may use the interpreter and thus is only safe to do after calling enableInitializersExecution; see
also caveats there. If not set, every extension will have its initial value as its state. While the
environment's constant map can be accessed without loadExts, many functions that take
Environment or are in a monad carrying it such as CoreM may not function properly without it.
If level is exported, the module to be elaborated is assumed to be participating in the module
system and imports will be restricted accordingly. If it is server, the data for
getModuleEntries (includeServer := true) is loaded as well. If it is private, all data is loaded
as if no module annotations were present in the imports.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Creates environment object from imports and frees compacted regions after calling act. No live
references to the environment object or imported objects may exist after act finishes. As this
cannot be ruled out after loading environment extensions, importModules's loadExts is always
unset using this function.
Equations
- Lean.withImportModules imports opts act trustLevel = do let env ← Lean.importModules imports opts trustLevel tryFinally (act env) env.freeRegions
Instances For
Enables/disables kernel diagnostics.
Equations
- Lean.Kernel.enableDiag env flag = Lean.Environment.modifyCheckedAsync✝ env fun (x : Lean.Kernel.Environment) => x.enableDiag flag
Instances For
Equations
Instances For
Equations
- Lean.Kernel.resetDiag env = Lean.Environment.modifyCheckedAsync✝ env fun (x : Lean.Kernel.Environment) => x.resetDiag
Instances For
Equations
- Lean.Kernel.getDiagnostics env = env.checked.get.diagnostics
Instances For
Equations
- Lean.Kernel.setDiagnostics env diag = Lean.Environment.modifyCheckedAsync✝ env fun (x : Lean.Kernel.Environment) => x.setDiagnostics diag
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Evaluates the given declaration under the given environment to a value of the given type.
This function is only safe to use if the type matches the declaration's type in the environment
and if enableInitializersExecution has been used before importing any modules.
If checkMeta is true (the default), the function checks that the constant is declared or imported
as meta or otherwise fails with an error. It should only be set to false in cases where it is
acceptable for code to work only in the language server, where more IR is loaded, such as in
#eval.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Replays the difference between newEnv and oldEnv onto dest: the set of constants in newEnv
but not oldEnv and the environment extension state for extensions defining replay?. If
skipExisting is true, constants that are already in dest are not added. If newEnv and dest
are not derived from oldEnv, the result is undefined.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Like evalConst, but first check that constName indeed is a declaration of type typeName.
Note that this function cannot guarantee that typeName is in fact the name of the type α.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Plumbing function for Lean.Meta.realizeValue; see documentation there.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Plumbing function for Lean.Meta.realizeConst; see documentation there.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Kernel API #
Kernel isDefEq predicate. 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.
Equations
- Lean.Kernel.isDefEqGuarded env lctx a b = match Lean.Kernel.isDefEq env lctx a b with | Except.ok result => result | x => false
Instances For
Kernel WHNF 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.
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.
- getEnv : m Environment
- modifyEnv : (Environment → Environment) → m Unit
Instances
Returns the module name of the current file.
Equations
- Lean.getMainModule = do let __do_lift ← Lean.getEnv pure __do_lift.header.mainModule
Instances For
Equations
- Lean.instMonadEnvOfMonadLift m n = { getEnv := liftM Lean.getEnv, modifyEnv := fun (f : Lean.Environment → Lean.Environment) => liftM (Lean.modifyEnv f) }
Sets Environment.isExporting to the given value while executing x. No-op if
EnvironmentHeader.isModule is false.
Equations
- One or more equations did not get rendered due to their size.
Instances For
If when is true, sets Environment.isExporting to false while executing x.
Equations
- Lean.withoutExporting x when = if when = true then Lean.withExporting x false else x
Instances For
Constructs a DefinitionVal, inferring the unsafe field
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.