{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} module Proof.Assistant.Lean where import Control.Concurrent.Async (race) import Data.ByteString (ByteString) import Data.Coerce (coerce) import Data.Foldable (foldl') import Data.Text (unpack) import System.Directory (withCurrentDirectory) import System.Process (readProcessWithExitCode) import Proof.Assistant.Helpers import Proof.Assistant.RefreshFile import Proof.Assistant.Request import Proof.Assistant.ResourceLimit import Proof.Assistant.Settings import Proof.Assistant.State import qualified Data.Text as Text callLean :: InterpreterState LeanSettings -> InterpreterRequest -> IO ByteString callLean InterpreterState{..} ir = do let ls@LeanSettings{..} = coerce settings s@ExternalInterpreterSettings{..} = externalLean (dir, path) <- refreshTmpFile s (validateLean ls ir) (Just projectDir) withCurrentDirectory dir $ do let fullArgs = (unpack <$> coerce args) <> [path] runProcess = readProcessWithExitCode (t2s executable) fullArgs "" asyncExecutable = do setPriority priority (_exitCode, stdout, stderr) <- runProcess pure . validate path . toBS . unlines $ [stdout, stderr] asyncTimer = asyncWait time eresult <- race asyncTimer (handleErrorMaybe asyncExecutable) case eresult of Left () -> pure "Time limit exceeded" Right bs -> pure bs validateLean :: LeanSettings -> InterpreterRequest -> InterpreterRequest validateLean LeanSettings{..} ir@InterpreterRequest{..} = ir { interpreterRequestMessage = validatedMsg } where remove txt blockedPrefix = Text.replace blockedPrefix "" txt removeAllFromLine x = foldl' remove x leanBlockList removeUnsafeImports = textToBS . removeAllFromLine . bsToText validatedMsg = removeUnsafeImports interpreterRequestMessage