Skip to content

Commit 4dd38d9

Browse files
ana-pantiliegithub-actionsandreiburdusa
authored
Match disjunction tool (#2697)
Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Andrei Burdușa <andrei.burdusa@zoho.com>
1 parent 9e0a81c commit 4dd38d9

File tree

10 files changed

+401
-52
lines changed

10 files changed

+401
-52
lines changed

hie-cabal.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ cradle:
99
- { path: "./kore/app/parser", component: "kore:kore-parser" }
1010
- { path: "./kore/app/prof", component: "kore:kore-prof" }
1111
- { path: "./kore/app/repl", component: "kore:kore-repl" }
12+
- { path: "./kore/app/match-disjunction", component: "kore:kore-match-disjunction" }

hie-stack.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ cradle:
99
- { path: "./kore/app/parser", component: "kore:kore-parser" }
1010
- { path: "./kore/app/prof", component: "kore:kore-prof" }
1111
- { path: "./kore/app/repl", component: "kore:kore-repl" }
12+
- { path: "./kore/app/match-disjunction", component: "kore:kore-match-disjunction" }

kore/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ ghcid:
4646
ghcid-repl:
4747
$(stack) exec -- ghcid -c "stack ghci $(package) --test --ghci-options='-fobject-code -fno-warn-unused-do-bind' --main-is $(package):kore-repl --work-dir .stack-work-ghci"
4848

49+
ghcid-match:
50+
$(stack) exec -- ghcid -c "stack ghci $(package) --test --ghci-options='-fobject-code -fno-warn-unused-do-bind' --main-is $(package):kore-match-disjunction --work-dir .stack-work-ghci"
4951

5052
# TODO(Vladimir): remove 'hyperlink-source' when we upgrade from lts-12.10 (8.4.3)
5153
hoogle-gen:

kore/app/exec/Main.hs

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,11 @@ import Kore.Internal.MultiAnd (
5555
)
5656
import qualified Kore.Internal.MultiAnd as MultiAnd
5757
import qualified Kore.Internal.OrPattern as OrPattern
58-
import Kore.Internal.Pattern (
59-
Conditional (..),
60-
Pattern,
61-
)
62-
import Kore.Internal.Predicate (
63-
makePredicate,
64-
)
6558
import Kore.Internal.TermLike (
6659
TermLike,
6760
VariableName,
6861
mkSortVariable,
6962
mkTop,
70-
pattern And_,
7163
)
7264
import Kore.Log (
7365
KoreLogOptions (..),
@@ -91,10 +83,6 @@ import Kore.Log.WarnIfLowProductivity (
9183
import qualified Kore.ModelChecker.Bounded as Bounded (
9284
CheckResult (..),
9385
)
94-
import Kore.Parser (
95-
ParsedPattern,
96-
parseKorePattern,
97-
)
9886
import Kore.Parser.ParserUtils (
9987
readPositiveIntegral,
10088
)
@@ -161,7 +149,6 @@ import Options.SMT (
161149
import Prelude.Kore
162150
import Pretty (
163151
Doc,
164-
Pretty (..),
165152
hPutDoc,
166153
putDoc,
167154
vsep,
@@ -919,48 +906,12 @@ loadPattern mainModule (Just fileName) =
919906
mainPatternParseAndVerify mainModule fileName
920907
loadPattern _ Nothing = error "Missing: --pattern PATTERN_FILE"
921908

922-
{- | IO action that parses a kore pattern from a filename and prints timing
923-
information.
924-
-}
925-
mainPatternParse :: String -> Main ParsedPattern
926-
mainPatternParse = mainParse parseKorePattern
927-
928909
renderResult :: KoreExecOptions -> Doc ann -> IO ()
929910
renderResult KoreExecOptions{outputFileName} doc =
930911
case outputFileName of
931912
Nothing -> putDoc doc
932913
Just outputFile -> withFile outputFile WriteMode (`hPutDoc` doc)
933914

934-
{- | IO action that parses a kore pattern from a filename, verifies it,
935-
converts it to a pure pattern, and prints timing information.
936-
-}
937-
mainPatternParseAndVerify ::
938-
VerifiedModule StepperAttributes ->
939-
String ->
940-
Main (TermLike VariableName)
941-
mainPatternParseAndVerify indexedModule patternFileName =
942-
mainPatternParse patternFileName >>= mainPatternVerify indexedModule
943-
944-
mainParseSearchPattern ::
945-
VerifiedModule StepperAttributes ->
946-
String ->
947-
Main (Pattern VariableName)
948-
mainParseSearchPattern indexedModule patternFileName = do
949-
purePattern <- mainPatternParseAndVerify indexedModule patternFileName
950-
case purePattern of
951-
And_ _ term predicateTerm ->
952-
return
953-
Conditional
954-
{ term
955-
, predicate =
956-
either
957-
(error . show . pretty)
958-
id
959-
(makePredicate predicateTerm)
960-
, substitution = mempty
961-
}
962-
_ -> error "Unexpected non-conjunctive pattern"
963-
964915
savedProofsModuleName :: ModuleName
965916
savedProofsModuleName =
966917
ModuleName

kore/app/match-disjunction/Main.hs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
module Main (main) where
2+
3+
import GlobalMain
4+
import Kore.Attribute.Symbol (
5+
StepperAttributes,
6+
)
7+
import Kore.BugReport
8+
import Kore.Exec (matchDisjunction)
9+
import Kore.IndexedModule.IndexedModule (
10+
VerifiedModule,
11+
)
12+
import Kore.Internal.Pattern (Pattern)
13+
import qualified Kore.Internal.Pattern as Pattern
14+
import Kore.Internal.TermLike (
15+
pattern Or_,
16+
)
17+
import Kore.Log (
18+
KoreLogOptions,
19+
parseKoreLogOptions,
20+
runKoreLog,
21+
)
22+
import Kore.Rewrite.RewritingVariable (
23+
RewritingVariableName,
24+
mkRewritingPattern,
25+
)
26+
import Kore.Syntax.Module (
27+
ModuleName (..),
28+
)
29+
import Kore.Unparser (
30+
unparse,
31+
)
32+
import Options.Applicative (
33+
InfoMod,
34+
Parser,
35+
argument,
36+
fullDesc,
37+
header,
38+
help,
39+
long,
40+
metavar,
41+
progDesc,
42+
str,
43+
strOption,
44+
)
45+
import Prelude.Kore
46+
import Pretty
47+
import System.Clock (
48+
Clock (..),
49+
TimeSpec,
50+
getTime,
51+
)
52+
import System.Exit (
53+
exitWith,
54+
)
55+
import System.IO (
56+
IOMode (WriteMode),
57+
withFile,
58+
)
59+
60+
exeName :: ExeName
61+
exeName = ExeName "kore-match-disjunction"
62+
63+
envName :: String
64+
envName = "KORE_MATCH_DISJUNCTION_OPTS"
65+
66+
data KoreMatchDisjunctionOptions = KoreMatchDisjunctionOptions
67+
{ -- | Name of file containing a definition to verify and use for execution
68+
definitionFileName :: !FilePath
69+
, -- | Name of file containing a disjunction to verify and use for matching
70+
disjunctionFileName :: !FilePath
71+
, -- | Name of file used to match with disjunction
72+
matchFileName :: !FilePath
73+
, -- | Name for file to contain the output pattern
74+
outputFileName :: !(Maybe FilePath)
75+
, -- | The name of the main module in the definition
76+
mainModuleName :: !ModuleName
77+
, bugReportOption :: !BugReportOption
78+
, koreLogOptions :: !KoreLogOptions
79+
}
80+
81+
parseKoreMatchDisjunctionOptions :: TimeSpec -> Parser KoreMatchDisjunctionOptions
82+
parseKoreMatchDisjunctionOptions startTime =
83+
KoreMatchDisjunctionOptions
84+
<$> argument
85+
str
86+
( metavar "DEFINITION_FILE"
87+
<> help "Kore definition file to verify and use for execution."
88+
)
89+
<*> strOption
90+
( metavar "DISJUNCTION_FILE"
91+
<> long "disjunction"
92+
<> help "File containing a disjunction of concrete terms."
93+
)
94+
<*> strOption
95+
( metavar "MATCH_FILE"
96+
<> long "match"
97+
<> help "Kore source file representing pattern to search for."
98+
)
99+
<*> optional
100+
( strOption
101+
( metavar "PATTERN_OUTPUT_FILE"
102+
<> long "output"
103+
<> help "Output file to contain final Kore pattern."
104+
)
105+
)
106+
<*> parseMainModuleName
107+
<*> parseBugReportOption
108+
<*> parseKoreLogOptions exeName startTime
109+
where
110+
parseMainModuleName =
111+
GlobalMain.parseModuleName
112+
"MODULE"
113+
"module"
114+
"The name of the main module in the Kore definition."
115+
116+
parserInfoModifiers :: InfoMod options
117+
parserInfoModifiers =
118+
fullDesc
119+
<> progDesc "Matches Kore pattern in MATCH_FILE with Kore pattern in DISJUNCTION_FILE"
120+
<> header "kore-match-disjunction - a tool for applying search patterns to disjunctions of configurations"
121+
122+
main :: IO ()
123+
main = do
124+
startTime <- getTime Monotonic
125+
options <-
126+
mainGlobal
127+
exeName
128+
(Just envName)
129+
(parseKoreMatchDisjunctionOptions startTime)
130+
parserInfoModifiers
131+
for_ (localOptions options) mainWithOptions
132+
133+
mainWithOptions :: KoreMatchDisjunctionOptions -> IO ()
134+
mainWithOptions options = do
135+
exitCode <-
136+
withBugReport exeName bugReportOption $ \tmpDir ->
137+
koreMatchDisjunction options
138+
& runKoreLog tmpDir koreLogOptions
139+
exitWith exitCode
140+
where
141+
KoreMatchDisjunctionOptions{bugReportOption} = options
142+
KoreMatchDisjunctionOptions{koreLogOptions} = options
143+
144+
koreMatchDisjunction :: KoreMatchDisjunctionOptions -> Main ExitCode
145+
koreMatchDisjunction options = do
146+
definition <- loadDefinitions [definitionFileName]
147+
mainModule <- loadModule mainModuleName definition
148+
matchPattern <- mainParseMatchPattern mainModule matchFileName
149+
disjunctionPattern <-
150+
mainParseDisjunctionPattern mainModule disjunctionFileName
151+
final <-
152+
clockSomethingIO "Executing" $
153+
matchDisjunction mainModule matchPattern disjunctionPattern
154+
lift $
155+
renderResult
156+
options
157+
(unparse final)
158+
return ExitSuccess
159+
where
160+
mainParseMatchPattern mainModule fileName =
161+
mainParseSearchPattern mainModule fileName
162+
<&> mkRewritingPattern
163+
KoreMatchDisjunctionOptions
164+
{ definitionFileName
165+
, disjunctionFileName
166+
, matchFileName
167+
, mainModuleName
168+
} = options
169+
170+
mainParseDisjunctionPattern ::
171+
VerifiedModule StepperAttributes ->
172+
String ->
173+
Main [Pattern RewritingVariableName]
174+
mainParseDisjunctionPattern indexedModule patternFileName = do
175+
purePattern <- mainPatternParseAndVerify indexedModule patternFileName
176+
return $ parseDisjunction purePattern
177+
where
178+
parseDisjunction (Or_ _ term1 term2) =
179+
parseDisjunction term1 <> parseDisjunction term2
180+
parseDisjunction term =
181+
let patt =
182+
mkRewritingPattern
183+
. Pattern.fromTermLike
184+
$ term
185+
in [patt]
186+
187+
renderResult :: KoreMatchDisjunctionOptions -> Doc ann -> IO ()
188+
renderResult KoreMatchDisjunctionOptions{outputFileName} doc =
189+
case outputFileName of
190+
Nothing -> putDoc doc
191+
Just outputFile ->
192+
withFile outputFile WriteMode (`hPutDoc` doc)

kore/app/share/GlobalMain.hs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module GlobalMain (
2222
LoadedModule,
2323
loadDefinitions,
2424
loadModule,
25+
mainParseSearchPattern,
26+
mainPatternParseAndVerify,
2527
) where
2628

2729
import Control.Exception (
@@ -58,13 +60,20 @@ import Kore.Attribute.Definition (
5860
import Kore.Attribute.SourceLocation (
5961
notDefault,
6062
)
63+
import Kore.Attribute.Symbol (
64+
StepperAttributes,
65+
)
6166
import qualified Kore.Attribute.Symbol as Attribute (
6267
Symbol,
6368
)
6469
import qualified Kore.Builtin as Builtin
6570
import Kore.IndexedModule.IndexedModule (
6671
VerifiedModule,
6772
)
73+
import Kore.Internal.Conditional (Conditional (..))
74+
import Kore.Internal.Pattern (Pattern)
75+
import Kore.Internal.Predicate (makePredicate)
76+
import Kore.Internal.TermLike (TermLike, pattern And_)
6877
import Kore.Log as Log
6978
import Kore.Log.ErrorParse (
7079
errorParse,
@@ -75,6 +84,7 @@ import Kore.Log.ErrorVerify (
7584
import Kore.Parser (
7685
ParsedPattern,
7786
parseKoreDefinition,
87+
parseKorePattern,
7888
)
7989
import qualified Kore.Parser.Lexer as Lexer
8090
import Kore.Parser.ParserUtils (
@@ -83,7 +93,7 @@ import Kore.Parser.ParserUtils (
8393
import Kore.Rewrite.Strategy (
8494
GraphSearchOrder (..),
8595
)
86-
import Kore.Syntax
96+
import Kore.Syntax hiding (Pattern)
8797
import Kore.Syntax.Definition (
8898
ModuleName (..),
8999
ParsedDefinition,
@@ -130,6 +140,7 @@ import qualified Paths_kore as MetaData (
130140
version,
131141
)
132142
import Prelude.Kore
143+
import qualified Pretty as KorePretty
133144
import System.Clock (
134145
Clock (Monotonic),
135146
diffTimeSpec,
@@ -513,3 +524,39 @@ loadDefinitions filePaths =
513524

514525
loadModule :: ModuleName -> LoadedDefinition -> Main LoadedModule
515526
loadModule moduleName = lookupMainModule moduleName . indexedModules
527+
528+
mainParseSearchPattern ::
529+
VerifiedModule StepperAttributes ->
530+
String ->
531+
Main (Pattern VariableName)
532+
mainParseSearchPattern indexedModule patternFileName = do
533+
purePattern <- mainPatternParseAndVerify indexedModule patternFileName
534+
case purePattern of
535+
And_ _ term predicateTerm ->
536+
return
537+
Conditional
538+
{ term
539+
, predicate =
540+
either
541+
(error . show . KorePretty.pretty)
542+
id
543+
(makePredicate predicateTerm)
544+
, substitution = mempty
545+
}
546+
_ -> error "Unexpected non-conjunctive pattern"
547+
548+
{- | IO action that parses a kore pattern from a filename, verifies it,
549+
converts it to a pure pattern, and prints timing information.
550+
-}
551+
mainPatternParseAndVerify ::
552+
VerifiedModule StepperAttributes ->
553+
String ->
554+
Main (TermLike VariableName)
555+
mainPatternParseAndVerify indexedModule patternFileName =
556+
mainPatternParse patternFileName >>= mainPatternVerify indexedModule
557+
558+
{- | IO action that parses a kore pattern from a filename and prints timing
559+
information.
560+
-}
561+
mainPatternParse :: String -> Main ParsedPattern
562+
mainPatternParse = mainParse parseKorePattern

0 commit comments

Comments
 (0)