summaryrefslogtreecommitdiff
path: root/source/Api.hs
diff options
context:
space:
mode:
Diffstat (limited to 'source/Api.hs')
-rw-r--r--source/Api.hs2074
1 files changed, 1053 insertions, 1021 deletions
diff --git a/source/Api.hs b/source/Api.hs
index 430eb41..2220434 100644
--- a/source/Api.hs
+++ b/source/Api.hs
@@ -10,17 +10,21 @@ module Api
, scan
, parse
, parseWorkspace
+ , AuthorityFreeParseError(..)
+ , renderAuthorityFreeParseError
, simpleStream
, builtins
, ParseException(..)
- , gloss, GlossError(..)
- , generateTasks
- , encodeTasks
, verify, verifyMeasured
, verifyWithObserverAndStoreMode
+ , verifyMeasuredWithObserverAndStoreMode
+ , verifyWithObserverAndStoreModeAndJobs
+ , verifyMeasuredWithObserverAndStoreModeAndJobs
, StoreValidationMode(..)
- , VerificationRequestOrdinal
- , verificationRequestOrdinalValue
+ , WorkPosition
+ , workPosition
+ , workPositionModuleOrdinal
+ , workPositionLocalRequestOrdinal
, VerificationRequestObserver
, verificationRequestObserver
, ProverAnswer
@@ -31,69 +35,58 @@ module Api
)
, pattern Yes
, VerificationResult(..)
- , VerificationRoute(..)
+ , VerificationPresentation
+ , ReportedEscapeKind(..)
+ , ReportedEscape(..)
, VerificationReport(..)
, VerificationMeasurements(..)
, VerificationDriverError(..)
, FailedVerification(..)
, VerificationFailureReason(..)
- , exportHtml
- , prepareHtmlExport
- , prepareHtmlExportResult
+ , prepareVerifiedHtmlExportResult
, prepareDefaultSourceGraph
, defaultHtmlMountPrefixes
) where
import Base
-import Checking
import Checking.Declaration qualified as Declaration
import Checking.Foundation qualified as Foundation
import Checking.Identity qualified as Identity
-import Checking.Legacy qualified as Legacy
import Checking.Module qualified as Typed
-import Checking.Obligation
import Checking.Semantic qualified as Semantic
-import Checking.Transition qualified as Transition
-import Encoding
-import Felix.Migration qualified as Migration
+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 Meaning
- ( GlossError(..)
- , meaning
- )
import Provers
import Render.Html.Export qualified as HtmlExport
-import Render.Html.Output (PreparedHtmlBundle)
+import Render.Html.Output (PreparedHtmlArtifact)
import Report.Location
import Syntax.Abstract qualified as Raw
import Syntax.Adapt (scanChunk, ScannedLexicalItem)
-import Syntax.Internal qualified as Internal
import Syntax.Interface qualified as Syntax
import Syntax.Lexicon (builtins)
import Syntax.Token
-import Tptp.UnsortedFirstOrder qualified as Tptp
import Control.Exception qualified as Exception
import Control.Monad.Logger
-import Control.Monad (foldM, unless)
+import Control.Monad (unless)
import Data.Bifunctor (first)
import Data.List.NonEmpty qualified as NonEmpty
import Data.Map.Strict qualified as Map
-import Data.Set qualified as Set
import Data.Text qualified as StrictText
import Data.Text.Encoding.Error (UnicodeException)
import Data.Text.IO qualified as Text
-import Data.Vector qualified as Vector
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
@@ -234,31 +227,74 @@ scan input = do
(unTokStream tokenStream)
--- | Parse a file. Throws a 'ParseException' when tokenizing, scanning, or
--- parsing fails.
+-- | 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 throwWorkspaceError pure result
+ 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 ParseWorkspaceError [Raw.Block])
+ -> io (Either AuthorityFreeParseError [Raw.Block])
parseWorkspace file =
fmap Felix.importedBeforeImporterBlocks
- <$> liftIO (parseDefaultWorkspace file)
+ <$> liftIO (parseDefaultWorkspaceWithPrelude file)
-parseDefaultWorkspace
+parseDefaultWorkspaceWithPrelude
:: FilePath
- -> IO (Either ParseWorkspaceError ParsedSourceWorkspace)
-parseDefaultWorkspace file = do
- prepared <- prepareDefaultSourceRequest file
- case prepared of
- Left err ->
- pure (Left err)
- Right (mounts, request) ->
- Felix.parseSourceWorkspace mounts request
+ -> 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
@@ -326,81 +362,45 @@ throwWorkspaceError = \case
simpleStream :: TokStream -> [[Token]]
simpleStream TokStream{unTokStream=chunks} = [unLocated <$> ch | ch <- chunks]
--- | Parse the workspace, then gloss each module independently in
--- imported-before-importer order.
-gloss :: MonadIO io => FilePath -> io [Internal.Block]
-gloss file = do
- result <- liftIO (parseDefaultWorkspace file)
- workspace <- either throwWorkspaceError pure result
- liftIO
- (concat
- <$> traverse
- (\parsed ->
- either throwIO pure
- (meaning
- (Felix.parsedModuleBlocks parsed)))
- (toList
- (Felix.parsedWorkspaceImportedBeforeImporter
- workspace)))
-
+data VerificationResult
+ = VerificationCompleted
+ !VerificationReport
+ !VerificationPresentation
+ | CompletedWithExplicitGaps
+ !VerificationReport
+ !VerificationPresentation
+ | VerificationFailure !VerificationReport !FailedVerification
+ | VerificationCheckingFailure
+ !VerificationReport
+ !VerificationDriverError
+ deriving (Show)
-generateTasks :: MonadIO io => FilePath -> io [Internal.Task]
-generateTasks file = do
- obligations <-
- prepareCheckingTasks
- contractionTask
- file
- pure (preparedObligationTask <$> obligations)
+-- | Strict owner-independent source presentation retained only after the
+-- complete typed workspace succeeds.
+data VerificationPresentation = VerificationPresentation
+ !HtmlExport.HtmlPresentation
-prepareCheckingTasks
- :: MonadIO io
- => (Internal.Task -> Internal.Task)
- -> FilePath
- -> io [PreparedObligation]
-prepareCheckingTasks prepareTask file = do
- blocks <- gloss file
- liftIO
- (checkPrepared
- WithoutDumpPremselTraining
- prepareTask
- blocks)
-
-encodeTasks :: MonadIO io => FilePath -> io [Tptp.Task]
-encodeTasks file = do
- obligations <-
- prepareCheckingTasks
- contractionTask
- file
- pure
- [ preparedTptpSyntax
- (preparedProverTptpTask
- (preparedObligationProverTask obligation))
- | obligation <- obligations
- ]
+instance Show VerificationPresentation where
+ show _presentation =
+ "VerificationPresentation <HTML presentation>"
-data VerificationResult
- = VerifiedWithTrustedVampire !VerificationReport
- | CompletedWithExplicitGaps !VerificationReport
- | VerificationFailure !FailedVerification
- deriving (Show)
+data ReportedEscapeKind
+ = ReportedSourceAxiom
+ | ReportedOmitted
+ deriving (Show, Eq)
-data VerificationRoute
- = LegacyVerificationRoute
- | TypedVerificationRoute
+data ReportedEscape = ReportedEscape
+ { reportedEscapeKind :: !ReportedEscapeKind
+ , reportedEscapeLocation :: !Location
+ }
deriving (Show, Eq)
data VerificationReport = VerificationReport
- { verificationRoute :: !VerificationRoute
- , verificationLegacyDeclaredAssumptionCount :: !Int
- , verificationTypedDeclaredAssumptionCount :: !Int
- , verificationTrustedVampireCount :: !Int
- , verificationExplicitGapLocations :: ![Location]
- , verificationTrustedLegacyRuleCount :: !Int
- , verificationKernelProofCount :: !Int
+ { verificationDirectEscapes :: ![ReportedEscape]
}
deriving (Show, Eq)
--- | Invocation-local observation of the sequential verification pipeline.
+-- | Invocation-local observation of the verification pipeline.
--
-- Durations use the monotonic clock and are never part of fact authority or
-- deterministic verification results.
@@ -410,73 +410,76 @@ data VerificationMeasurements = VerificationMeasurements
, verificationInvocationNanoseconds :: !Word64
, verificationCheckingNanoseconds :: !Word64
, verificationModuleCount :: !Int
+ , verificationDetectedProcessorCount :: !(Maybe Int)
+ , verificationEffectiveJobs :: !Int
+ , verificationJobsOverridden :: !Bool
+ , verificationMaximumLiveModuleCheckers :: !Int
+ , verificationMaximumLiveVampireProcesses :: !Int
, verificationMaximumReadyModuleCount :: !Int
- , verificationReadyModuleWaitNanoseconds :: !Word64
, verificationObligationBatchCount :: !Int
, verificationPreparedObligationCount :: !Int
, verificationMaximumObligationBatchSize :: !Int
, verificationPreparedRequestBytes :: !Word64
, verificationVampireRunCount :: !Int
+ , verificationModuleRootHitCount :: !Int
+ , verificationModuleRootMissCount :: !Int
, verificationFirstVampireStartNanoseconds
:: !(Maybe Word64)
, verificationVampireExecutionNanoseconds :: !Word64
- , verificationReplayMeasurements
- :: !Transition.TransitionReplayMeasurements
}
deriving (Show, Eq)
data VerificationObservation = VerificationObservation
{ observedModuleCount :: !Int
- , observedReadyAt
- :: !(Map ResolvedSourceAddress Word64)
+ , observedDetectedProcessorCount :: !(Maybe Int)
+ , observedEffectiveJobs :: !Int
+ , observedJobsOverridden :: !Bool
+ , observedLiveModuleCheckers :: !Int
+ , observedMaximumLiveModuleCheckers :: !Int
+ , observedMaximumLiveVampireProcesses :: !Int
, observedMaximumReadyModuleCount :: !Int
- , observedReadyModuleWaitNanoseconds :: !Word64
, observedObligationBatchCount :: !Int
, observedPreparedObligationCount :: !Int
, observedMaximumObligationBatchSize :: !Int
, observedPreparedRequestBytes :: !Word64
, observedVampireRunCount :: !Int
+ , observedModuleRootHitCount :: !Int
+ , observedModuleRootMissCount :: !Int
, observedFirstVampireStart :: !(Maybe Word64)
, observedVampireExecutionNanoseconds :: !Word64
- , observedNextRequestOrdinal :: !Natural
}
initialVerificationObservation :: VerificationObservation
initialVerificationObservation =
VerificationObservation
{ observedModuleCount = 0
- , observedReadyAt = Map.empty
+ , observedDetectedProcessorCount = Nothing
+ , observedEffectiveJobs = 1
+ , observedJobsOverridden = False
+ , observedLiveModuleCheckers = 0
+ , observedMaximumLiveModuleCheckers = 0
+ , observedMaximumLiveVampireProcesses = 0
, observedMaximumReadyModuleCount = 0
- , observedReadyModuleWaitNanoseconds = 0
, observedObligationBatchCount = 0
, observedPreparedObligationCount = 0
, observedMaximumObligationBatchSize = 0
, observedPreparedRequestBytes = 0
, observedVampireRunCount = 0
+ , observedModuleRootHitCount = 0
+ , observedModuleRootMissCount = 0
, observedFirstVampireStart = Nothing
, observedVampireExecutionNanoseconds = 0
- , observedNextRequestOrdinal = 1
}
-newtype VerificationRequestOrdinal = VerificationRequestOrdinal Natural
- deriving (Show, Eq, Ord)
-
-verificationRequestOrdinalValue
- :: VerificationRequestOrdinal
- -> Natural
-verificationRequestOrdinalValue
- (VerificationRequestOrdinal value) =
- value
-
newtype VerificationRequestObserver = VerificationRequestObserver
{ observeVerificationRequest
- :: VerificationRequestOrdinal
+ :: WorkPosition
-> PreparedVerificationRequest
-> IO ()
}
verificationRequestObserver
- :: (VerificationRequestOrdinal
+ :: (WorkPosition
-> PreparedVerificationRequest
-> IO ())
-> VerificationRequestObserver
@@ -489,7 +492,6 @@ ignoreVerificationRequests =
data FailedVerification = FailedVerification
{ failedVerificationLocation :: !Location
- , failedVerificationFormula :: !Internal.Formula
, failedVerificationReason :: !VerificationFailureReason
}
deriving (Show)
@@ -502,58 +504,32 @@ data VerificationFailureReason
| TransportFailure !ProverProcessError
deriving (Show)
-failedVerification
- :: ( Location
- , Internal.Formula
- , Either ProverProcessError ProverAnswer
- )
- -> Maybe FailedVerification
-failedVerification (location, formula, result) =
- FailedVerification location formula <$> case result of
- 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)
-
-newtype VerificationAborted =
- VerificationAborted FailedVerification
- deriving (Show)
-
-instance Exception VerificationAborted
+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
- | VerificationGlossError
- !ResolvedSource
- !GlossError
- | VerificationCheckingError
- !ResolvedSource
- !CheckingError
- | VerificationObligationResolutionError
- !ObligationResolutionError
- | VerificationLegacyModuleError
- !Legacy.LegacyModuleStageError
- | VerificationTransitionModuleError
- !Transition.TransitionModuleError
| VerificationFoundationManifestError
!(NonEmpty Foundation.FoundationManifestError)
| VerificationMissingImportedModule
!ResolvedSourceAddress
| VerificationMissingRootModule
!ResolvedSourceAddress
- | VerificationMigrationManifestError
- !Migration.MigrationManifestError
- | VerificationMigrationRouteMismatch
- !Migration.MigrationGraphRoute
| VerificationFinalPreludeReadinessError
!Typed.FinalPreludeReadinessError
| VerificationTypedInputError
@@ -572,6 +548,9 @@ data VerificationDriverError
| VerificationValidationIntegrityError
!ResolvedSource
!Declaration.ValidationIntegrityError
+ | VerificationAdmittedViewError
+ !ResolvedSource
+ !AdmittedViewError
| VerificationParsedArtifactIntegrityError
!ResolvedSource
!Felix.ParsedArtifactIntegrityError
@@ -579,13 +558,119 @@ data VerificationDriverError
| VerificationStorePlanningFailure !Store.StorePlanningError
| VerificationStoreLifecycleFailure !Store.StoreLifecycleError
| VerificationModuleArtifactKeyError !Semantic.ModuleArtifactKeyError
+ | VerificationModuleSchedulerInvariant !Text
deriving (Show)
instance Exception VerificationDriverError
-data CheckedWorkspace
- = CheckedLegacyWorkspace !Transition.TransitionAdmittedModule
- | CheckedTypedWorkspace !Typed.SealedTypedModule
+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
@@ -601,14 +686,68 @@ verifyWithObserverAndStoreMode
-> FilePath
-> io (Either VerificationDriverError VerificationResult)
verifyWithObserverAndStoreMode store validationMode observer prover file =
- fmap fst
- <$> try
- (verifyMeasuredThrowingWithStore
- 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)
@@ -663,6 +802,7 @@ verifyMeasuredThrowing requestObserver prover file = do
(verifyMeasuredThrowingWithStore
store
FreshStoreValidation
+ sequentialJobs
requestObserver
prover
file))
@@ -675,35 +815,52 @@ verifyMeasuredThrowingWithStore
:: (MonadUnliftIO io, MonadLogger io)
=> Store.Store
-> StoreValidationMode
+ -> JobsSelection
-> VerificationRequestObserver
-> Vampire
-> FilePath
-> io (VerificationResult, VerificationMeasurements)
verifyMeasuredThrowingWithStore
- store validationMode requestObserver prover file = do
+ 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
) <-
- withRunInIO \runInIO -> do
- observationRef <-
- newIORef initialVerificationObservation
+ withRunInIO \runInIO ->
+ 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
- let resolver =
- typedVampireResolver
- runInIO
- prover
- requestObserver
- observationRef
+ preludeResolver <-
+ typedVampireResolver
+ runInIO
+ executor
+ 0
+ observationRef
preparationStart <- getMonotonicTimeNSec
prepared <-
prepareDefaultSourceRequest file
@@ -711,102 +868,72 @@ verifyMeasuredThrowingWithStore
(throwIO . VerificationWorkspaceError)
pure
let (mounts, request) = prepared
- selection <-
- either
- (throwIO . VerificationMigrationManifestError)
- pure
- (Migration.resolveMigrationSelection
- mounts
- Migration.typedMigrationModules)
- root <-
- resolveRoot mounts request
+ preparationEnd <- getMonotonicTimeNSec
+ prelude <-
+ Typed.acquireFinalPreludeSession
+ memo store foundation preludeResolver
>>= either
(throwIO
- . VerificationWorkspaceError
- . SourceWorkspaceError)
+ . VerificationFinalPreludeReadinessError)
pure
- preparationEnd <- getMonotonicTimeNSec
- prelude <-
- if Migration.migrationSelectionContains selection root
- then
- Just
- <$> (Typed.buildFinalPreludeSession
- store foundation resolver
- >>= either
- (throwIO
- . VerificationFinalPreludeReadinessError)
- pure)
- else
- pure Nothing
+ observeModuleRootAcquisition observationRef
+ (Typed.finalPreludeAcquisition prelude)
let preludeSyntax =
Typed.sealedTypedModuleSyntax
- . Typed.migrationPreludeModule
- syntaxInputs source
- | Migration.migrationSelectionContains selection source =
- maybeToList (preludeSyntax <$> prelude)
- | otherwise = []
+ (Typed.finalPreludeModule prelude)
+ syntaxInputs _source = [preludeSyntax]
(parsed, measured) <-
- Felix.parseSourceWorkspaceMeasuredWithStoreAndSyntaxInputs
+ Felix.parseSourceWorkspaceMeasuredWithStoreAndSyntaxInputsAndGraphValidation
store
mounts
request
syntaxInputs
+ (Prelude.rejectOrdinaryPreludeSourceGraph
+ (Typed.finalPreludeSource prelude))
>>= either throwParseExecutionError pure
checkingStart <- getMonotonicTimeNSec
- admitted <-
- (Right <$> case
- ( prelude
- , Migration.classifyMigrationGraph selection parsed
- ) of
- (Nothing, Migration.LegacyMigrationGraph) ->
- CheckedLegacyWorkspace
- <$> checkParsedWorkspace
- foundation
- runInIO
- prover
- requestObserver
- observationRef
- parsed
- (Just finalPrelude, Migration.TypedMigrationGraph) ->
- CheckedTypedWorkspace
- <$> checkTypedWorkspace
- foundation
- finalPrelude
- resolver
- validationMode
- observationRef
- parsed
- store
- (_, route) ->
- throwIO
- (VerificationMigrationRouteMismatch route))
- `catch`
- \(VerificationAborted failed) ->
- pure (Left failed)
+ outcome <-
+ checkTypedWorkspace
+ memo
+ storeCoordinator
+ foundation
+ prelude
+ runInIO
+ executor
+ (jobsSelectionEffectiveJobs jobsSelection)
+ validationMode
+ observationRef
+ parsed
+ store
checkingEnd <- getMonotonicTimeNSec
+ executorObserved <- vampireExecutorObservation executor
+ mergeExecutorObservation observationRef executorObserved
observed <- readIORef observationRef
pure
- ( admitted
+ ( outcome
, measured
, preparationEnd - preparationStart
, checkingStart
, checkingEnd
, observed
+ , parsed
)
let result =
case admittedResult of
- Left failed ->
- VerificationFailure failed
- Right admitted ->
- let report =
- checkedWorkspaceReport admitted
- in
- if null
- (verificationExplicitGapLocations report)
- then
- VerifiedWithTrustedVampire report
- else
- CompletedWithExplicitGaps report
+ 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
@@ -815,7 +942,6 @@ verifyMeasuredThrowingWithStore
parseMeasurements
sourcePreparation
observation
- (either (const Nothing) Just admittedResult)
logInfoN
(renderVerificationMeasurements measurements)
pure (result, measurements)
@@ -829,187 +955,205 @@ verifyMeasuredThrowingWithStore
throwIO
(VerificationParsedArtifactIntegrityError source failure)
-checkParsedWorkspace
+checkTypedWorkspace
:: forall io
. (MonadIO io, MonadLogger io)
- => Foundation.CheckedFoundation
- -> (forall a. io a -> IO a)
- -> Vampire
- -> VerificationRequestObserver
- -> IORef VerificationObservation
- -> ParsedSourceWorkspace
- -> IO Transition.TransitionAdmittedModule
-checkParsedWorkspace
- checkedFoundationValue
- runInIO
- prover
- requestObserver
- observationRef
- workspace = do
- assignments <-
- driverLegacy
- (Legacy.assignLegacyModuleOrdinals workspace)
- initializeModuleObservation
- observationRef
- assignments
- admittedByAddress <-
- foldM
- (checkModule
- checkedFoundationValue
- assignments)
- Map.empty
- (toList assignments)
- let rootAddress =
- Felix.parsedModuleAddress
- (Felix.parsedWorkspaceRootModule workspace)
- maybe
- (throwIO
- (VerificationMissingRootModule rootAddress))
- pure
- (Map.lookup rootAddress admittedByAddress)
- where
- foundation =
- initialLegacyCheckingEnvironment
-
- checkModule
- :: Foundation.CheckedFoundation
- -> NonEmpty Legacy.LegacyModuleAssignment
- -> Map
- ResolvedSourceAddress
- Transition.TransitionAdmittedModule
- -> Legacy.LegacyModuleAssignment
- -> IO
- (Map
- ResolvedSourceAddress
- Transition.TransitionAdmittedModule)
- checkModule
- moduleFoundation
- assignments
- admittedByAddress
- assignment = do
- let parsedModule =
- Legacy.assignedParsedModule assignment
- source =
- Felix.parsedModuleResolved parsedModule
- address =
- Felix.parsedModuleAddress parsedModule
- moduleStart <- getMonotonicTimeNSec
- observeModuleStart
- observationRef
- assignments
- admittedByAddress
- address
- moduleStart
- directImports <-
- traverse
- (lookupImportedModule admittedByAddress
- . Felix.parsedImportedAddress)
- (Felix.parsedModuleImports parsedModule)
- builder <-
- driverTransition
- (Transition.openTransitionModuleBuilder
- moduleFoundation
- foundation
- assignment
- directImports)
- blocks <-
- glossModule
- source
- (Felix.parsedModuleBlocks parsedModule)
- checked <- do
- checkedResult <- try
- (runCheckingBlocks
- blocks
- (initialTransitionCheckingState
- builder
- (resolvePreparedBatch
- runInIO
- prover
- requestObserver
- observationRef)))
- either
- (throwIO . VerificationCheckingError source)
- pure
- checkedResult
- finalBuilder <-
- maybe
- (impossible
- "checking lost its transition module builder")
- pure
- (checkingTransitionModuleBuilder checked)
- admitted <-
- driverTransition
- (Transition.sealTransitionModule
- (checkingStateEnvironment checked)
- finalBuilder)
- moduleEnd <- getMonotonicTimeNSec
- let admittedByAddress' =
- Map.insert address admitted admittedByAddress
- observeModuleAdmission
- observationRef
- assignments
- admittedByAddress'
- moduleEnd
- pure admittedByAddress'
-
-checkTypedWorkspace
- :: Foundation.CheckedFoundation
- -> Typed.MigrationPreludeSession
- -> Declaration.VampireResolver
+ => Store.StoreMemo
+ -> Store.StoreCoordinator
+ -> Foundation.CheckedFoundation
+ -> Typed.FinalPreludeSession
+ -> (forall value. io value -> IO value)
+ -> VampireExecutor
+ -> EffectiveJobs
-> StoreValidationMode
-> IORef VerificationObservation
-> ParsedSourceWorkspace
-> Store.Store
- -> IO Typed.SealedTypedModule
+ -> IO TypedWorkspaceOutcome
checkTypedWorkspace
- foundation prelude resolver validationMode observationRef workspace
+ memo
+ storeCoordinator
+ foundation
+ prelude
+ runInIO
+ executor
+ selectedJobs
+ validationMode
+ observationRef
+ workspace
store = do
- memo <- Store.newStoreMemo store
let modules =
- toList (Felix.parsedWorkspaceImportedBeforeImporter workspace)
- modifyIORef' observationRef \observation ->
- observation
- { observedModuleCount = length modules
- , observedMaximumReadyModuleCount =
- if null modules then 0 else 1
- }
- admittedByAddress <-
- foldM (checkModule memo) Map.empty modules
- let root = Felix.parsedWorkspaceRootModule workspace
- rootAddress = Felix.parsedModuleAddress root
- maybe
- (throwIO (VerificationMissingRootModule rootAddress))
- pure
- (Map.lookup rootAddress admittedByAddress)
+ 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
- storeValidationLookup lookupStore =
- Declaration.validationLookup
- (\key ->
- Store.loadProofValidation lookupStore key
- >>= either
- (throwIO . VerificationStoreFailure)
- pure)
- (\key ->
- Store.loadDeclarationValidation lookupStore key
- >>= either
- (throwIO . VerificationStoreFailure)
- pure)
+ workerBound = effectiveJobsValue selectedJobs
- validationRun =
- case validationMode of
- FreshStoreValidation ->
- Declaration.FreshValidation
- WarmStoreValidation ->
- Declaration.WarmValidation
- (storeValidationLookup store)
-
- checkModule memo admittedByAddress parsed = do
- let source = Felix.parsedModuleResolved parsed
- address = Felix.parsedModuleAddress parsed
- directAddresses =
+ 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 = do
+ let parsed = moduleTaskParsed task
+ source = Felix.parsedModuleResolved parsed
+ address = Felix.parsedModuleAddress parsed
direct <-
traverse
(\directAddress ->
@@ -1018,8 +1162,14 @@ checkTypedWorkspace
(VerificationMissingImportedModule
directAddress))
pure
- (Map.lookup directAddress admittedByAddress))
- directAddresses
+ (Map.lookup directAddress sealedByAddress))
+ (moduleTaskDirectAddresses task)
+ resolver <-
+ typedVampireResolver
+ runInIO
+ executor
+ (moduleTaskOrdinal task)
+ observationRef
input <-
either
(throwIO . VerificationTypedInputError source)
@@ -1031,9 +1181,16 @@ checkTypedWorkspace
validationRun
parsed
direct)
- loadCachedModule memo parsed direct >>= \case
- Just sealed ->
- pure (Map.insert address sealed admittedByAddress)
+ loadCachedModule parsed direct >>= \case
+ Just sealed -> do
+ observeModuleRootAcquisition
+ observationRef Typed.ModuleRootHit
+ pure
+ (ModuleCheckSucceeded
+ address
+ sealed
+ (completeAdmittedModule
+ (Typed.identifiedPhysicalModule parsed)))
Nothing -> do
typedResult <-
Exception.catch
@@ -1046,21 +1203,88 @@ checkTypedWorkspace
case typedResult of
Typed.TypedModuleOpenFailed err ->
throwIO (VerificationTypedOpenError source err)
- Typed.TypedModuleFailed err prefix ->
- flushPrefix prefix
- >>= either
- (throwIO . VerificationStoreFailure)
- (const
- (throwIO
- (VerificationTypedModuleError
- source
- err
- prefix)))
+ 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
- pure (Map.insert address sealed admittedByAddress)
+ 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
@@ -1080,22 +1304,24 @@ checkTypedWorkspace
(Typed.sealedTypedModuleSyntax sealed))
(Semantic.semanticInterfaceAssertedId
(Typed.sealedTypedModuleSemantic sealed))
- Store.writeSealedModule
- store
- (Typed.sealedTypedModulePrefix sealed)
- [Typed.sealedTypedModuleSyntax sealed]
- [Typed.sealedTypedModuleSemantic sealed]
- artifact
- >>= either
- (throwIO . VerificationStoreFailure)
- (\acknowledged ->
- unless
- (acknowledged == artifact)
- (throwIO
- (VerificationStoreFailure
- Store.StoreModuleArtifactIdMismatch)))
+ 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 memo parsed direct =
+ loadCachedModule parsed direct =
case validationMode of
WarmStoreValidation -> do
let owner =
@@ -1104,7 +1330,7 @@ checkTypedWorkspace
directSemantic =
Semantic.semanticInterfaceAssertedId
(Typed.sealedTypedModuleSemantic
- (Typed.migrationPreludeModule prelude))
+ (Typed.finalPreludeModule prelude))
: ( Semantic.semanticInterfaceAssertedId
. Typed.sealedTypedModuleSemantic
<$> direct
@@ -1120,386 +1346,275 @@ checkTypedWorkspace
(Typed.identifiedPhysicalModule parsed)))
directSemantic
(Identity.theoryId foundation))
- Store.loadCachedModuleInstallation
- memo
- store
- artifactKey
- (Syntax.moduleSyntaxAssertedId
- (Felix.parsedModuleSyntaxInterface parsed))
- >>= \case
+ 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) -> do
- cached <-
- either
- (throwIO
- . VerificationTypedCachedModuleError
- (Felix.parsedModuleResolved parsed))
- pure
- (Typed.cachedSealedTypedModule
- foundation
- (Typed.migrationPreludeModule prelude
- : direct)
- installation)
- pure (Just cached)
+ Right (Just installation) ->
+ either
+ (throwIO
+ . VerificationTypedCachedModuleError
+ (Felix.parsedModuleResolved parsed))
+ (pure . Just)
+ (Typed.cachedSealedTypedModule
+ foundation
+ (Typed.finalPreludeModule prelude : direct)
+ installation)
FreshStoreValidation ->
pure Nothing
- flushPrefix prefix =
- Store.writePendingModulePrefix store prefix
+ 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
:: forall io
. (MonadIO io, MonadLogger io)
=> (forall value. io value -> IO value)
- -> Vampire
- -> VerificationRequestObserver
+ -> VampireExecutor
+ -> Natural
-> IORef VerificationObservation
- -> Declaration.VampireResolver
-typedVampireResolver runInIO prover requestObserver observationRef =
- Declaration.vampireResolver \prepared -> do
- started <- getMonotonicTimeNSec
- observeVampireStart observationRef started
- let request = preparedTypedProverRequest prepared
- modifyIORef' observationRef \observation ->
- observation
+ -> IO Declaration.VampireResolver
+typedVampireResolver
+ runInIO executor moduleOrdinal observationRef = do
+ localOrdinalRef <- newIORef 1
+ pure (Declaration.vampireBatchResolver \prepared -> do
+ let batchSize = NonEmpty.length prepared
+ ordinalCount = fromIntegral batchSize
+ firstOrdinal <- atomicModifyIORef' localOrdinalRef
+ (\current -> (current + ordinalCount, current))
+ let positions =
+ NonEmpty.fromList
+ [ workPosition moduleOrdinal ordinal
+ | ordinal <-
+ [firstOrdinal .. firstOrdinal + ordinalCount - 1]
+ ]
+ positioned =
+ NonEmpty.zip positions prepared
+ preparedBytes =
+ foldl'
+ (\total task ->
+ total
+ + fromIntegral
+ (preparedVerificationByteCount
+ (preparedTypedProverRequest task)))
+ 0
+ prepared
+ atomicModifyIORef' observationRef \observation ->
+ ( observation
{ observedObligationBatchCount =
observedObligationBatchCount observation + 1
, observedPreparedObligationCount =
- observedPreparedObligationCount observation + 1
+ observedPreparedObligationCount observation + batchSize
, observedMaximumObligationBatchSize =
max
- 1
+ batchSize
(observedMaximumObligationBatchSize observation)
, observedPreparedRequestBytes =
observedPreparedRequestBytes observation
- + fromIntegral
- (preparedVerificationByteCount request)
+ + preparedBytes
}
- result <- runInIO
- (runPreparedTypedProverWithObserver
- (observeRequest observationRef requestObserver)
- prover
- prepared)
- finished <- getMonotonicTimeNSec
- observeVampireFinish observationRef (finished - started)
- pure result
-
-initializeModuleObservation
- :: IORef VerificationObservation
- -> NonEmpty Legacy.LegacyModuleAssignment
- -> IO ()
-initializeModuleObservation observationRef assignments = do
- now <- getMonotonicTimeNSec
- let ready =
- readyModuleAssignments
- assignments
- Map.empty
- modifyIORef'
- observationRef
- (\observation ->
- observation
- { observedModuleCount =
- NonEmpty.length assignments
- , observedReadyAt =
- Map.fromList
- [ (legacyAssignmentAddress assignment, now)
- | assignment <- ready
- ]
- , observedMaximumReadyModuleCount =
- length ready
- })
-
-observeModuleStart
+ , ()
+ )
+ results <-
+ Async.mapConcurrently
+ (\(position, task) ->
+ runInIO
+ (runPreparedTypedProverWithExecutor
+ executor
+ position
+ task))
+ (NonEmpty.toList positioned)
+ pure (NonEmpty.fromList results))
+
+observeModuleRootAcquisition
:: IORef VerificationObservation
- -> NonEmpty Legacy.LegacyModuleAssignment
- -> Map
- ResolvedSourceAddress
- Transition.TransitionAdmittedModule
- -> ResolvedSourceAddress
- -> Word64
+ -> Typed.ModuleRootAcquisition
-> IO ()
-observeModuleStart
- observationRef
- assignments
- admittedByAddress
- address
- now =
- modifyIORef'
- observationRef
- (\observation ->
- let
- ready =
- readyModuleAssignments
- assignments
- admittedByAddress
- readySince =
- Map.findWithDefault
- now
- address
- (observedReadyAt observation)
- in
+observeModuleRootAcquisition observationRef acquisition =
+ atomicModifyIORef' observationRef \observation ->
+ ( case acquisition of
+ Typed.ModuleRootHit ->
observation
- { observedMaximumReadyModuleCount =
- max
- (observedMaximumReadyModuleCount
- observation)
- (length ready)
- , observedReadyModuleWaitNanoseconds =
- observedReadyModuleWaitNanoseconds
- observation
- + (now - readySince)
- })
-
-observeModuleAdmission
- :: IORef VerificationObservation
- -> NonEmpty Legacy.LegacyModuleAssignment
- -> Map
- ResolvedSourceAddress
- Transition.TransitionAdmittedModule
- -> Word64
- -> IO ()
-observeModuleAdmission
- observationRef
- assignments
- admittedByAddress
- now =
- modifyIORef'
- observationRef
- (\observation ->
- let
- ready =
- readyModuleAssignments
- assignments
- admittedByAddress
- readyAt =
- foldl'
- (\known assignment ->
- Map.insertWith
- (\_new old -> old)
- (legacyAssignmentAddress assignment)
- now
- known)
- (observedReadyAt observation)
- ready
- in
+ { observedModuleRootHitCount =
+ observedModuleRootHitCount observation + 1
+ }
+ Typed.ModuleRootMiss ->
observation
- { observedReadyAt = readyAt
- , observedMaximumReadyModuleCount =
- max
- (observedMaximumReadyModuleCount
- observation)
- (length ready)
- })
-
-readyModuleAssignments
- :: NonEmpty Legacy.LegacyModuleAssignment
- -> Map
- ResolvedSourceAddress
- Transition.TransitionAdmittedModule
- -> [Legacy.LegacyModuleAssignment]
-readyModuleAssignments assignments admittedByAddress =
- [ assignment
- | assignment <- NonEmpty.toList assignments
- , legacyAssignmentAddress assignment
- `Map.notMember` admittedByAddress
- , all
- (`Map.member` admittedByAddress)
- (legacyAssignmentImportAddresses assignment)
- ]
-
-legacyAssignmentAddress
- :: Legacy.LegacyModuleAssignment
- -> ResolvedSourceAddress
-legacyAssignmentAddress =
- Felix.parsedModuleAddress
- . Legacy.assignedParsedModule
-
-legacyAssignmentImportAddresses
- :: Legacy.LegacyModuleAssignment
- -> [ResolvedSourceAddress]
-legacyAssignmentImportAddresses =
- fmap Felix.parsedImportedAddress
- . Felix.parsedModuleImports
- . Legacy.assignedParsedModule
-
-lookupImportedModule
- :: Map
- ResolvedSourceAddress
- Transition.TransitionAdmittedModule
- -> ResolvedSourceAddress
- -> IO Transition.TransitionAdmittedModule
-lookupImportedModule admittedByAddress address =
- maybe
- (throwIO
- (VerificationMissingImportedModule address))
- pure
- (Map.lookup address admittedByAddress)
-
-glossModule
- :: ResolvedSource
- -> [Raw.Block]
- -> IO [Internal.Block]
-glossModule source rawBlocks =
- either
- (throwIO . VerificationGlossError source)
- pure
- (meaning rawBlocks)
+ { observedModuleRootMissCount =
+ observedModuleRootMissCount observation + 1
+ }
+ , ()
+ )
-resolvePreparedBatch
- :: forall io
- . (MonadIO io, MonadLogger io)
- => (forall a. io a -> IO a)
- -> Vampire
- -> VerificationRequestObserver
- -> IORef VerificationObservation
- -> PreparedObligationBatch
- -> IO ResolvedObligationBatch
-resolvePreparedBatch
- runInIO prover requestObserver observationRef batch = do
- observePreparedBatch observationRef batch
- resolved <-
- traverse
- resolveObligation
- (preparedBatchObligations batch)
- driverResolution
- (resolveObligationBatch batch resolved)
- where
- resolveObligation obligation =
- case preparedObligationMethod obligation of
- RecordExplicitGap{} ->
- driverResolution
- (resolveObligationAsGap obligation)
- ProveWithVampire -> do
- started <- getMonotonicTimeNSec
- observeVampireStart
- observationRef
- started
- result <-
- runInIO
- (runPreparedProverWithObserver
- (observeRequest
- observationRef
- requestObserver)
- prover
- (preparedObligationProverTask
- obligation))
- finished <- getMonotonicTimeNSec
- observeVampireFinish
- observationRef
- (finished - started)
- case failedVerification result of
- Just failed ->
- throwIO (VerificationAborted failed)
- Nothing ->
- case result of
- ( _location
- , _formula
- , Right answer
- )
- | Just accepted <-
- provedVampireRun answer ->
- driverResolution
- (resolveObligationWithVampire
- obligation
- accepted)
- _ ->
- impossible
- "successful prover result has no accepted Vampire run"
-
-observeRequest
+observeReadyModules
:: IORef VerificationObservation
- -> VerificationRequestObserver
- -> PreparedVerificationRequest
+ -> Int
-> IO ()
-observeRequest observationRef observer request = do
- ordinal <- atomicModifyIORef' observationRef \observation ->
- let current = observedNextRequestOrdinal observation
+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
- { observedNextRequestOrdinal = current + 1
+ { observedLiveModuleCheckers = live
+ , observedMaximumLiveModuleCheckers =
+ max live
+ (observedMaximumLiveModuleCheckers observation)
}
- , VerificationRequestOrdinal current
+ , ()
)
- observeVerificationRequest observer ordinal request
-
-observePreparedBatch
+ action `Exception.finally`
+ atomicModifyIORef' observationRef
+ (\observation ->
+ ( observation
+ { observedLiveModuleCheckers =
+ observedLiveModuleCheckers observation - 1
+ }
+ , ()
+ ))
+
+mergeExecutorObservation
:: IORef VerificationObservation
- -> PreparedObligationBatch
+ -> VampireExecutorObservation
-> IO ()
-observePreparedBatch observationRef batch =
- modifyIORef'
- observationRef
- (\observation ->
- observation
- { observedObligationBatchCount =
- observedObligationBatchCount observation
- + 1
- , observedPreparedObligationCount =
- observedPreparedObligationCount observation
- + obligationCount
- , observedMaximumObligationBatchSize =
- max
- (observedMaximumObligationBatchSize
- observation)
- obligationCount
- , observedPreparedRequestBytes =
- observedPreparedRequestBytes observation
- + requestBytes
- })
- where
- obligations =
- preparedBatchObligations batch
- obligationCount =
- Vector.length obligations
- requestBytes =
- Vector.foldl'
- (\total obligation ->
- total
- + fromIntegral
- (preparedVerificationByteCount
- (preparedProverRequest
- (preparedObligationProverTask
- obligation))))
- 0
- obligations
-
-observeVampireStart
- :: IORef VerificationObservation
- -> Word64
- -> IO ()
-observeVampireStart observationRef started =
- modifyIORef'
- observationRef
- (\observation ->
- observation
- { observedVampireRunCount =
- observedVampireRunCount observation
- + 1
- , observedFirstVampireStart =
- case observedFirstVampireStart observation of
- Nothing ->
- Just started
- firstStart ->
- firstStart
- })
-
-observeVampireFinish
- :: IORef VerificationObservation
- -> Word64
- -> IO ()
-observeVampireFinish observationRef duration =
- modifyIORef'
- observationRef
- (\observation ->
- observation
- { observedVampireExecutionNanoseconds =
- observedVampireExecutionNanoseconds
- observation
- + duration
- })
+mergeExecutorObservation observationRef executorObserved =
+ atomicModifyIORef' observationRef \observation ->
+ ( observation
+ { observedVampireRunCount =
+ vampireExecutorRunCount executorObserved
+ , observedMaximumLiveVampireProcesses =
+ vampireExecutorMaximumLiveCount executorObserved
+ , observedFirstVampireStart =
+ vampireExecutorFirstStartNanoseconds executorObserved
+ , observedVampireExecutionNanoseconds =
+ vampireExecutorExecutionNanoseconds executorObserved
+ }
+ , ()
+ )
finalizeVerificationMeasurements
:: Word64
@@ -1508,7 +1623,6 @@ finalizeVerificationMeasurements
-> Felix.ParseMeasurements
-> Word64
-> VerificationObservation
- -> Maybe CheckedWorkspace
-> VerificationMeasurements
finalizeVerificationMeasurements
invocationStart
@@ -1516,8 +1630,7 @@ finalizeVerificationMeasurements
checkingEnd
parseMeasurements
sourcePreparation
- observation
- admitted =
+ observation =
VerificationMeasurements
{ verificationParseMeasurements =
parseMeasurements
@@ -1529,10 +1642,18 @@ finalizeVerificationMeasurements
checkingEnd - checkingStart
, verificationModuleCount =
observedModuleCount observation
+ , verificationDetectedProcessorCount =
+ observedDetectedProcessorCount observation
+ , verificationEffectiveJobs =
+ observedEffectiveJobs observation
+ , verificationJobsOverridden =
+ observedJobsOverridden observation
+ , verificationMaximumLiveModuleCheckers =
+ observedMaximumLiveModuleCheckers observation
+ , verificationMaximumLiveVampireProcesses =
+ observedMaximumLiveVampireProcesses observation
, verificationMaximumReadyModuleCount =
observedMaximumReadyModuleCount observation
- , verificationReadyModuleWaitNanoseconds =
- observedReadyModuleWaitNanoseconds observation
, verificationObligationBatchCount =
observedObligationBatchCount observation
, verificationPreparedObligationCount =
@@ -1543,20 +1664,16 @@ finalizeVerificationMeasurements
observedPreparedRequestBytes observation
, verificationVampireRunCount =
observedVampireRunCount observation
+ , verificationModuleRootHitCount =
+ observedModuleRootHitCount observation
+ , verificationModuleRootMissCount =
+ observedModuleRootMissCount observation
, verificationFirstVampireStartNanoseconds =
fmap
(\started -> started - invocationStart)
(observedFirstVampireStart observation)
, verificationVampireExecutionNanoseconds =
observedVampireExecutionNanoseconds observation
- , verificationReplayMeasurements =
- case admitted of
- Just (CheckedLegacyWorkspace legacy) ->
- Transition.transitionAdmittedReplayMeasurements legacy
- Just (CheckedTypedWorkspace _typed) ->
- emptyReplayMeasurements
- Nothing ->
- emptyReplayMeasurements
}
renderVerificationMeasurements
@@ -1607,6 +1724,21 @@ renderVerificationMeasurements measurements =
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)
@@ -1634,6 +1766,10 @@ renderVerificationMeasurements measurements =
(verificationPreparedRequestBytes measurements)
, "vampire_runs=" <> renderIntegral
(verificationVampireRunCount measurements)
+ , "module_root_hits=" <> renderIntegral
+ (verificationModuleRootHitCount measurements)
+ , "module_root_misses=" <> renderIntegral
+ (verificationModuleRootMissCount measurements)
, "first_vampire_ms="
<> maybe
"none"
@@ -1644,43 +1780,9 @@ renderVerificationMeasurements measurements =
<> renderNanoseconds
(verificationVampireExecutionNanoseconds
measurements)
- , "vampire_idle_ms="
- <> renderNanoseconds
- (verificationVampireIdleNanoseconds
- measurements)
- , "vampire_utilization_permille="
- <> renderIntegral
- (verificationVampireUtilizationPermille
- measurements)
, "max_ready_modules=" <> renderIntegral
(verificationMaximumReadyModuleCount
measurements)
- , "ready_wait_sum_ms="
- <> renderNanoseconds
- (verificationReadyModuleWaitNanoseconds
- measurements)
- , "kernel_replays=" <> renderIntegral
- (Transition.transitionKernelReplayCount replay)
- , "kernel_replay_nodes=" <> renderIntegral
- (Transition.transitionKernelReplayNodeCount replay)
- , "kernel_replay_max_depth=" <> renderIntegral
- (Transition.transitionKernelReplayMaximumDepth replay)
- , "reconstructions=" <> renderIntegral
- (Transition.transitionReconstructionCount replay)
- , "connection_search_work=" <> renderIntegral
- (Transition.transitionReconstructionSearchWork
- replay)
- , "connection_derived_atoms=" <> renderIntegral
- (Transition.transitionReconstructionDerivedAtomCount
- replay)
- , "connection_max_candidate_depth=" <> renderIntegral
- (Transition.transitionReconstructionMaximumCandidateDepth
- replay)
- , "connection_replay_nodes=" <> renderIntegral
- (Transition.transitionConnectionReplayNodeCount replay)
- , "connection_replay_max_depth=" <> renderIntegral
- (Transition.transitionConnectionReplayMaximumDepth
- replay)
, "total_ms="
<> renderNanoseconds
(verificationInvocationNanoseconds
@@ -1689,52 +1791,6 @@ renderVerificationMeasurements measurements =
where
parseMeasurements =
verificationParseMeasurements measurements
- replay =
- verificationReplayMeasurements measurements
-
-emptyReplayMeasurements
- :: Transition.TransitionReplayMeasurements
-emptyReplayMeasurements =
- Transition.TransitionReplayMeasurements
- { Transition.transitionKernelReplayCount = 0
- , Transition.transitionKernelReplayNodeCount = 0
- , Transition.transitionKernelReplayMaximumDepth = 0
- , Transition.transitionReconstructionCount = 0
- , Transition.transitionReconstructionSearchWork = 0
- , Transition.transitionReconstructionDerivedAtomCount = 0
- , Transition.transitionReconstructionMaximumCandidateDepth = 0
- , Transition.transitionConnectionReplayNodeCount = 0
- , Transition.transitionConnectionReplayMaximumDepth = 0
- }
-
-verificationVampireIdleNanoseconds
- :: VerificationMeasurements
- -> Word64
-verificationVampireIdleNanoseconds measurements =
- checking - min checking execution
- where
- checking =
- verificationCheckingNanoseconds measurements
- execution =
- verificationVampireExecutionNanoseconds
- measurements
-
-verificationVampireUtilizationPermille
- :: VerificationMeasurements
- -> Word64
-verificationVampireUtilizationPermille measurements
- | checking == 0 =
- 0
- | otherwise =
- min
- 1000
- (execution * 1000 `div` checking)
- where
- checking =
- verificationCheckingNanoseconds measurements
- execution =
- verificationVampireExecutionNanoseconds
- measurements
renderNanoseconds :: Word64 -> Text
renderNanoseconds nanoseconds =
@@ -1744,78 +1800,93 @@ renderIntegral :: Show number => number -> Text
renderIntegral =
StrictText.pack . show
-driverLegacy
- :: Either Legacy.LegacyModuleStageError value
- -> IO value
-driverLegacy =
- either
- (throwIO . VerificationLegacyModuleError)
- pure
-
-driverTransition
- :: Either Transition.TransitionModuleError value
- -> IO value
-driverTransition =
- either
- (throwIO . VerificationTransitionModuleError)
- pure
-
-driverResolution
- :: Either ObligationResolutionError value
- -> IO value
-driverResolution =
- either
- (throwIO . VerificationObligationResolutionError)
- pure
-
-checkedWorkspaceReport :: CheckedWorkspace -> VerificationReport
-checkedWorkspaceReport = \case
- CheckedLegacyWorkspace admitted ->
- legacyVerificationReport admitted
- CheckedTypedWorkspace _admitted ->
- VerificationReport
- { verificationRoute = TypedVerificationRoute
- , verificationLegacyDeclaredAssumptionCount = 0
- , verificationTypedDeclaredAssumptionCount = 0
- , verificationTrustedVampireCount = 0
- , verificationExplicitGapLocations = []
- , verificationTrustedLegacyRuleCount = 0
- , verificationKernelProofCount = 0
- }
-
-legacyVerificationReport
- :: Transition.TransitionAdmittedModule
+admittedWorkspaceReport
+ :: AdmittedTypedWorkspace
-> VerificationReport
-legacyVerificationReport admitted =
+admittedWorkspaceReport (AdmittedTypedWorkspace modules) =
VerificationReport
- { verificationRoute = LegacyVerificationRoute
- , verificationLegacyDeclaredAssumptionCount =
- Set.size
- (Legacy.legacyDeclaredAssumptionUses trust)
- , verificationTypedDeclaredAssumptionCount =
- Set.size
- (Transition.typedDeclaredAssumptionUses
- (Transition.transitionAdmittedTypedTrustDependencies
- admitted))
- , verificationTrustedVampireCount =
- Set.size
- (Legacy.legacyTrustedVampireUses trust)
- + Transition.transitionAdmittedTypedTrustedVampireCount
- admitted
- , verificationExplicitGapLocations =
- Legacy.legacyGapLocations trust
- , verificationTrustedLegacyRuleCount =
- Set.size
- (Legacy.trustedLegacyRuleUses trust)
- , verificationKernelProofCount =
- Transition.transitionAdmittedKernelProofCount
- admitted
+ { verificationDirectEscapes =
+ concatMap admittedModuleEscapes modules
}
+
+admittedModuleEscapes
+ :: AdmittedTypedModule
+ -> [ReportedEscape]
+admittedModuleEscapes (AdmittedTypedModule declarations) =
+ concatMap admittedDeclarationEscapes declarations
+
+admittedDeclarationEscapes
+ :: AdmittedTypedDeclaration
+ -> [ReportedEscape]
+admittedDeclarationEscapes
+ (AdmittedTypedDeclaration _slot declaration) =
+ axiomEscape <> proofEscapes
where
- trust =
- Legacy.legacyAdmittedTrustDependencies
- (Transition.transitionAdmittedLegacyModule
- admitted)
+ 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)
@@ -1825,58 +1896,19 @@ verify
verify prover file =
fmap fst <$> verifyMeasured prover file
-exportHtml :: MonadUnliftIO io => FilePath -> io Text
-exportHtml file =
- HtmlExport.preparedHtmlRootDocument
- <$> prepareDefaultHtmlExport file
-
-prepareHtmlExport
- :: MonadUnliftIO io
- => FilePath
- -> io PreparedHtmlBundle
-prepareHtmlExport file =
- prepareHtmlExportResult file
- >>= either throwIO pure
-
-prepareHtmlExportResult
- :: MonadUnliftIO io
- => FilePath
- -> io (Either HtmlExport.HtmlExportError PreparedHtmlBundle)
-prepareHtmlExportResult file =
- fmap HtmlExport.preparedHtmlOutputBundle
- <$> prepareDefaultHtmlExportResult file
-
-prepareDefaultHtmlExport
- :: MonadUnliftIO io
- => FilePath
- -> io HtmlExport.PreparedHtmlExport
-prepareDefaultHtmlExport file = do
- result <- prepareDefaultHtmlExportResult file
- either throwIO pure result
-
-prepareDefaultHtmlExportResult
- :: MonadUnliftIO io
- => FilePath
- -> io (Either HtmlExport.HtmlExportError HtmlExport.PreparedHtmlExport)
-prepareDefaultHtmlExportResult file = do
- hintsResult <- liftIO (findAndReadRendererFile "lexicon.tsv")
- case hintsResult of
- Left failure ->
- pure (Left failure)
- Right hints -> do
- prepared <- liftIO (prepareDefaultSourceRequest file)
- case prepared of
- Left parseFailure ->
- pure
- (Left
- (HtmlExport.HtmlExportParseError parseFailure))
- Right (mounts, request) ->
- liftIO
- (HtmlExport.prepareHtmlExport
- defaultHtmlMountPrefixes
- mounts
- request
- hints)
+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 =