module Language.Lean.Env
( Env
, TrustLevel
, trustHigh
, standardEnv
, hottEnv
, envAddUniv
, envAddDecl
, envReplaceAxiom
, envTrustLevel
, envContainsProofIrrelProp
, envIsImpredicative
, envContainsDecl
, envLookupDecl
, envContainsUniv
, envIsDescendant
, envForget
, envDecls
, forEnvDecl_
, envUnivs
, forEnvUniv_
) where
import Control.Exception (bracket)
import Control.Lens
import Control.Monad
import Data.IORef
import Foreign
import Foreign.C
import System.IO.Unsafe
import Language.Lean.Internal.Decl
import Language.Lean.Internal.Exception
import Language.Lean.Internal.Exception.Unsafe
import Language.Lean.Internal.Name
type WrapLeanVisitFn p = (p -> IO ()) -> IO (FunPtr (p -> IO ()))
type LeanFoldFn s p = s -> FunPtr (p -> IO ()) -> OutExceptionPtr -> IO Bool
runLeanFold :: IsLeanValue a p
=> WrapLeanVisitFn p
-> LeanFoldFn s p
-> Fold s a
runLeanFold wrapFn foldFn h e = unsafePerformIO $ do
ref <- newIORef $! (coerce $! pure ())
let g d_ptr = do
d <- mkLeanValue d_ptr
cur_val <- readIORef ref
let hd = h d
let chd = coerce hd
seq hd $ seq chd $ do
writeIORef ref $! cur_val *> chd
bracket (wrapFn g) freeHaskellFunPtr $ \g_ptr -> do
alloca $ \ex_ptr -> do
success <- foldFn e g_ptr ex_ptr
if success then
readIORef ref
else
throwLeanException =<< peek ex_ptr
safeRunLeanFold :: IsLeanValue a p
=> WrapLeanVisitFn p
-> LeanFoldFn s p
-> (a -> IO ())
-> (s -> IO ())
safeRunLeanFold wrapFn foldFn f s = do
let g = mkLeanValue >=> f
bracket (wrapFn g) freeHaskellFunPtr $ \g_ptr -> do
alloca $ \ex_ptr -> do
success <- foldFn s g_ptr ex_ptr
unless success $ do
throwLeanException =<< peek ex_ptr
newtype TrustLevel = TrustLevel { _trustValue :: Word32 }
deriving (Eq, Ord, Num, Show)
trustFromUInt :: CUInt -> TrustLevel
trustFromUInt = TrustLevel . fromIntegral
trustUInt :: TrustLevel -> CUInt
trustUInt (TrustLevel u) = fromIntegral u
trustHigh :: TrustLevel
trustHigh = TrustLevel 100000
standardEnv :: TrustLevel -> Env
standardEnv lvl = tryGetLeanValue $ lean_env_mk_std lvl
lean_env_mk_std :: (TrustLevel) -> (OutEnvPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_mk_std a1 a2 a3 =
let {a1' = trustUInt a1} in
let {a2' = id a2} in
let {a3' = id a3} in
lean_env_mk_std'_ a1' a2' a3' >>= \res ->
let {res' = toBool res} in
return (res')
hottEnv :: TrustLevel -> Env
hottEnv lvl = tryGetLeanValue $ lean_env_mk_hott lvl
lean_env_mk_hott :: (TrustLevel) -> (OutEnvPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_mk_hott a1 a2 a3 =
let {a1' = trustUInt a1} in
let {a2' = id a2} in
let {a3' = id a3} in
lean_env_mk_hott'_ a1' a2' a3' >>= \res ->
let {res' = toBool res} in
return (res')
envAddUniv :: Name -> Env -> Env
envAddUniv u e = tryGetLeanValue $ lean_env_add_univ e u
lean_env_add_univ :: (Env) -> (Name) -> (OutEnvPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_add_univ a1 a2 a3 a4 =
(withEnv) a1 $ \a1' ->
(withName) a2 $ \a2' ->
let {a3' = id a3} in
let {a4' = id a4} in
lean_env_add_univ'_ a1' a2' a3' a4' >>= \res ->
let {res' = toBool res} in
return (res')
envAddDecl :: CertDecl -> Env -> Env
envAddDecl d e = tryGetLeanValue $ lean_env_add e d
lean_env_add :: (Env) -> (CertDecl) -> (OutEnvPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_add a1 a2 a3 a4 =
(withEnv) a1 $ \a1' ->
(withCertDecl) a2 $ \a2' ->
let {a3' = id a3} in
let {a4' = id a4} in
lean_env_add'_ a1' a2' a3' a4' >>= \res ->
let {res' = toBool res} in
return (res')
envReplaceAxiom :: CertDecl -> Env -> Env
envReplaceAxiom d e = tryGetLeanValue $ lean_env_replace e d
lean_env_replace :: (Env) -> (CertDecl) -> (OutEnvPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_replace a1 a2 a3 a4 =
(withEnv) a1 $ \a1' ->
(withCertDecl) a2 $ \a2' ->
let {a3' = id a3} in
let {a4' = id a4} in
lean_env_replace'_ a1' a2' a3' a4' >>= \res ->
let {res' = toBool res} in
return (res')
envTrustLevel :: Env -> TrustLevel
envTrustLevel = lean_env_trust_level
lean_env_trust_level :: (Env) -> (TrustLevel)
lean_env_trust_level a1 =
unsafePerformIO $
(withEnv) a1 $ \a1' ->
let {res = lean_env_trust_level'_ a1'} in
let {res' = trustFromUInt res} in
return (res')
envContainsProofIrrelProp :: (Env) -> (Bool)
envContainsProofIrrelProp a1 =
unsafePerformIO $
(withEnv) a1 $ \a1' ->
let {res = envContainsProofIrrelProp'_ a1'} in
let {res' = toBool res} in
return (res')
envIsImpredicative :: (Env) -> (Bool)
envIsImpredicative a1 =
unsafePerformIO $
(withEnv) a1 $ \a1' ->
let {res = envIsImpredicative'_ a1'} in
let {res' = toBool res} in
return (res')
envContainsUniv :: (Env) -> (Name) -> (Bool)
envContainsUniv a1 a2 =
unsafePerformIO $
(withEnv) a1 $ \a1' ->
(withName) a2 $ \a2' ->
let {res = envContainsUniv'_ a1' a2'} in
let {res' = toBool res} in
return (res')
envContainsDecl :: (Env) -> (Name) -> (Bool)
envContainsDecl a1 a2 =
unsafePerformIO $
(withEnv) a1 $ \a1' ->
(withName) a2 $ \a2' ->
let {res = envContainsDecl'_ a1' a2'} in
let {res' = toBool res} in
return (res')
envLookupDecl :: Name -> Env -> Maybe Decl
envLookupDecl nm e =
if envContainsDecl e nm then
Just (tryGetLeanValue $ lean_env_get_decl e nm)
else
Nothing
lean_env_get_decl :: (Env) -> (Name) -> (OutDeclPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_get_decl a1 a2 a3 a4 =
(withEnv) a1 $ \a1' ->
(withName) a2 $ \a2' ->
let {a3' = id a3} in
let {a4' = id a4} in
lean_env_get_decl'_ a1' a2' a3' a4' >>= \res ->
let {res' = toBool res} in
return (res')
envIsDescendant :: Env -> Env -> Bool
envIsDescendant = lean_env_is_descendant
lean_env_is_descendant :: (Env) -> (Env) -> (Bool)
lean_env_is_descendant a1 a2 =
unsafePerformIO $
(withEnv) a1 $ \a1' ->
(withEnv) a2 $ \a2' ->
let {res = lean_env_is_descendant'_ a1' a2'} in
let {res' = toBool res} in
return (res')
envForget :: Env -> Env
envForget x = tryGetLeanValue $ lean_env_forget x
lean_env_forget :: (Env) -> (OutEnvPtr) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_forget a1 a2 a3 =
(withEnv) a1 $ \a1' ->
let {a2' = id a2} in
let {a3' = id a3} in
lean_env_forget'_ a1' a2' a3' >>= \res ->
let {res' = toBool res} in
return (res')
envDecls :: Fold Env Decl
envDecls = runLeanFold wrapDeclVisitFn lean_env_for_each_decl
forEnvDecl_ :: Env -> (Decl -> IO ()) -> IO ()
forEnvDecl_ e f = safeRunLeanFold wrapDeclVisitFn lean_env_for_each_decl f e
foreign import ccall "wrapper" wrapDeclVisitFn :: WrapLeanVisitFn DeclPtr
lean_env_for_each_decl :: (Env) -> (FunPtr (DeclPtr -> IO ())) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_for_each_decl a1 a2 a3 =
(withEnv) a1 $ \a1' ->
let {a2' = id a2} in
let {a3' = id a3} in
lean_env_for_each_decl'_ a1' a2' a3' >>= \res ->
let {res' = toBool res} in
return (res')
envUnivs :: Fold Env Name
envUnivs = runLeanFold wrapNameVisitFn lean_env_for_each_univ
forEnvUniv_ :: Env -> (Name -> IO ()) -> IO ()
forEnvUniv_ e f = safeRunLeanFold wrapNameVisitFn lean_env_for_each_univ f e
foreign import ccall "wrapper" wrapNameVisitFn :: WrapLeanVisitFn NamePtr
lean_env_for_each_univ :: (Env) -> (FunPtr (NamePtr -> IO ())) -> (OutExceptionPtr) -> IO ((Bool))
lean_env_for_each_univ a1 a2 a3 =
(withEnv) a1 $ \a1' ->
let {a2' = id a2} in
let {a3' = id a3} in
lean_env_for_each_univ'_ a1' a2' a3' >>= \res ->
let {res' = toBool res} in
return (res')
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_mk_std"
lean_env_mk_std'_ :: (CUInt -> ((OutEnvPtr) -> ((OutExceptionPtr) -> (IO CInt))))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_mk_hott"
lean_env_mk_hott'_ :: (CUInt -> ((OutEnvPtr) -> ((OutExceptionPtr) -> (IO CInt))))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_add_univ"
lean_env_add_univ'_ :: ((EnvPtr) -> ((NamePtr) -> ((OutEnvPtr) -> ((OutExceptionPtr) -> (IO CInt)))))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_add"
lean_env_add'_ :: ((EnvPtr) -> ((CertDeclPtr) -> ((OutEnvPtr) -> ((OutExceptionPtr) -> (IO CInt)))))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_replace"
lean_env_replace'_ :: ((EnvPtr) -> ((CertDeclPtr) -> ((OutEnvPtr) -> ((OutExceptionPtr) -> (IO CInt)))))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_trust_level"
lean_env_trust_level'_ :: ((EnvPtr) -> CUInt)
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_proof_irrel"
envContainsProofIrrelProp'_ :: ((EnvPtr) -> CInt)
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_impredicative"
envIsImpredicative'_ :: ((EnvPtr) -> CInt)
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_contains_univ"
envContainsUniv'_ :: ((EnvPtr) -> ((NamePtr) -> CInt))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_contains_decl"
envContainsDecl'_ :: ((EnvPtr) -> ((NamePtr) -> CInt))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_get_decl"
lean_env_get_decl'_ :: ((EnvPtr) -> ((NamePtr) -> ((OutDeclPtr) -> ((OutExceptionPtr) -> (IO CInt)))))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_is_descendant"
lean_env_is_descendant'_ :: ((EnvPtr) -> ((EnvPtr) -> CInt))
foreign import ccall unsafe "Language/Lean/Env.chs.h lean_env_forget"
lean_env_forget'_ :: ((EnvPtr) -> ((OutEnvPtr) -> ((OutExceptionPtr) -> (IO CInt))))
foreign import ccall safe "Language/Lean/Env.chs.h lean_env_for_each_decl"
lean_env_for_each_decl'_ :: ((EnvPtr) -> ((FunPtr ((DeclPtr) -> (IO ()))) -> ((OutExceptionPtr) -> (IO CInt))))
foreign import ccall safe "Language/Lean/Env.chs.h lean_env_for_each_univ"
lean_env_for_each_univ'_ :: ((EnvPtr) -> ((FunPtr ((NamePtr) -> (IO ()))) -> ((OutExceptionPtr) -> (IO CInt))))