lean4-htt/src/Lean/MonadEnv.lean
2020-09-25 06:48:51 -07:00

135 lines
4.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Environment
import Lean.Exception
namespace Lean
section Methods
variables {m : Type → Type} [MonadEnv m]
def setEnv (env : Environment) : m Unit :=
modifyEnv fun _ => env
@[inline] def withoutModifyingEnv [Monad m] [MonadFinally m] {α : Type} (x : m α) : m α := do
env ← getEnv;
finally x (setEnv env)
@[inline] def matchConst [Monad m] {α : Type} (e : Expr) (failK : Unit → m α) (k : ConstantInfo → List Level → m α) : m α := do
match e with
| Expr.const constName us _ => do
env ← getEnv;
match env.find? constName with
| some cinfo => k cinfo us
| none => failK ()
| _ => failK ()
@[inline] def matchConstInduct [Monad m] {α : Type} (e : Expr) (failK : Unit → m α) (k : InductiveVal → List Level → m α) : m α :=
matchConst e failK fun cinfo us =>
match cinfo with
| ConstantInfo.inductInfo val => k val us
| _ => failK ()
@[inline] def matchConstCtor [Monad m] {α : Type} (e : Expr) (failK : Unit → m α) (k : ConstructorVal → List Level → m α) : m α :=
matchConst e failK fun cinfo us =>
match cinfo with
| ConstantInfo.ctorInfo val => k val us
| _ => failK ()
@[inline] def matchConstRec [Monad m] {α : Type} (e : Expr) (failK : Unit → m α) (k : RecursorVal → List Level → m α) : m α :=
matchConst e failK fun cinfo us =>
match cinfo with
| ConstantInfo.recInfo val => k val us
| _ => failK ()
section
variables [Monad m]
def hasConst (constName : Name) : m Bool := do
env ← getEnv;
pure $ env.contains constName
private partial def mkAuxNameAux (env : Environment) (base : Name) : Nat → Name
| i =>
let candidate := base.appendIndexAfter i;
if env.contains candidate then
mkAuxNameAux (i+1)
else
candidate
def mkAuxName (baseName : Name) (idx : Nat) : m Name := do
env ← getEnv;
pure $ mkAuxNameAux env baseName idx
variables [MonadExceptOf Exception m] [Ref m] [AddErrorMessageContext m]
def getConstInfo (constName : Name) : m ConstantInfo := do
env ← getEnv;
match env.find? constName with
| some info => pure info
| none => throwError ("unknown constant '" ++ constName ++ "'")
def getConstInfoInduct (constName : Name) : m InductiveVal := do
info ← getConstInfo constName;
match info with
| ConstantInfo.inductInfo v => pure v
| _ => throwError ("'" ++ constName ++ "' is not a inductive type")
def getConstInfoCtor (constName : Name) : m ConstructorVal := do
info ← getConstInfo constName;
match info with
| ConstantInfo.ctorInfo v => pure v
| _ => throwError ("'" ++ constName ++ "' is not a constructor")
def getConstInfoRec (constName : Name) : m RecursorVal := do
info ← getConstInfo constName;
match info with
| ConstantInfo.recInfo v => pure v
| _ => throwError ("'" ++ constName ++ "' is not a recursor")
@[inline] def matchConstStruct {α : Type} (e : Expr) (failK : Unit → m α) (k : InductiveVal → List Level → ConstructorVal → m α) : m α :=
matchConstInduct e failK fun ival us =>
if ival.isRec then failK ()
else match ival.ctors with
| [ctor] => do
ctorInfo ← getConstInfo ctor;
match ctorInfo with
| ConstantInfo.ctorInfo cval => k ival us cval
| _ => failK ()
| _ => failK ()
def addDecl [MonadOptions m] (decl : Declaration) : m Unit := do
env ← getEnv;
match env.addDecl decl with
| Except.ok env => setEnv env
| Except.error ex => throwKernelException ex
def compileDecl [MonadOptions m] (decl : Declaration) : m Unit := do
env ← getEnv;
opts ← getOptions;
match env.compileDecl opts decl with
| Except.ok env => setEnv env
| Except.error ex => throwKernelException ex
def addAndCompile [MonadOptions m] (decl : Declaration) : m Unit := do
addDecl decl;
compileDecl decl
variables [MonadExceptOf Exception m] [Ref m] [AddErrorMessageContext m]
unsafe def evalConst (α) (constName : Name) : m α := do
env ← getEnv;
ofExcept $ env.evalConst α constName
unsafe def evalConstCheck (α) (typeName : Name) (constName : Name) : m α := do
env ← getEnv;
ofExcept $ env.evalConstCheck α typeName constName
end
end Methods
end Lean