@@ -2,11 +2,16 @@ module Main (main) where
22
33import Control.Lens qualified as Lens
44import Control.Monad.Catch (
5- MonadMask ,
65 handle ,
76 throwM ,
87 )
98import Control.Monad.Extra as Monad
9+ import Data.Compact (
10+ compactWithSharing ,
11+ )
12+ import Data.Compact.Serialize (
13+ writeCompact ,
14+ )
1015import Data.Default (
1116 def ,
1217 )
@@ -25,6 +30,9 @@ import Data.Set.Internal qualified as Set
2530import Data.Text (
2631 unpack ,
2732 )
33+ import Data.Time.Clock (
34+ UTCTime (.. ),
35+ )
2836import GHC.Generics qualified as GHC
2937import GlobalMain
3038import Kore.Attribute.Definition (
@@ -53,8 +61,6 @@ import Kore.Internal.TermLike (
5361 )
5462import Kore.Log (
5563 KoreLogOptions (.. ),
56- LogMessage ,
57- WithLog ,
5864 parseKoreLogOptions ,
5965 runKoreLog ,
6066 unparseKoreLogOptions ,
@@ -72,6 +78,9 @@ import Kore.Log.WarnIfLowProductivity (
7278import Kore.ModelChecker.Bounded qualified as Bounded (
7379 CheckResult (.. ),
7480 )
81+ import Kore.Options (
82+ enableDisableFlag ,
83+ )
7584import Kore.Parser.ParserUtils (
7685 readPositiveIntegral ,
7786 )
@@ -128,7 +137,6 @@ import Options.Applicative qualified as Options
128137import Options.Applicative.Help.Pretty qualified as OptPretty
129138import Options.SMT (
130139 KoreSolverOptions (.. ),
131- Solver (.. ),
132140 ensureSmtPreludeExists ,
133141 parseKoreSolverOptions ,
134142 unparseKoreSolverOptions ,
@@ -140,13 +148,6 @@ import Pretty (
140148 hPutDoc ,
141149 putDoc ,
142150 )
143- import Prof (
144- MonadProf ,
145- )
146- import SMT (
147- MonadSMT ,
148- )
149- import SMT qualified
150151import Stats
151152import System.Clock (
152153 Clock (Monotonic ),
@@ -157,12 +158,16 @@ import System.Directory (
157158 copyFile ,
158159 doesFileExist ,
159160 emptyPermissions ,
161+ getModificationTime ,
160162 setOwnerExecutable ,
161163 setOwnerReadable ,
162164 setOwnerSearchable ,
163165 setOwnerWritable ,
164166 setPermissions ,
165167 )
168+ import System.Environment (
169+ getExecutablePath ,
170+ )
166171import System.Exit (
167172 exitWith ,
168173 )
@@ -280,6 +285,7 @@ data KoreExecOptions = KoreExecOptions
280285 , rtsStatistics :: ! (Maybe FilePath )
281286 , bugReportOption :: ! BugReportOption
282287 , maxCounterexamples :: Natural
288+ , serialize :: ! Bool
283289 }
284290 deriving stock (GHC.Generic )
285291
@@ -324,6 +330,12 @@ parseKoreExecOptions startTime =
324330 <*> optional parseRtsStatistics
325331 <*> parseBugReportOption
326332 <*> parseMaxCounterexamples
333+ <*> enableDisableFlag
334+ " serialize"
335+ True
336+ False
337+ False
338+ " serialization of initialized definition to disk. [default: disabled]"
327339 parseMaxCounterexamples = counterexamples <|> pure 1
328340 where
329341 counterexamples =
@@ -441,6 +453,7 @@ koreExecSh
441453 rtsStatistics
442454 _
443455 maxCounterexamples
456+ _
444457 ) =
445458 unlines $
446459 [ " #!/bin/sh"
@@ -540,19 +553,21 @@ envName = "KORE_EXEC_OPTS"
540553main :: IO ()
541554main = do
542555 startTime <- getTime Monotonic
556+ exePath <- getExecutablePath
557+ exeLastModifiedTime <- getModificationTime exePath
543558 options <-
544559 mainGlobal
545560 Main. exeName
546561 (Just envName)
547562 (parseKoreExecOptions startTime)
548563 parserInfoModifiers
549- for_ (localOptions options) mainWithOptions
564+ for_ (localOptions options) $ mainWithOptions exeLastModifiedTime
550565
551566{- | Use the parsed 'KoreExecOptions' to set up output and logging, then
552567dispatch the requested command.
553568-}
554- mainWithOptions :: LocalOptions KoreExecOptions -> IO ()
555- mainWithOptions LocalOptions {execOptions, simplifierx} = do
569+ mainWithOptions :: UTCTime -> LocalOptions KoreExecOptions -> IO ()
570+ mainWithOptions exeLastModifiedTime LocalOptions {execOptions, simplifierx} = do
556571 let KoreExecOptions {koreSolverOptions, bugReportOption, outputFileName} =
557572 execOptions
558573 ensureSmtPreludeExists koreSolverOptions
@@ -564,7 +579,7 @@ mainWithOptions LocalOptions{execOptions, simplifierx} = do
564579 }
565580 writeOptionsAndKoreFiles tmpDir execOptions'
566581 e <-
567- mainDispatch LocalOptions {execOptions = execOptions', simplifierx}
582+ mainDispatch exeLastModifiedTime LocalOptions {execOptions = execOptions', simplifierx}
568583 & handle handleWithConfiguration
569584 & handle handleSomeException
570585 & runKoreLog
@@ -603,8 +618,8 @@ mainWithOptions LocalOptions{execOptions, simplifierx} = do
603618 throwM someException
604619
605620-- | Dispatch the requested command, for example 'koreProve' or 'koreRun'.
606- mainDispatch :: LocalOptions KoreExecOptions -> Main ExitCode
607- mainDispatch = warnProductivity . mainDispatchWorker
621+ mainDispatch :: UTCTime -> LocalOptions KoreExecOptions -> Main ExitCode
622+ mainDispatch exeLastModifiedTime = warnProductivity . mainDispatchWorker
608623 where
609624 warnProductivity :: Main (KFileLocations , ExitCode ) -> Main ExitCode
610625 warnProductivity action = do
@@ -620,59 +635,92 @@ mainDispatch = warnProductivity . mainDispatchWorker
620635 then koreBmc localOptions proveOptions
621636 else koreProve localOptions proveOptions
622637 | Just searchOptions <- koreSearchOptions =
623- koreSearch localOptions searchOptions
638+ koreSearch exeLastModifiedTime localOptions searchOptions
639+ | True <- serialize =
640+ koreSerialize localOptions
624641 | otherwise =
625- koreRun localOptions
642+ koreRun exeLastModifiedTime localOptions
626643 where
627644 KoreExecOptions {koreProveOptions} = execOptions
628645 KoreExecOptions {koreSearchOptions} = execOptions
646+ KoreExecOptions {serialize} = execOptions
629647
630648koreSearch ::
649+ UTCTime ->
631650 LocalOptions KoreExecOptions ->
632651 KoreSearchOptions ->
633652 Main (KFileLocations , ExitCode )
634- koreSearch LocalOptions {execOptions, simplifierx} searchOptions = do
653+ koreSearch exeLastModifiedTime LocalOptions {execOptions, simplifierx} searchOptions = do
635654 let KoreExecOptions {definitionFileName} = execOptions
636- definition <- loadDefinitions [definitionFileName]
637655 let KoreExecOptions {mainModuleName} = execOptions
638- mainModule <- loadModule mainModuleName definition
656+ let KoreExecOptions {koreSolverOptions} = execOptions
657+ SerializedDefinition {serializedModule, lemmas, locations} <-
658+ deserializeDefinition simplifierx koreSolverOptions definitionFileName mainModuleName exeLastModifiedTime
659+ let SerializedModule {verifiedModule, metadataTools} = serializedModule
639660 let KoreSearchOptions {searchFileName} = searchOptions
640- target <- mainParseSearchPattern mainModule searchFileName
661+ target <- mainParseSearchPattern verifiedModule searchFileName
641662 let KoreExecOptions {patternFileName} = execOptions
642- initial <- loadPattern mainModule patternFileName
663+ initial <- loadPattern verifiedModule patternFileName
643664 final <-
644- execute execOptions mainModule $
665+ execute koreSolverOptions metadataTools lemmas $
645666 search
646667 simplifierx
647668 depthLimit
648669 breadthLimit
649- mainModule
670+ serializedModule
650671 initial
651672 target
652673 config
653674 lift $ renderResult execOptions (unparse final)
654- return (kFileLocations definition , ExitSuccess )
675+ return (locations , ExitSuccess )
655676 where
656677 KoreSearchOptions {bound, searchType} = searchOptions
657678 config = Search. Config {bound, searchType}
658679 KoreExecOptions {breadthLimit, depthLimit} = execOptions
659680
660- koreRun :: LocalOptions KoreExecOptions -> Main (KFileLocations , ExitCode )
661- koreRun LocalOptions {execOptions, simplifierx} = do
681+ koreRun :: UTCTime -> LocalOptions KoreExecOptions -> Main (KFileLocations , ExitCode )
682+ koreRun exeLastModifiedTime LocalOptions {execOptions, simplifierx} = do
662683 let KoreExecOptions {definitionFileName} = execOptions
663- definition <- loadDefinitions [definitionFileName]
664684 let KoreExecOptions {mainModuleName} = execOptions
665- mainModule <- loadModule mainModuleName definition
685+ let KoreExecOptions {koreSolverOptions} = execOptions
686+ SerializedDefinition {serializedModule, lemmas, locations} <-
687+ deserializeDefinition simplifierx koreSolverOptions definitionFileName mainModuleName exeLastModifiedTime
688+ let SerializedModule {verifiedModule, metadataTools} = serializedModule
666689 let KoreExecOptions {patternFileName} = execOptions
667- initial <- loadPattern mainModule patternFileName
690+ initial <- loadPattern verifiedModule patternFileName
668691 (exitCode, final) <-
669- execute execOptions mainModule $
670- exec simplifierx depthLimit breadthLimit mainModule strategy initial
692+ execute koreSolverOptions metadataTools lemmas $
693+ exec
694+ simplifierx
695+ depthLimit
696+ breadthLimit
697+ serializedModule
698+ strategy
699+ initial
671700 lift $ renderResult execOptions (unparse final)
672- return (kFileLocations definition , exitCode)
701+ return (locations , exitCode)
673702 where
674703 KoreExecOptions {breadthLimit, depthLimit, strategy} = execOptions
675704
705+ -- kore-exec --serialize calls this function in order to construct the definition to serialize
706+ -- and write it to the output file specified by the user. It is an error to not specify an output
707+ -- file as binary data cannot be displayed on the terminal. We put this functionality in the
708+ -- kore-exec binary because that's where most of the logic it needed in order to function already
709+ -- lived.
710+ koreSerialize :: LocalOptions KoreExecOptions -> Main (KFileLocations , ExitCode )
711+ koreSerialize LocalOptions {execOptions, simplifierx} = do
712+ let KoreExecOptions {definitionFileName} = execOptions
713+ let KoreExecOptions {mainModuleName} = execOptions
714+ let KoreExecOptions {outputFileName} = execOptions
715+ let KoreExecOptions {koreSolverOptions} = execOptions
716+ serializedDefinition@ SerializedDefinition {locations} <- makeSerializedDefinition simplifierx koreSolverOptions definitionFileName mainModuleName
717+ case outputFileName of
718+ Nothing -> return (locations, ExitFailure 1 )
719+ Just outputFile -> do
720+ compact <- compactWithSharing serializedDefinition & liftIO
721+ writeCompact outputFile compact & liftIO
722+ return (locations, ExitSuccess )
723+
676724koreProve ::
677725 LocalOptions KoreExecOptions ->
678726 KoreProveOptions ->
@@ -689,7 +737,8 @@ koreProve LocalOptions{execOptions, simplifierx} proveOptions = do
689737 let KoreProveOptions {saveProofs} = proveOptions
690738 maybeAlreadyProvenModule <- loadProven definitionFileName saveProofs
691739 let KoreExecOptions {maxCounterexamples} = execOptions
692- proveResult <- execute execOptions mainModule' $ do
740+ let KoreExecOptions {koreSolverOptions} = execOptions
741+ proveResult <- execute koreSolverOptions (MetadataTools. build mainModule) (getSMTLemmas mainModule) $ do
693742 let KoreExecOptions {breadthLimit, depthLimit} = execOptions
694743 KoreProveOptions {graphSearch, finalNodeType} = proveOptions
695744 prove
@@ -794,8 +843,9 @@ koreBmc LocalOptions{execOptions, simplifierx} proveOptions = do
794843 let KoreExecOptions {mainModuleName} = execOptions
795844 mainModule <- loadModule mainModuleName definition
796845 let KoreProveOptions {specMainModule} = proveOptions
846+ let KoreExecOptions {koreSolverOptions} = execOptions
797847 specModule <- loadModule specMainModule definition
798- (exitCode, final) <- execute execOptions mainModule $ do
848+ (exitCode, final) <- execute koreSolverOptions ( MetadataTools. build mainModule) (getSMTLemmas mainModule) $ do
799849 let KoreExecOptions {breadthLimit, depthLimit} = execOptions
800850 KoreProveOptions {graphSearch} = proveOptions
801851 checkResult <-
@@ -818,46 +868,7 @@ koreBmc LocalOptions{execOptions, simplifierx} proveOptions = do
818868 failure pat = (ExitFailure 1 , pat)
819869 success = (ExitSuccess , mkTop $ mkSortVariable " R" )
820870
821- type MonadExecute exe =
822- ( MonadMask exe
823- , MonadIO exe
824- , MonadSMT exe
825- , MonadProf exe
826- , WithLog LogMessage exe
827- )
828-
829- -- | Run the worker in the context of the main module.
830- execute ::
831- forall r .
832- KoreExecOptions ->
833- -- | Main module
834- LoadedModule ->
835- -- | Worker
836- (forall exe . MonadExecute exe => exe r ) ->
837- Main r
838- execute options mainModule worker =
839- clockSomethingIO " Executing" $
840- case solver of
841- Z3 -> withZ3
842- None -> withoutSMT
843- where
844- withZ3 =
845- SMT. runSMT
846- config
847- (declareSMTLemmas (MetadataTools. build mainModule) mainModule)
848- worker
849- withoutSMT = SMT. runNoSMT worker
850- KoreSolverOptions {timeOut, rLimit, resetInterval, prelude, solver} =
851- Lens. view (field @ " koreSolverOptions" ) options
852- config =
853- SMT. defaultConfig
854- { SMT. timeOut = timeOut
855- , SMT. rLimit = rLimit
856- , SMT. resetInterval = resetInterval
857- , SMT. prelude = prelude
858- }
859-
860- loadPattern :: LoadedModule -> Maybe FilePath -> Main (TermLike VariableName )
871+ loadPattern :: LoadedModuleSyntax -> Maybe FilePath -> Main (TermLike VariableName )
861872loadPattern mainModule (Just fileName) =
862873 mainPatternParseAndVerify mainModule fileName
863874loadPattern _ Nothing = error " Missing: --pattern PATTERN_FILE"
0 commit comments