summaryrefslogtreecommitdiff
path: root/source/Api.hs
diff options
context:
space:
mode:
Diffstat (limited to 'source/Api.hs')
-rw-r--r--source/Api.hs1973
1 files changed, 0 insertions, 1973 deletions
diff --git a/source/Api.hs b/source/Api.hs
deleted file mode 100644
index d9fca1d..0000000
--- a/source/Api.hs
+++ /dev/null
@@ -1,1973 +0,0 @@
-{-# LANGUAGE ExplicitForAll #-}
-{-# LANGUAGE MultiWayIf #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE TupleSections #-}
-{-# LANGUAGE NoMonomorphismRestriction #-}
-{-# LANGUAGE RankNTypes #-}
-
-module Api
- ( tokenize, TokStream
- , scan
- , parse
- , parseWorkspace
- , AuthorityFreeParseError(..)
- , renderAuthorityFreeParseError
- , simpleStream
- , builtins
- , ParseException(..)
- , verify, verifyMeasured
- , verifyWithObserverAndStoreMode
- , verifyMeasuredWithObserverAndStoreMode
- , verifyWithObserverAndStoreModeAndJobs
- , verifyMeasuredWithObserverAndStoreModeAndJobs
- , StoreValidationMode(..)
- , WorkPosition
- , workPosition
- , workPositionModuleOrdinal
- , workPositionLocalRequestOrdinal
- , VerificationRequestObserver
- , verificationRequestObserver
- , ProverAnswer
- ( CounterSatisfiable
- , ContradictoryAxioms
- , Uncertain
- , Error
- )
- , pattern Yes
- , VerificationResult(..)
- , VerificationPresentation
- , ReportedEscapeKind(..)
- , ReportedEscape(..)
- , VerificationReport(..)
- , VerificationMeasurements(..)
- , VerificationDriverError(..)
- , FailedVerification(..)
- , VerificationFailureReason(..)
- , prepareVerifiedHtmlExportResult
- , prepareDefaultSourceGraph
- , defaultHtmlMountPrefixes
- ) where
-
-
-import Base
-import Checking.Declaration qualified as Declaration
-import Checking.Foundation qualified as Foundation
-import Checking.Identity qualified as Identity
-import Checking.Module qualified as Typed
-import Checking.Semantic qualified as Semantic
-import Felix.Module (localDeclarationOrdinal)
-import Felix.Parse (ParseException(..), ParseWorkspaceError(..), ParsedSourceWorkspace)
-import Felix.Parse qualified as Felix
-import Felix.Prelude qualified as Prelude
-import Felix.Source
-import Felix.Store qualified as Store
-import Felix.Source.Graph (ResolvedSourceGraph)
-import Felix.Source.Graph qualified as SourceGraph
-import Provers
-import Render.Html.Export qualified as HtmlExport
-import Render.Html.Output (PreparedHtmlArtifact)
-import Report.Location
-import Syntax.Abstract qualified as Raw
-import Syntax.Adapt (scanChunk, ScannedLexicalItem)
-import Syntax.Interface qualified as Syntax
-import Syntax.Lexicon (builtins)
-import Syntax.Token
-
-import Control.Exception qualified as Exception
-import Control.Monad.Logger
-import Control.Monad (unless)
-import Data.Bifunctor (first)
-import Data.List.NonEmpty qualified as NonEmpty
-import Data.Map.Strict qualified as Map
-import Data.Text qualified as StrictText
-import Data.Text.Encoding.Error (UnicodeException)
-import Data.Text.IO qualified as Text
-import Numeric.Natural (Natural)
-import System.FilePath.Posix
-import Text.Megaparsec hiding (failure, parse, Token, try)
-import UnliftIO
-import UnliftIO.Async qualified as Async
-import UnliftIO.Directory
-import UnliftIO.Environment
-
--- Renderer data follows the established current-directory, configured-library,
--- and debug-directory lookup policy.
-findAndReadRendererFile
- :: FilePath
- -> IO (Either HtmlExport.HtmlExportError Text)
-findAndReadRendererFile path = do
- rootsResult <- tryRendererIO do
- currentDir <- getCurrentDirectory
- configuredLibrary <- lookupEnv "NAPROCHE_LIB"
- let libraryDir =
- fromMaybe
- (currentDir </> "library")
- configuredLibrary
- pure
- [ currentDir </> path
- , libraryDir </> path
- , currentDir </> "debug" </> path
- ]
- case rootsResult of
- Left failure ->
- pure
- (Left
- (HtmlExport.HtmlRendererDataLookupFailed
- path
- (StrictText.pack
- (displayException failure))))
- Right candidates -> do
- selected <- selectRendererData path candidates
- case selected of
- Left failure ->
- pure (Left failure)
- Right selectedPath -> do
- readResult <- tryRendererRead
- (Text.readFile selectedPath)
- pure case readResult of
- Left reason ->
- Left
- (HtmlExport.HtmlRendererDataReadFailed
- selectedPath
- reason)
- Right contents ->
- Right contents
-
-selectRendererData
- :: FilePath
- -> [FilePath]
- -> IO (Either HtmlExport.HtmlExportError FilePath)
-selectRendererData requested candidates =
- go candidates
- where
- go = \case
- [] ->
- pure
- (Left
- (HtmlExport.HtmlRendererDataNotFound
- requested
- candidates))
- candidate : remaining -> do
- inspected <- tryRendererIO
- (doesFileExist candidate)
- case inspected of
- Left failure ->
- pure
- (Left
- (HtmlExport.HtmlRendererDataLookupFailed
- candidate
- (StrictText.pack
- (displayException failure))))
- Right True ->
- pure (Right candidate)
- Right False ->
- go remaining
-
-tryRendererIO :: IO value -> IO (Either IOException value)
-tryRendererIO = Exception.try
-
-tryRendererRead :: IO value -> IO (Either Text value)
-tryRendererRead action =
- Exception.catch
- (Exception.catch
- (Right <$> action)
- renderIOException)
- renderUnicodeException
- where
- renderIOException :: IOException -> IO (Either Text value)
- renderIOException =
- pure . Left . StrictText.pack . displayException
-
- renderUnicodeException
- :: UnicodeException
- -> IO (Either Text value)
- renderUnicodeException =
- pure . Left . StrictText.pack . displayException
-
-lexFile :: MonadIO io => FilePath -> io (Text, [[Located Token]])
-lexFile file = do
- prepared <- liftIO (prepareDefaultSourceRequest file)
- (mounts, request) <- either throwWorkspaceError pure prepared
- loaded <-
- liftIO (resolveAndLoadRoot mounts request)
- >>= either throwIO pure
- let source = loadedSource loaded
- raw = loadedText loaded
- locationPath = resolvedSourceLocationPath source
- canonicalPath =
- canonicalPathFilePath
- (resolvedSourceCanonicalPath source)
- registration <-
- registerFilePathWithDisplay
- canonicalPath
- locationPath
- fileId <- either
- (throwIO . SourceLocationRegistrationFailed source)
- pure
- registration
- case runLexer fileId locationPath raw of
- Left tokenError ->
- throwIO (TokenError (errorBundlePretty tokenError))
- Right (_imports, chunks) ->
- pure (raw, chunks)
-
--- | Throws a 'ParseException' when tokenizing fails.
-tokenize :: MonadIO io => FilePath -> io TokStream
-tokenize file = do
- (raw, chunks) <- lexFile file
- pure (TokStream raw chunks)
-
--- | Scan the given file for lexical items. The actual parsing process
--- builds one workspace lexicon instead.
-scan :: MonadIO io => FilePath -> io [ScannedLexicalItem]
-scan input = do
- tokenStream <- tokenize input
- fmap (concatMap (fmap unLocated)) $
- traverse
- (either (throwIO . LexicalScanFailure) pure . scanChunk)
- (unTokStream tokenStream)
-
-
--- | Parse a file. Throws an 'AuthorityFreeParseError' when packaged-prelude
--- loading/parsing or ordinary workspace parsing fails.
-parse :: MonadIO io => FilePath -> io [Raw.Block]
-parse file = do
- result <- parseWorkspace file
- either throwIO pure result
-
-data AuthorityFreeParseError
- = AuthorityFreePreludeLoadFailed !Prelude.PreludeLoadError
- | AuthorityFreePreludeParseFailed !Prelude.PreludeParseError
- | AuthorityFreeWorkspaceFailed !ParseWorkspaceError
- deriving (Show)
-
-instance Exception AuthorityFreeParseError
-
-renderAuthorityFreeParseError :: AuthorityFreeParseError -> Text
-renderAuthorityFreeParseError = \case
- AuthorityFreePreludeLoadFailed failure ->
- "packaged final prelude loading failed: "
- <> Prelude.renderPreludeLoadError failure
- AuthorityFreePreludeParseFailed failure ->
- "packaged final prelude parsing failed: "
- <> Prelude.renderPreludeParseError failure
- AuthorityFreeWorkspaceFailed failure ->
- Felix.renderParseWorkspaceError failure
-
-parseWorkspace
- :: MonadIO io
- => FilePath
- -> io (Either AuthorityFreeParseError [Raw.Block])
-parseWorkspace file =
- fmap Felix.importedBeforeImporterBlocks
- <$> liftIO (parseDefaultWorkspaceWithPrelude file)
-
-parseDefaultWorkspaceWithPrelude
- :: FilePath
- -> IO
- (Either
- AuthorityFreeParseError
- ParsedSourceWorkspace)
-parseDefaultWorkspaceWithPrelude file =
- Prelude.loadReservedPreludeSourceInput >>= \case
- Left failure ->
- pure (Left (AuthorityFreePreludeLoadFailed failure))
- Right source ->
- Prelude.parseReservedPreludeSource source >>= \case
- Left failure ->
- pure (Left (AuthorityFreePreludeParseFailed failure))
- Right prelude -> do
- prepared <- prepareDefaultSourceRequest file
- case prepared of
- Left failure ->
- pure
- (Left
- (AuthorityFreeWorkspaceFailed failure))
- Right (mounts, request) -> do
- let syntax =
- Felix.identifiedParsedModuleSyntaxInterface
- (Prelude.reservedParsedPreludeModule
- prelude)
- fmap
- (first AuthorityFreeWorkspaceFailed . fmap fst)
- (Felix.parseSourceWorkspaceMeasuredWithSyntaxInputsAndGraphValidation
- mounts
- request
- (const [syntax])
- (Prelude.rejectOrdinaryPreludeSourceGraph
- source))
-
-prepareDefaultSourceRequest
- :: FilePath
- -> IO (Either ParseWorkspaceError (SourceMounts, RootRequest))
-prepareDefaultSourceRequest file = do
- mountsResult <- prepareDefaultSourceMounts
- requestResult <- classifyRootRequest file
- pure case (mountsResult, requestResult) of
- (Left err, _) ->
- Left (SourceWorkspaceError err)
- (_, Left err) ->
- Left (SourceWorkspaceError err)
- (Right mounts, Right request) ->
- Right (mounts, request)
-
-prepareDefaultSourceGraph
- :: FilePath
- -> IO (Either ParseWorkspaceError ResolvedSourceGraph)
-prepareDefaultSourceGraph file = do
- prepared <- prepareDefaultSourceRequest file
- case prepared of
- Left sourceFailure ->
- pure (Left sourceFailure)
- Right (mounts, request) ->
- first SourceWorkspaceError
- <$> SourceGraph.buildResolvedSourceGraph mounts request
-
-prepareDefaultSourceMounts :: IO (Either SourceError SourceMounts)
-prepareDefaultSourceMounts = do
- currentDir <- getCurrentDirectory
- configuredLibrary <- lookupEnv "NAPROCHE_LIB"
- let libraryDir = configuredLibrary ?? (currentDir </> "library")
- debugDir = currentDir </> "debug"
- prepareSourceMounts
- [ (sourceMountId "project", currentDir)
- , (sourceMountId "library", libraryDir)
- , (sourceMountId "debug", debugDir)
- ]
-
-classifyRootRequest :: FilePath -> IO (Either SourceError RootRequest)
-classifyRootRequest file
- | isAbsolute file =
- existingRoot file
- | otherwise =
- pure (searchedRoot file)
-
-throwWorkspaceError :: MonadIO io => ParseWorkspaceError -> io a
-throwWorkspaceError = \case
- SourceWorkspaceError err ->
- throwIO err
- err@(SourceLexiconCollision _) ->
- throwIO err
- err@(SourceSyntaxPragmaError _source _pragmaError) ->
- throwIO err
- err@(SourceSyntaxDeclarationError _source _declarationError) ->
- throwIO err
- err@(SourceSyntaxMaterializationError _materializationError) ->
- throwIO err
- err@(SourceParsedModuleKeyError _source _keyError) ->
- throwIO err
- SourceParseError _source err ->
- throwIO err
-
-
-simpleStream :: TokStream -> [[Token]]
-simpleStream TokStream{unTokStream=chunks} = [unLocated <$> ch | ch <- chunks]
-
-data VerificationResult
- = VerificationCompleted
- !VerificationReport
- !VerificationPresentation
- | CompletedWithExplicitGaps
- !VerificationReport
- !VerificationPresentation
- | VerificationFailure !VerificationReport !FailedVerification
- | VerificationCheckingFailure
- !VerificationReport
- !VerificationDriverError
- deriving (Show)
-
--- | Strict owner-independent source presentation retained only after the
--- complete typed workspace succeeds.
-data VerificationPresentation = VerificationPresentation
- !HtmlExport.HtmlPresentation
-
-instance Show VerificationPresentation where
- show _presentation =
- "VerificationPresentation <HTML presentation>"
-
-data ReportedEscapeKind
- = ReportedSourceAxiom
- | ReportedOmitted
- deriving (Show, Eq)
-
-data ReportedEscape = ReportedEscape
- { reportedEscapeKind :: !ReportedEscapeKind
- , reportedEscapeLocation :: !Location
- }
- deriving (Show, Eq)
-
-data VerificationReport = VerificationReport
- { verificationDirectEscapes :: ![ReportedEscape]
- }
- deriving (Show, Eq)
-
--- | Invocation-local observation of the verification pipeline.
---
--- Durations use the monotonic clock and are never part of fact authority or
--- deterministic verification results.
-data VerificationMeasurements = VerificationMeasurements
- { verificationParseMeasurements :: !Felix.ParseMeasurements
- , verificationSourcePreparationNanoseconds :: !Word64
- , verificationInvocationNanoseconds :: !Word64
- , verificationCheckingNanoseconds :: !Word64
- , verificationModuleCount :: !Int
- , verificationDetectedProcessorCount :: !(Maybe Int)
- , verificationEffectiveJobs :: !Int
- , verificationJobsOverridden :: !Bool
- , verificationMaximumLiveModuleCheckers :: !Int
- , verificationMaximumLiveVampireProcesses :: !Int
- , verificationMaximumReadyModuleCount :: !Int
- , verificationObligationBatchCount :: !Int
- , verificationPreparedObligationCount :: !Int
- , verificationMaximumObligationBatchSize :: !Int
- , verificationPreparedRequestBytes :: !Word64
- , verificationRequestPreparationNanoseconds :: !Word64
- , verificationVampireRunCount :: !Int
- , verificationModuleRootHitCount :: !Int
- , verificationModuleRootMissCount :: !Int
- , verificationFirstVampireStartNanoseconds
- :: !(Maybe Word64)
- , verificationFinalVampireSubmissionNanoseconds
- :: !(Maybe Word64)
- , verificationFinalVampireCompletionNanoseconds
- :: !(Maybe Word64)
- , verificationVampireExecutionNanoseconds :: !Word64
- , verificationLongestVampireExecutionNanoseconds :: !Word64
- }
- deriving (Show, Eq)
-
-data VerificationObservation = VerificationObservation
- { observedModuleCount :: !Int
- , observedDetectedProcessorCount :: !(Maybe Int)
- , observedEffectiveJobs :: !Int
- , observedJobsOverridden :: !Bool
- , observedLiveModuleCheckers :: !Int
- , observedMaximumLiveModuleCheckers :: !Int
- , observedMaximumLiveVampireProcesses :: !Int
- , observedMaximumReadyModuleCount :: !Int
- , observedObligationBatchCount :: !Int
- , observedPreparedObligationCount :: !Int
- , observedMaximumObligationBatchSize :: !Int
- , observedPreparedRequestBytes :: !Word64
- , observedRequestPreparationNanoseconds :: !Word64
- , observedVampireRunCount :: !Int
- , observedModuleRootHitCount :: !Int
- , observedModuleRootMissCount :: !Int
- , observedFirstVampireStart :: !(Maybe Word64)
- , observedFinalVampireSubmission :: !(Maybe Word64)
- , observedFinalVampireCompletion :: !(Maybe Word64)
- , observedVampireExecutionNanoseconds :: !Word64
- , observedLongestVampireExecutionNanoseconds :: !Word64
- }
-
-initialVerificationObservation :: VerificationObservation
-initialVerificationObservation =
- VerificationObservation
- { observedModuleCount = 0
- , observedDetectedProcessorCount = Nothing
- , observedEffectiveJobs = 1
- , observedJobsOverridden = False
- , observedLiveModuleCheckers = 0
- , observedMaximumLiveModuleCheckers = 0
- , observedMaximumLiveVampireProcesses = 0
- , observedMaximumReadyModuleCount = 0
- , observedObligationBatchCount = 0
- , observedPreparedObligationCount = 0
- , observedMaximumObligationBatchSize = 0
- , observedPreparedRequestBytes = 0
- , observedRequestPreparationNanoseconds = 0
- , observedVampireRunCount = 0
- , observedModuleRootHitCount = 0
- , observedModuleRootMissCount = 0
- , observedFirstVampireStart = Nothing
- , observedFinalVampireSubmission = Nothing
- , observedFinalVampireCompletion = Nothing
- , observedVampireExecutionNanoseconds = 0
- , observedLongestVampireExecutionNanoseconds = 0
- }
-
-newtype VerificationRequestObserver = VerificationRequestObserver
- { observeVerificationRequest
- :: WorkPosition
- -> PreparedVerificationRequest
- -> IO ()
- }
-
-verificationRequestObserver
- :: (WorkPosition
- -> PreparedVerificationRequest
- -> IO ())
- -> VerificationRequestObserver
-verificationRequestObserver =
- VerificationRequestObserver
-
-ignoreVerificationRequests :: VerificationRequestObserver
-ignoreVerificationRequests =
- VerificationRequestObserver \_ordinal _request -> pure ()
-
-data FailedVerification = FailedVerification
- { failedVerificationLocation :: !Location
- , failedVerificationReason :: !VerificationFailureReason
- }
- deriving (Show)
-
-data VerificationFailureReason
- = CountermodelFailure !Text
- | ContradictoryInputFailure !Text
- | IndeterminateFailure !Text
- | ProtocolFailure !Text !Text
- | TransportFailure !ProverProcessError
- deriving (Show)
-
-verificationFailureReason
- :: Either ProverProcessError ProverAnswer
- -> Maybe VerificationFailureReason
-verificationFailureReason = \case
- Left processError ->
- Just (TransportFailure processError)
- Right Yes ->
- Nothing
- Right (CounterSatisfiable tptp) ->
- Just (CountermodelFailure tptp)
- Right (ContradictoryAxioms tptp) ->
- Just (ContradictoryInputFailure tptp)
- Right (Uncertain tptp) ->
- Just (IndeterminateFailure tptp)
- Right (Error taskLabel message) ->
- Just (ProtocolFailure taskLabel message)
-
-data VerificationDriverError
- = VerificationWorkspaceError
- !ParseWorkspaceError
- | VerificationFoundationManifestError
- !(NonEmpty Foundation.FoundationManifestError)
- | VerificationMissingImportedModule
- !ResolvedSourceAddress
- | VerificationMissingRootModule
- !ResolvedSourceAddress
- | VerificationFinalPreludeReadinessError
- !Typed.FinalPreludeReadinessError
- | VerificationTypedInputError
- !ResolvedSource
- !Typed.TypedModuleInputError
- | VerificationTypedOpenError
- !ResolvedSource
- !Declaration.DriverOpenError
- | VerificationTypedCachedModuleError
- !ResolvedSource
- !Typed.CachedTypedModuleError
- | VerificationTypedModuleError
- !ResolvedSource
- !Typed.TypedModuleFailure
- !Declaration.PendingModulePrefix
- | VerificationValidationIntegrityError
- !ResolvedSource
- !Declaration.ValidationIntegrityError
- | VerificationAdmittedViewError
- !ResolvedSource
- !AdmittedViewError
- | VerificationParsedArtifactIntegrityError
- !ResolvedSource
- !Felix.ParsedArtifactIntegrityError
- | VerificationStoreFailure !Store.StoreFailure
- | VerificationStorePlanningFailure !Store.StorePlanningError
- | VerificationStoreLifecycleFailure !Store.StoreLifecycleError
- | VerificationModuleArtifactKeyError !Semantic.ModuleArtifactKeyError
- | VerificationModuleSchedulerInvariant !Text
- deriving (Show)
-
-instance Exception VerificationDriverError
-
-data TypedWorkspaceOutcome
- = TypedWorkspaceSucceeded
- !AdmittedTypedWorkspace
- | TypedWorkspaceRejected
- !AdmittedTypedWorkspace
- !TypedWorkspaceFailure
-
-data TypedWorkspaceFailure
- = TypedWorkspaceCheckingRejected !VerificationDriverError
- | TypedWorkspaceProverRejected !FailedVerification
-
-data ModuleTask = ModuleTask
- { moduleTaskOrdinal :: !Natural
- , moduleTaskParsed :: !Felix.ParsedModule
- , moduleTaskDirectAddresses :: ![ResolvedSourceAddress]
- }
-
-data ModuleCheckResult
- = ModuleCheckSucceeded
- !ResolvedSourceAddress
- !Typed.SealedTypedModule
- !AdmittedTypedModule
- | ModuleCheckRejected
- !AdmittedTypedModule
- !TypedWorkspaceFailure
-
-data ModuleFailureCandidate = ModuleFailureCandidate
- !Natural
- !AdmittedTypedModule
- !TypedWorkspaceFailure
-
-data AdmittedTypedDeclaration = AdmittedTypedDeclaration
- !Semantic.DeclarationSlot
- !Typed.TypedSourceDeclaration
-
-newtype AdmittedTypedModule = AdmittedTypedModule
- [AdmittedTypedDeclaration]
-
-newtype AdmittedTypedWorkspace = AdmittedTypedWorkspace
- [AdmittedTypedModule]
-
-data AdmittedViewError
- = AdmittedDeclarationCountMismatch
- !Int
- !Int
- | AdmittedDeclarationSlotMismatch
- ![Semantic.DeclarationSlot]
- ![Semantic.DeclarationSlot]
- deriving (Show, Eq)
-
-completeAdmittedModule
- :: Typed.IdentifiedModuleInput
- -> AdmittedTypedModule
-completeAdmittedModule input =
- AdmittedTypedModule
- (uncurry AdmittedTypedDeclaration <$> expectedDeclarations input)
-
-checkedAdmittedModule
- :: Bool
- -> Typed.IdentifiedModuleInput
- -> Declaration.PendingModulePrefix
- -> Either AdmittedViewError AdmittedTypedModule
-checkedAdmittedModule requireComplete input prefix = do
- let expected = expectedDeclarations input
- expectedSlots = fst <$> expected
- actualSlots =
- Declaration.committedBatchSlot
- <$> Declaration.pendingModulePrefixBatches prefix
- admittedCount = length actualSlots
- if requireComplete
- then unless
- (admittedCount == length expected)
- (Left
- (AdmittedDeclarationCountMismatch
- (length expected)
- admittedCount))
- else unless
- (admittedCount <= length expected)
- (Left
- (AdmittedDeclarationCountMismatch
- (length expected)
- admittedCount))
- unless
- (actualSlots == take admittedCount expectedSlots)
- (Left
- (AdmittedDeclarationSlotMismatch
- (take admittedCount expectedSlots)
- actualSlots))
- pure
- (AdmittedTypedModule
- [ AdmittedTypedDeclaration slot declaration
- | (slot, declaration) <- take admittedCount expected
- ])
-
-expectedDeclarations
- :: Typed.IdentifiedModuleInput
- -> [(Semantic.DeclarationSlot, Typed.TypedSourceDeclaration)]
-expectedDeclarations input =
- zipWith
- (\ordinal declaration ->
- ( Semantic.declarationSlot
- (Typed.identifiedModuleOwner input)
- (localDeclarationOrdinal ordinal)
- , declaration
- ))
- [0..]
- (Typed.typedSourceDeclarations
- (Typed.identifiedModuleParsed input))
-
-data StoreValidationMode
- = FreshStoreValidation
- | WarmStoreValidation
- deriving (Show, Eq)
-
-verifyWithObserverAndStoreMode
- :: (MonadUnliftIO io, MonadLogger io)
- => Store.Store
- -> StoreValidationMode
- -> VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io (Either VerificationDriverError VerificationResult)
-verifyWithObserverAndStoreMode store validationMode observer prover file =
- verifyWithObserverAndStoreModeAndJobs
- store validationMode sequentialJobs observer prover file
-
-verifyWithObserverAndStoreModeAndJobs
- :: (MonadUnliftIO io, MonadLogger io)
- => Store.Store
- -> StoreValidationMode
- -> JobsSelection
- -> VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io (Either VerificationDriverError VerificationResult)
-verifyWithObserverAndStoreModeAndJobs
- store validationMode jobs observer prover file =
- fmap (fmap fst)
- (verifyMeasuredWithObserverAndStoreModeAndJobs
- store validationMode jobs observer prover file)
-
-verifyMeasuredWithObserverAndStoreMode
- :: (MonadUnliftIO io, MonadLogger io)
- => Store.Store
- -> StoreValidationMode
- -> VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io
- (Either
- VerificationDriverError
- (VerificationResult, VerificationMeasurements))
-verifyMeasuredWithObserverAndStoreMode
- store validationMode observer prover file =
- verifyMeasuredWithObserverAndStoreModeAndJobs
- store validationMode sequentialJobs observer prover file
-
-verifyMeasuredWithObserverAndStoreModeAndJobs
- :: (MonadUnliftIO io, MonadLogger io)
- => Store.Store
- -> StoreValidationMode
- -> JobsSelection
- -> VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io
- (Either
- VerificationDriverError
- (VerificationResult, VerificationMeasurements))
-verifyMeasuredWithObserverAndStoreModeAndJobs
- store validationMode jobs observer prover file =
- try
- (verifyMeasuredThrowingWithStore
- store validationMode jobs observer prover file)
-
-sequentialJobs :: JobsSelection
-sequentialJobs =
- JobsSelection
- { jobsSelectionDetectedProcessors = Nothing
- , jobsSelectionEffectiveJobs =
- fromMaybe
- (impossible "one is not a positive worker count")
- (effectiveJobs 1)
- , jobsSelectionWasOverridden = True
- }
-
-verifyMeasured
- :: (MonadUnliftIO io, MonadLogger io)
- => Vampire
- -> FilePath
- -> io
- (Either
- VerificationDriverError
- (VerificationResult, VerificationMeasurements))
-verifyMeasured prover file =
- verifyMeasuredWithObserver
- ignoreVerificationRequests
- prover
- file
-
-verifyMeasuredWithObserver
- :: (MonadUnliftIO io, MonadLogger io)
- => VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io
- (Either
- VerificationDriverError
- (VerificationResult, VerificationMeasurements))
-verifyMeasuredWithObserver observer prover file =
- try (verifyMeasuredThrowing observer prover file)
-
-verifyMeasuredThrowing
- :: (MonadUnliftIO io, MonadLogger io)
- => VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io (VerificationResult, VerificationMeasurements)
-verifyMeasuredThrowing requestObserver prover file = do
- foundation <-
- either
- (throwIO . VerificationFoundationManifestError)
- pure
- Foundation.checkedFoundation
- planned <- liftIO (Store.planStore Store.FreshTemporaryStore)
- plan <- either
- (throwIO . VerificationStorePlanningFailure)
- pure
- planned
- withRunInIO \runInIO ->
- Store.withStoreLease plan \lease -> do
- opened <- Store.withOpenStore
- lease
- (Identity.theoryId foundation)
- (\_startup store ->
- runInIO
- (verifyMeasuredThrowingWithStore
- store
- FreshStoreValidation
- sequentialJobs
- requestObserver
- prover
- file))
- either
- (throwIO . VerificationStoreLifecycleFailure)
- pure
- opened
-
-verifyMeasuredThrowingWithStore
- :: (MonadUnliftIO io, MonadLogger io)
- => Store.Store
- -> StoreValidationMode
- -> JobsSelection
- -> VerificationRequestObserver
- -> Vampire
- -> FilePath
- -> io (VerificationResult, VerificationMeasurements)
-verifyMeasuredThrowingWithStore
- store validationMode jobsSelection requestObserver prover file = do
- invocationStart <- liftIO getMonotonicTimeNSec
- memo <- liftIO (Store.newStoreMemo store)
- storeCoordinator <- liftIO Store.newStoreCoordinator
- ( admittedResult
- , parseMeasurements
- , sourcePreparation
- , checkingStart
- , checkingEnd
- , observation
- , parsedPresentation
- ) <-
- liftIO
- (withVampireExecutor
- (jobsSelectionEffectiveJobs jobsSelection)
- prover
- (observeVerificationRequest requestObserver)
- \executor -> do
- observationRef <- newIORef
- initialVerificationObservation
- { observedDetectedProcessorCount =
- jobsSelectionDetectedProcessors jobsSelection
- , observedEffectiveJobs =
- effectiveJobsValue
- (jobsSelectionEffectiveJobs jobsSelection)
- , observedJobsOverridden =
- jobsSelectionWasOverridden jobsSelection
- }
- foundation <-
- either
- (throwIO
- . VerificationFoundationManifestError)
- pure
- Foundation.checkedFoundation
- preparationStart <- getMonotonicTimeNSec
- prepared <-
- prepareDefaultSourceRequest file
- >>= either
- (throwIO . VerificationWorkspaceError)
- pure
- let (mounts, request) = prepared
- preparationEnd <- getMonotonicTimeNSec
- prelude <- withVampireRequestOwner executor \owner -> do
- preludeResolver <-
- typedVampireResolver
- owner
- 0
- observationRef
- Typed.acquireFinalPreludeSession
- memo store foundation preludeResolver
- >>= either
- (throwIO
- . VerificationFinalPreludeReadinessError)
- pure
- observeModuleRootAcquisition observationRef
- (Typed.finalPreludeAcquisition prelude)
- let preludeSyntax =
- Typed.sealedTypedModuleSyntax
- (Typed.finalPreludeModule prelude)
- syntaxInputs _source = [preludeSyntax]
- (parsed, measured) <-
- Felix.parseSourceWorkspaceMeasuredWithStoreAndSyntaxInputsAndGraphValidation
- store
- mounts
- request
- syntaxInputs
- (Prelude.rejectOrdinaryPreludeSourceGraph
- (Typed.finalPreludeSource prelude))
- >>= either throwParseExecutionError pure
- checkingStart <- getMonotonicTimeNSec
- outcome <-
- checkTypedWorkspace
- memo
- storeCoordinator
- foundation
- prelude
- executor
- (jobsSelectionEffectiveJobs jobsSelection)
- validationMode
- observationRef
- parsed
- store
- checkingEnd <- getMonotonicTimeNSec
- executorObserved <- vampireExecutorObservation executor
- mergeExecutorObservation observationRef executorObserved
- observed <- readIORef observationRef
- pure
- ( outcome
- , measured
- , preparationEnd - preparationStart
- , checkingStart
- , checkingEnd
- , observed
- , parsed
- ))
- let result =
- case admittedResult of
- TypedWorkspaceRejected admitted failure ->
- let report = admittedWorkspaceReport admitted
- in case failure of
- TypedWorkspaceCheckingRejected checkingFailure ->
- VerificationCheckingFailure
- report checkingFailure
- TypedWorkspaceProverRejected proverFailure ->
- VerificationFailure report proverFailure
- TypedWorkspaceSucceeded admitted ->
- completedResult
- (admittedWorkspaceReport admitted)
- (VerificationPresentation
- (HtmlExport.htmlPresentationFromParsedWorkspace
- parsedPresentation))
- measurements =
- finalizeVerificationMeasurements
- invocationStart
- checkingStart
- checkingEnd
- parseMeasurements
- sourcePreparation
- observation
- logInfoN
- (renderVerificationMeasurements measurements)
- pure (result, measurements)
- where
- throwParseExecutionError = \case
- Felix.ParseExecutionWorkspaceError failure ->
- throwIO (VerificationWorkspaceError failure)
- Felix.ParseExecutionStoreFailure failure ->
- throwIO (VerificationStoreFailure failure)
- Felix.ParseExecutionArtifactIntegrityFailure source failure ->
- throwIO
- (VerificationParsedArtifactIntegrityError source failure)
-
-checkTypedWorkspace
- :: Store.StoreMemo
- -> Store.StoreCoordinator
- -> Foundation.CheckedFoundation
- -> Typed.FinalPreludeSession
- -> VampireExecutor
- -> EffectiveJobs
- -> StoreValidationMode
- -> IORef VerificationObservation
- -> ParsedSourceWorkspace
- -> Store.Store
- -> IO TypedWorkspaceOutcome
-checkTypedWorkspace
- memo
- storeCoordinator
- foundation
- prelude
- executor
- selectedJobs
- validationMode
- observationRef
- workspace
- store = do
- let modules =
- zipWith
- makeTask
- [1..]
- (toList
- (Felix.parsedWorkspaceImportedBeforeImporter workspace))
- rootAddress =
- Felix.parsedModuleAddress
- (Felix.parsedWorkspaceRootModule workspace)
- atomicModifyIORef' observationRef
- (\observation ->
- ( observation
- { observedModuleCount = length modules
- }
- , ()
- ))
- scheduleModules
- rootAddress
- modules
- Map.empty
- Map.empty
- Map.empty
- Nothing
- where
- workerBound = effectiveJobsValue selectedJobs
-
- makeTask ordinal parsed =
- ModuleTask
- { moduleTaskOrdinal = ordinal
- , moduleTaskParsed = parsed
- , moduleTaskDirectAddresses =
- nubOrd
- (Felix.parsedImportedAddress
- <$> Felix.parsedModuleImports parsed)
- }
-
- scheduleModules
- rootAddress
- pending
- running
- sealedByAddress
- admittedByOrdinal
- candidate = do
- let readyCount =
- length
- [ ()
- | task <- pending
- , taskMayStart candidate sealedByAddress task
- ]
- observeReadyModules observationRef readyCount
- (pending', running') <-
- startReadyModules
- pending
- running
- sealedByAddress
- candidate
- Exception.onException
- (if Map.null running'
- then case candidate of
- Just selected
- | any
- (\task ->
- moduleTaskOrdinal task
- < candidateOrdinal selected)
- pending' ->
- throwIO
- (VerificationModuleSchedulerInvariant
- "an earlier module is not terminal")
- | otherwise ->
- pure
- (TypedWorkspaceRejected
- (admittedWorkspaceThrough
- admittedByOrdinal
- selected)
- (candidateFailure selected))
- Nothing
- | null pending' -> do
- unless
- (Map.member rootAddress sealedByAddress)
- (throwIO
- (VerificationMissingRootModule
- rootAddress))
- pure
- (TypedWorkspaceSucceeded
- (completeAdmittedWorkspace
- admittedByOrdinal))
- | otherwise ->
- throwIO
- (VerificationModuleSchedulerInvariant
- "no ready module and no running module")
- else do
- (_completedAsync, (ordinal, completed)) <-
- Async.waitAny (Map.elems running')
- let runningWithoutCompleted =
- Map.delete ordinal running'
- case completed of
- Left fatal -> do
- cancelModuleCheckers runningWithoutCompleted
- Exception.throwIO fatal
- Right (ModuleCheckSucceeded
- address sealed admittedModule) ->
- scheduleModules
- rootAddress
- pending'
- runningWithoutCompleted
- (Map.insert address sealed sealedByAddress)
- (Map.insert
- ordinal
- admittedModule
- admittedByOrdinal)
- candidate
- Right (ModuleCheckRejected
- admittedModule failure) -> do
- let selected =
- chooseEarlierFailure
- candidate
- (ModuleFailureCandidate
- ordinal
- admittedModule
- failure)
- cutoff = candidateOrdinal selected
- (later, retained) =
- Map.partitionWithKey
- (\runningOrdinal _async ->
- runningOrdinal > cutoff)
- runningWithoutCompleted
- cancelModuleCheckers later
- scheduleModules
- rootAddress
- pending'
- retained
- sealedByAddress
- admittedByOrdinal
- (Just selected)
- )
- (cancelModuleCheckers running')
-
- startReadyModules
- pending
- running
- sealedByAddress
- candidate
- | Map.size running >= workerBound =
- pure (pending, running)
- | otherwise =
- case extractFirstReady candidate sealedByAddress pending of
- Nothing ->
- pure (pending, running)
- Just (task, remaining) -> do
- checker <- Async.async do
- completed <-
- (Exception.try
- (observeModuleChecker observationRef
- (checkModule task sealedByAddress))
- :: IO
- (Either
- SomeException
- ModuleCheckResult))
- pure (moduleTaskOrdinal task, completed)
- startReadyModules
- remaining
- (Map.insert
- (moduleTaskOrdinal task)
- checker
- running)
- sealedByAddress
- candidate
-
- checkModule task sealedByAddress =
- withVampireRequestOwner executor \requestOwner -> do
- let parsed = moduleTaskParsed task
- source = Felix.parsedModuleResolved parsed
- address = Felix.parsedModuleAddress parsed
- direct <-
- traverse
- (\directAddress ->
- maybe
- (throwIO
- (VerificationMissingImportedModule
- directAddress))
- pure
- (Map.lookup directAddress sealedByAddress))
- (moduleTaskDirectAddresses task)
- resolver <-
- typedVampireResolver
- requestOwner
- (moduleTaskOrdinal task)
- observationRef
- input <-
- either
- (throwIO . VerificationTypedInputError source)
- pure
- (Typed.typedModuleInput
- foundation
- (Typed.finalPreludeReadiness prelude)
- resolver
- validationRun
- parsed
- direct)
- loadCachedModule parsed direct >>= \case
- Just sealed -> do
- observeModuleRootAcquisition
- observationRef Typed.ModuleRootHit
- pure
- (ModuleCheckSucceeded
- address
- sealed
- (completeAdmittedModule
- (Typed.identifiedPhysicalModule parsed)))
- Nothing -> do
- typedResult <-
- Exception.catch
- (Typed.runTypedModule input)
- (\failure ->
- throwIO
- (VerificationValidationIntegrityError
- source
- failure))
- case typedResult of
- Typed.TypedModuleOpenFailed err ->
- throwIO (VerificationTypedOpenError source err)
- Typed.TypedModuleFailed err prefix -> do
- let driverFailure =
- VerificationTypedModuleError
- source err prefix
- case classifyTypedModuleFailure err of
- TypedIntegrityFailure ->
- throwIO driverFailure
- TypedCheckingRejection ->
- reportFailure
- parsed
- prefix
- (TypedWorkspaceCheckingRejected
- driverFailure)
- TypedVerificationRejection failed ->
- reportFailure
- parsed
- prefix
- (TypedWorkspaceProverRejected failed)
- TypedProverFailure failed ->
- reportFailure
- parsed
- prefix
- (TypedWorkspaceProverRejected failed)
- Typed.TypedModuleSucceeded sealed -> do
- admittedModule <-
- either
- (throwIO
- . VerificationAdmittedViewError source)
- pure
- (checkedAdmittedModule
- True
- (Typed.identifiedPhysicalModule parsed)
- (Typed.sealedTypedModulePrefix sealed))
- persistSealed
- (Typed.identifiedPhysicalModule parsed)
- sealed
- observeModuleRootAcquisition
- observationRef Typed.ModuleRootMiss
- pure
- (ModuleCheckSucceeded
- address sealed admittedModule)
-
- reportFailure parsed prefix failure = do
- let source = Felix.parsedModuleResolved parsed
- admittedModule <-
- either
- (throwIO . VerificationAdmittedViewError source)
- pure
- (checkedAdmittedModule
- False
- (Typed.identifiedPhysicalModule parsed)
- prefix)
- Store.withStoreCoordinator storeCoordinator
- (Store.writePendingModulePrefix store prefix)
- >>= either
- (throwIO . VerificationStoreFailure)
- pure
- pure (ModuleCheckRejected admittedModule failure)
-
- storeValidationLookup lookupStore =
- Declaration.validationLookup
- (\key ->
- Store.withStoreCoordinator storeCoordinator
- (Store.loadProofValidation lookupStore key)
- >>= either
- (throwIO . VerificationStoreFailure)
- pure)
- (\key ->
- Store.withStoreCoordinator storeCoordinator
- (Store.loadDeclarationValidation lookupStore key)
- >>= either
- (throwIO . VerificationStoreFailure)
- pure)
-
- validationRun =
- case validationMode of
- FreshStoreValidation ->
- Declaration.FreshValidation
- WarmStoreValidation ->
- Declaration.WarmValidation
- (storeValidationLookup store)
-
- persistSealed input sealed = do
- artifactKey <-
- either
- (throwIO . VerificationModuleArtifactKeyError)
- pure
- (Semantic.moduleArtifactKey
- (Typed.identifiedModuleOwner input)
- (Felix.identifiedParsedModuleId
- (Typed.identifiedModuleParsed input))
- (Semantic.semanticInterfaceDirectInputs
- (Typed.sealedTypedModuleSemantic sealed))
- (Identity.theoryId foundation))
- let artifact =
- Semantic.moduleArtifactResult
- artifactKey
- (Syntax.moduleSyntaxAssertedId
- (Typed.sealedTypedModuleSyntax sealed))
- (Semantic.semanticInterfaceAssertedId
- (Typed.sealedTypedModuleSemantic sealed))
- acknowledged <-
- Store.withStoreCoordinator storeCoordinator
- (Store.writeSealedModule
- store
- (Typed.sealedTypedModulePrefix sealed)
- [Typed.sealedTypedModuleSyntax sealed]
- [Typed.sealedTypedModuleSemantic sealed]
- artifact)
- >>= either
- (throwIO . VerificationStoreFailure)
- pure
- unless
- (acknowledged == artifact)
- (throwIO
- (VerificationStoreFailure
- Store.StoreModuleArtifactIdMismatch))
-
- loadCachedModule parsed direct =
- case validationMode of
- WarmStoreValidation -> do
- let owner =
- Typed.identifiedModuleOwner
- (Typed.identifiedPhysicalModule parsed)
- directSemantic =
- Semantic.semanticInterfaceAssertedId
- (Typed.sealedTypedModuleSemantic
- (Typed.finalPreludeModule prelude))
- : ( Semantic.semanticInterfaceAssertedId
- . Typed.sealedTypedModuleSemantic
- <$> direct
- )
- artifactKey <-
- either
- (throwIO . VerificationModuleArtifactKeyError)
- pure
- (Semantic.moduleArtifactKey
- owner
- (Felix.identifiedParsedModuleId
- (Typed.identifiedModuleParsed
- (Typed.identifiedPhysicalModule parsed)))
- directSemantic
- (Identity.theoryId foundation))
- loaded <-
- Store.withStoreCoordinator storeCoordinator
- (Store.loadCachedModuleInstallation
- memo
- store
- artifactKey
- (Syntax.moduleSyntaxAssertedId
- (Felix.parsedModuleSyntaxInterface parsed)))
- case loaded of
- Left failure ->
- throwIO (VerificationStoreFailure failure)
- Right Nothing ->
- pure Nothing
- Right (Just installation) ->
- either
- (throwIO
- . VerificationTypedCachedModuleError
- (Felix.parsedModuleResolved parsed))
- (pure . Just)
- (Typed.cachedSealedTypedModule
- foundation
- (Typed.finalPreludeModule prelude : direct)
- installation)
- FreshStoreValidation ->
- pure Nothing
-
- taskMayStart candidate sealedByAddress task =
- maybe True
- (moduleTaskOrdinal task <)
- (candidateOrdinal <$> candidate)
- && all
- (`Map.member` sealedByAddress)
- (moduleTaskDirectAddresses task)
-
- extractFirstReady candidate sealedByAddress = go []
- where
- go _before [] = Nothing
- go before (task : after)
- | taskMayStart candidate sealedByAddress task =
- Just (task, reverse before <> after)
- | otherwise =
- go (task : before) after
-
- chooseEarlierFailure Nothing incoming = incoming
- chooseEarlierFailure (Just current) incoming
- | candidateOrdinal incoming < candidateOrdinal current = incoming
- | otherwise = current
-
- candidateOrdinal (ModuleFailureCandidate ordinal _admitted _failure) =
- ordinal
-
- candidateFailure (ModuleFailureCandidate _ordinal _admitted failure) =
- failure
-
- candidateAdmitted (ModuleFailureCandidate _ordinal admitted _failure) =
- admitted
-
- completeAdmittedWorkspace admittedByOrdinal =
- AdmittedTypedWorkspace
- ( completeAdmittedModule (Typed.finalPreludeInput prelude)
- : fmap snd (Map.toAscList admittedByOrdinal)
- )
-
- admittedWorkspaceThrough admittedByOrdinal selected =
- let cutoff = candidateOrdinal selected
- earlier = Map.filterWithKey
- (\ordinal _admitted -> ordinal < cutoff)
- admittedByOrdinal
- in AdmittedTypedWorkspace
- ( completeAdmittedModule (Typed.finalPreludeInput prelude)
- : ( fmap snd (Map.toAscList earlier)
- <> [candidateAdmitted selected]
- )
- )
-
- cancelModuleCheckers running = do
- traverse_ Async.cancel (Map.elems running)
- traverse_ Async.waitCatch (Map.elems running)
-
-data TypedFailureClassification
- = TypedCheckingRejection
- | TypedVerificationRejection !FailedVerification
- | TypedProverFailure !FailedVerification
- | TypedIntegrityFailure
-
--- | Classify failures at the typed checking boundary conservatively.
---
--- Only source elaboration and recognized prover outcomes may retain an
--- admitted source report. Every declaration/sealing invariant, including a
--- future constructor not explicitly recognized below, remains fatal.
-classifyTypedModuleFailure
- :: Typed.TypedModuleFailure
- -> TypedFailureClassification
-classifyTypedModuleFailure = \case
- Typed.TypedActionFailed{} ->
- TypedCheckingRejection
- Typed.TypedDeclarationFailed
- (Declaration.ProofObligationFailedAt
- location
- (Declaration.VampireProcessFailed processError)) ->
- classifyTypedProverResult location (Left processError)
- Typed.TypedDeclarationFailed
- (Declaration.ProofObligationFailedAt
- location
- (Declaration.VampireObligationRejected answer)) ->
- classifyTypedProverResult location (Right answer)
- _failure ->
- TypedIntegrityFailure
-
-classifyTypedProverResult
- :: Location
- -> Either ProverProcessError ProverAnswer
- -> TypedFailureClassification
-classifyTypedProverResult location result =
- case verificationFailureReason result of
- Nothing ->
- TypedIntegrityFailure
- Just reason ->
- let failed = FailedVerification location reason
- in case reason of
- CountermodelFailure{} ->
- TypedVerificationRejection failed
- ContradictoryInputFailure{} ->
- TypedVerificationRejection failed
- IndeterminateFailure{} ->
- TypedProverFailure failed
- ProtocolFailure{} ->
- TypedProverFailure failed
- TransportFailure{} ->
- TypedProverFailure failed
-
-typedVampireResolver
- :: VampireRequestOwner
- -> Natural
- -> IORef VerificationObservation
- -> IO Declaration.VampireResolver
-typedVampireResolver
- requestOwner moduleOrdinal observationRef = do
- localOrdinalRef <- newIORef 1
- let reserve requests = do
- let batchSize = NonEmpty.length requests
- ordinalCount = fromIntegral batchSize
- firstOrdinal <- atomicModifyIORef' localOrdinalRef
- (\current -> (current + ordinalCount, current))
- let positions =
- NonEmpty.fromList
- [ workPosition moduleOrdinal ordinal
- | ordinal <-
- [firstOrdinal .. firstOrdinal + ordinalCount - 1]
- ]
- preparedBytes =
- foldl'
- (\total request ->
- total
- + fromIntegral
- (preparedVerificationByteCount request))
- 0
- requests
- atomicModifyIORef' observationRef \observation ->
- ( observation
- { observedObligationBatchCount =
- observedObligationBatchCount observation + 1
- , observedPreparedObligationCount =
- observedPreparedObligationCount observation + batchSize
- , observedMaximumObligationBatchSize =
- max batchSize
- (observedMaximumObligationBatchSize observation)
- , observedPreparedRequestBytes =
- observedPreparedRequestBytes observation
- + preparedBytes
- }
- , ()
- )
- pure positions
- submit requests = do
- positions <- reserve requests
- traverse
- (uncurry (submitVampireRequest requestOwner))
- (NonEmpty.zip positions requests)
- observe elapsed =
- atomicModifyIORef' observationRef \observation ->
- ( observation
- { observedRequestPreparationNanoseconds =
- observedRequestPreparationNanoseconds observation
- + elapsed
- }
- , ()
- )
- pure (Declaration.vampireSubmissionResolver submit observe)
-
-observeModuleRootAcquisition
- :: IORef VerificationObservation
- -> Typed.ModuleRootAcquisition
- -> IO ()
-observeModuleRootAcquisition observationRef acquisition =
- atomicModifyIORef' observationRef \observation ->
- ( case acquisition of
- Typed.ModuleRootHit ->
- observation
- { observedModuleRootHitCount =
- observedModuleRootHitCount observation + 1
- }
- Typed.ModuleRootMiss ->
- observation
- { observedModuleRootMissCount =
- observedModuleRootMissCount observation + 1
- }
- , ()
- )
-
-observeReadyModules
- :: IORef VerificationObservation
- -> Int
- -> IO ()
-observeReadyModules observationRef readyCount =
- atomicModifyIORef' observationRef \observation ->
- ( observation
- { observedMaximumReadyModuleCount =
- max readyCount
- (observedMaximumReadyModuleCount observation)
- }
- , ()
- )
-
-observeModuleChecker
- :: IORef VerificationObservation
- -> IO value
- -> IO value
-observeModuleChecker observationRef action = do
- atomicModifyIORef' observationRef \observation ->
- let live = observedLiveModuleCheckers observation + 1
- in
- ( observation
- { observedLiveModuleCheckers = live
- , observedMaximumLiveModuleCheckers =
- max live
- (observedMaximumLiveModuleCheckers observation)
- }
- , ()
- )
- action `Exception.finally`
- atomicModifyIORef' observationRef
- (\observation ->
- ( observation
- { observedLiveModuleCheckers =
- observedLiveModuleCheckers observation - 1
- }
- , ()
- ))
-
-mergeExecutorObservation
- :: IORef VerificationObservation
- -> VampireExecutorObservation
- -> IO ()
-mergeExecutorObservation observationRef executorObserved =
- atomicModifyIORef' observationRef \observation ->
- ( observation
- { observedVampireRunCount =
- vampireExecutorRunCount executorObserved
- , observedMaximumLiveVampireProcesses =
- vampireExecutorMaximumLiveCount executorObserved
- , observedFirstVampireStart =
- vampireExecutorFirstStartNanoseconds executorObserved
- , observedFinalVampireSubmission =
- vampireExecutorFinalSubmissionNanoseconds executorObserved
- , observedFinalVampireCompletion =
- vampireExecutorFinalCompletionNanoseconds executorObserved
- , observedVampireExecutionNanoseconds =
- vampireExecutorExecutionNanoseconds executorObserved
- , observedLongestVampireExecutionNanoseconds =
- vampireExecutorLongestExecutionNanoseconds executorObserved
- }
- , ()
- )
-
-finalizeVerificationMeasurements
- :: Word64
- -> Word64
- -> Word64
- -> Felix.ParseMeasurements
- -> Word64
- -> VerificationObservation
- -> VerificationMeasurements
-finalizeVerificationMeasurements
- invocationStart
- checkingStart
- checkingEnd
- parseMeasurements
- sourcePreparation
- observation =
- VerificationMeasurements
- { verificationParseMeasurements =
- parseMeasurements
- , verificationSourcePreparationNanoseconds =
- sourcePreparation
- , verificationInvocationNanoseconds =
- checkingEnd - invocationStart
- , verificationCheckingNanoseconds =
- checkingEnd - checkingStart
- , verificationModuleCount =
- observedModuleCount observation
- , verificationDetectedProcessorCount =
- observedDetectedProcessorCount observation
- , verificationEffectiveJobs =
- observedEffectiveJobs observation
- , verificationJobsOverridden =
- observedJobsOverridden observation
- , verificationMaximumLiveModuleCheckers =
- observedMaximumLiveModuleCheckers observation
- , verificationMaximumLiveVampireProcesses =
- observedMaximumLiveVampireProcesses observation
- , verificationMaximumReadyModuleCount =
- observedMaximumReadyModuleCount observation
- , verificationObligationBatchCount =
- observedObligationBatchCount observation
- , verificationPreparedObligationCount =
- observedPreparedObligationCount observation
- , verificationMaximumObligationBatchSize =
- observedMaximumObligationBatchSize observation
- , verificationPreparedRequestBytes =
- observedPreparedRequestBytes observation
- , verificationRequestPreparationNanoseconds =
- observedRequestPreparationNanoseconds observation
- , verificationVampireRunCount =
- observedVampireRunCount observation
- , verificationModuleRootHitCount =
- observedModuleRootHitCount observation
- , verificationModuleRootMissCount =
- observedModuleRootMissCount observation
- , verificationFirstVampireStartNanoseconds =
- fmap
- (\started -> started - invocationStart)
- (observedFirstVampireStart observation)
- , verificationFinalVampireSubmissionNanoseconds =
- fmap
- (\submitted -> submitted - invocationStart)
- (observedFinalVampireSubmission observation)
- , verificationFinalVampireCompletionNanoseconds =
- fmap
- (\completed -> completed - invocationStart)
- (observedFinalVampireCompletion observation)
- , verificationVampireExecutionNanoseconds =
- observedVampireExecutionNanoseconds observation
- , verificationLongestVampireExecutionNanoseconds =
- observedLongestVampireExecutionNanoseconds observation
- }
-
-renderVerificationMeasurements
- :: VerificationMeasurements
- -> Text
-renderVerificationMeasurements measurements =
- StrictText.unwords
- [ "M0"
- , "source_setup_ms="
- <> renderNanoseconds
- (verificationSourcePreparationNanoseconds
- measurements)
- , "resolution_ms="
- <> renderNanoseconds
- (Felix.parseMeasurementResolutionNanoseconds
- parseMeasurements)
- , "candidate_probes=" <> renderIntegral
- (Felix.parseMeasurementCandidateProbeCount
- parseMeasurements)
- , "canonicalizations=" <> renderIntegral
- (Felix.parseMeasurementCanonicalizationCount
- parseMeasurements)
- , "target_inspections=" <> renderIntegral
- (Felix.parseMeasurementTargetInspectionCount
- parseMeasurements)
- , "tokenization_ms="
- <> renderNanoseconds
- (Felix.parseMeasurementTokenizationNanoseconds
- parseMeasurements)
- , "scanning_ms="
- <> renderNanoseconds
- (Felix.parseMeasurementScanningNanoseconds
- parseMeasurements)
- , "syntax_interface_ms="
- <> renderNanoseconds
- (Felix.parseMeasurementSyntaxInterfaceNanoseconds
- parseMeasurements)
- , "parsing_ms="
- <> renderNanoseconds
- (Felix.parseMeasurementParsingNanoseconds
- parseMeasurements)
- , "parsed_hits=" <> renderIntegral
- (Felix.parseMeasurementParsedHitCount parseMeasurements)
- , "parsed_misses=" <> renderIntegral
- (Felix.parseMeasurementParsedMissCount parseMeasurements)
- , "parser_tables=" <> renderIntegral
- (Felix.parseMeasurementParserTableMaterializationCount
- parseMeasurements)
- , "modules=" <> renderIntegral
- (verificationModuleCount measurements)
- , "detected_processors="
- <> maybe
- "unavailable"
- renderIntegral
- (verificationDetectedProcessorCount measurements)
- , "effective_jobs=" <> renderIntegral
- (verificationEffectiveJobs measurements)
- , "jobs_overridden="
- <> if verificationJobsOverridden measurements
- then "yes"
- else "no"
- , "max_module_checkers=" <> renderIntegral
- (verificationMaximumLiveModuleCheckers measurements)
- , "max_vampire_processes=" <> renderIntegral
- (verificationMaximumLiveVampireProcesses measurements)
- , "files_read=" <> renderIntegral
- (Felix.parseMeasurementModuleCount
- parseMeasurements)
- , "import_occurrences=" <> renderIntegral
- (Felix.parseMeasurementImportOccurrenceCount
- parseMeasurements)
- , "chunks=" <> renderIntegral
- (Felix.parseMeasurementChunkCount
- parseMeasurements)
- , "source_bytes=" <> renderIntegral
- (Felix.parseMeasurementSourceByteCount
- parseMeasurements)
- , "checking_ms="
- <> renderNanoseconds
- (verificationCheckingNanoseconds
- measurements)
- , "batches=" <> renderIntegral
- (verificationObligationBatchCount measurements)
- , "obligations=" <> renderIntegral
- (verificationPreparedObligationCount measurements)
- , "max_batch=" <> renderIntegral
- (verificationMaximumObligationBatchSize
- measurements)
- , "prepared_bytes=" <> renderIntegral
- (verificationPreparedRequestBytes measurements)
- , "request_preparation_ms="
- <> renderNanoseconds
- (verificationRequestPreparationNanoseconds measurements)
- , "vampire_runs=" <> renderIntegral
- (verificationVampireRunCount measurements)
- , "module_root_hits=" <> renderIntegral
- (verificationModuleRootHitCount measurements)
- , "module_root_misses=" <> renderIntegral
- (verificationModuleRootMissCount measurements)
- , "first_vampire_ms="
- <> maybe
- "none"
- renderNanoseconds
- (verificationFirstVampireStartNanoseconds
- measurements)
- , "vampire_ms="
- <> renderNanoseconds
- (verificationVampireExecutionNanoseconds
- measurements)
- , "final_submission_ms="
- <> maybe
- "none"
- renderNanoseconds
- (verificationFinalVampireSubmissionNanoseconds
- measurements)
- , "final_completion_ms="
- <> maybe
- "none"
- renderNanoseconds
- (verificationFinalVampireCompletionNanoseconds
- measurements)
- , "vampire_span_ms="
- <> maybe
- "none"
- renderNanoseconds
- (vampireExecutionSpan measurements)
- , "longest_vampire_ms="
- <> renderNanoseconds
- (verificationLongestVampireExecutionNanoseconds
- measurements)
- , "max_ready_modules=" <> renderIntegral
- (verificationMaximumReadyModuleCount
- measurements)
- , "total_ms="
- <> renderNanoseconds
- (verificationInvocationNanoseconds
- measurements)
- ]
- where
- parseMeasurements =
- verificationParseMeasurements measurements
-
- vampireExecutionSpan measured = do
- started <- verificationFirstVampireStartNanoseconds measured
- completed <- verificationFinalVampireCompletionNanoseconds measured
- pure (completed - started)
-
-renderNanoseconds :: Word64 -> Text
-renderNanoseconds nanoseconds =
- renderIntegral (nanoseconds `div` 1000000)
-
-renderIntegral :: Show number => number -> Text
-renderIntegral =
- StrictText.pack . show
-
-admittedWorkspaceReport
- :: AdmittedTypedWorkspace
- -> VerificationReport
-admittedWorkspaceReport (AdmittedTypedWorkspace modules) =
- VerificationReport
- { verificationDirectEscapes =
- concatMap admittedModuleEscapes modules
- }
-
-admittedModuleEscapes
- :: AdmittedTypedModule
- -> [ReportedEscape]
-admittedModuleEscapes (AdmittedTypedModule declarations) =
- concatMap admittedDeclarationEscapes declarations
-
-admittedDeclarationEscapes
- :: AdmittedTypedDeclaration
- -> [ReportedEscape]
-admittedDeclarationEscapes
- (AdmittedTypedDeclaration _slot declaration) =
- axiomEscape <> proofEscapes
- where
- axiomEscape =
- case Typed.typedSourceDeclarationHead declaration of
- Raw.BlockAxiom location _title _marker _axiom ->
- [ReportedEscape ReportedSourceAxiom location]
- _ ->
- []
- proofEscapes =
- maybe [] omittedProofEscapes
- (Typed.typedSourceDeclarationProof declaration)
-
-omittedProofEscapes :: Raw.Proof -> [ReportedEscape]
-omittedProofEscapes = \case
- Raw.Omitted location ->
- [ReportedEscape ReportedOmitted location]
- Raw.Qed{} ->
- []
- Raw.Contradiction{} ->
- []
- Raw.ByCase _location cases ->
- concatMap (omittedProofEscapes . Raw.caseProof) cases
- Raw.ByContradiction _location proof ->
- omittedProofEscapes proof
- Raw.BySetInduction _location _term proof ->
- omittedProofEscapes proof
- Raw.ByOrdInduction _location proof ->
- omittedProofEscapes proof
- Raw.Assume _location _statement proof ->
- omittedProofEscapes proof
- Raw.FixSymbolic _location _variables _bound proof ->
- omittedProofEscapes proof
- Raw.FixSuchThat _location _variables _statement proof ->
- omittedProofEscapes proof
- Raw.Calc _location _quantifier _calculation proof ->
- omittedProofEscapes proof
- Raw.TakeVar _location _variables _bound _statement _justification proof ->
- omittedProofEscapes proof
- Raw.TakeNoun _location _noun _justification proof ->
- omittedProofEscapes proof
- Raw.Have _location _condition _statement _justification proof ->
- omittedProofEscapes proof
- Raw.Suffices _location _statement _justification proof ->
- omittedProofEscapes proof
- Raw.Subclaim _location _statement subproof continuation ->
- omittedProofEscapes subproof <> omittedProofEscapes continuation
- Raw.Define _location _variable _expression proof ->
- omittedProofEscapes proof
- Raw.DefineFunction
- _location _function _argument _value _domainVariable _domain
- proof ->
- omittedProofEscapes proof
- Raw.DefineFunctionLocal
- _location _function _argument _domain _target _ruleVariable
- _rules proof ->
- omittedProofEscapes proof
-
-completedResult
- :: VerificationReport
- -> VerificationPresentation
- -> VerificationResult
-completedResult report presentation
- | any ((== ReportedOmitted) . reportedEscapeKind)
- (verificationDirectEscapes report) =
- CompletedWithExplicitGaps report presentation
- | otherwise =
- VerificationCompleted report presentation
-
-verify
- :: (MonadUnliftIO io, MonadLogger io)
- => Vampire
- -> FilePath
- -> io (Either VerificationDriverError VerificationResult)
-verify prover file =
- fmap fst <$> verifyMeasured prover file
-
-prepareVerifiedHtmlExportResult
- :: MonadIO io
- => VerificationPresentation
- -> io (Either HtmlExport.HtmlExportError [PreparedHtmlArtifact])
-prepareVerifiedHtmlExportResult
- (VerificationPresentation workspace) = liftIO do
- hintsResult <- findAndReadRendererFile "lexicon.tsv"
- pure do
- hints <- hintsResult
- HtmlExport.prepareHtmlExport
- defaultHtmlMountPrefixes
- workspace
- hints
-
-defaultHtmlMountPrefixes :: [(SourceMountId, [Text])]
-defaultHtmlMountPrefixes =
- [ (sourceMountId "project", [])
- , (sourceMountId "library", ["library"])
- , (sourceMountId "debug", ["debug"])
- ]