Skip to content

Commit 4347105

Browse files
authored
Recognise ==Int and ==K equations as substitutions when internalising (#4061)
Booster now recognises predicates of shape `true #Equals (VAR ==Int <expr>)` and `true #Equals (VAR ==K <expr>)` as substitutions (given the global scope does not contradict that, i.e., no cycles or multiple substitutions for the same VAR...). Currently only matches ==Int and ==K. We could also match notBool (_ =/=Int _) and notBool (_ =/=K _) (more magic). When internalising rules and equations, the substitution must be turned back into predicates for the `requires` clause. Currently we also turn back the ensures clause substitutions into predicates (might want to change that). Part of #4059
1 parent 0bfbcff commit 4347105

File tree

5 files changed

+173
-227
lines changed

5 files changed

+173
-227
lines changed

booster/library/Booster/Syntax/Json/Internalise.hs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module Booster.Syntax.Json.Internalise (
2424
textToBS,
2525
trm,
2626
handleBS,
27+
asEquations,
2728
TermOrPredicates (..),
2829
InternalisedPredicates (..),
2930
PatternOrTopOrBottom (..),
@@ -481,6 +482,10 @@ mkEq x t = Internal.Predicate $ case sortOfTerm t of
481482
Internal.SortBool -> Internal.EqualsBool (Internal.Var x) t
482483
otherSort -> Internal.EqualsK (Internal.KSeq otherSort (Internal.Var x)) (Internal.KSeq otherSort t)
483484

485+
-- | turns a substitution into a list of equations
486+
asEquations :: Map Internal.Variable Internal.Term -> [Internal.Predicate]
487+
asEquations = map (uncurry mkEq) . Map.assocs
488+
484489
internalisePred ::
485490
Flag "alias" ->
486491
Flag "subsorts" ->
@@ -540,10 +545,12 @@ internalisePred allowAlias checkSubsorts sortVars definition@KoreDefinition{sort
540545
ensureEqualSorts (sortOfTerm a) argS
541546
ensureEqualSorts (sortOfTerm b) argS
542547
case (argS, a, b) of
548+
-- for "true" #Equals P, check whether P is in fact a substitution
543549
(Internal.SortBool, Internal.TrueBool, x) ->
544-
pure [BoolPred $ Internal.Predicate x]
550+
mapM mbSubstitution [x]
545551
(Internal.SortBool, x, Internal.TrueBool) ->
546-
pure [BoolPred $ Internal.Predicate x]
552+
mapM mbSubstitution [x]
553+
-- we could also detect NotBool (NEquals _) in "false" #Equals P
547554
(Internal.SortBool, Internal.FalseBool, x) ->
548555
pure [BoolPred $ Internal.Predicate $ Internal.NotBool x]
549556
(Internal.SortBool, x, Internal.FalseBool) ->
@@ -600,6 +607,33 @@ internalisePred allowAlias checkSubsorts sortVars definition@KoreDefinition{sort
600607
throwE (IncompatibleSorts (map externaliseSort [s1, s2]))
601608
zipWithM_ go args1 args2
602609

610+
mbSubstitution :: Internal.Term -> Except PatternError InternalisedPredicate
611+
mbSubstitution = \case
612+
eq@(Internal.EqualsInt (Internal.Var x) e)
613+
| x `Set.member` freeVariables e -> pure $ boolPred eq
614+
| otherwise -> pure $ SubstitutionPred x e
615+
eq@(Internal.EqualsInt e (Internal.Var x))
616+
| x `Set.member` freeVariables e -> pure $ boolPred eq
617+
| otherwise -> pure $ SubstitutionPred x e
618+
eq@(Internal.EqualsK (Internal.KSeq _sortL (Internal.Var x)) (Internal.KSeq _sortR e)) ->
619+
do
620+
-- NB sorts do not have to agree! (could be subsorts)
621+
pure $
622+
if (x `Set.member` freeVariables e)
623+
then boolPred eq
624+
else SubstitutionPred x e
625+
eq@(Internal.EqualsK (Internal.KSeq _sortL e) (Internal.KSeq _sortR (Internal.Var x))) ->
626+
do
627+
-- NB sorts do not have to agree! (could be subsorts)
628+
pure $
629+
if (x `Set.member` freeVariables e)
630+
then boolPred eq
631+
else SubstitutionPred x e
632+
other ->
633+
pure $ boolPred other
634+
635+
boolPred = BoolPred . Internal.Predicate
636+
603637
----------------------------------------
604638

605639
-- for use with withAssoc

booster/library/Booster/Syntax/ParsedKore/Internalise.hs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,10 @@ internaliseAxiom (Partial partialDefinition) parsedAxiom =
765765
sortVars
766766
attribs
767767

768+
{- | internalises a pattern and turns its contained substitution into
769+
equations (predicates). Errors if any ceil conditions or
770+
unsupported predicates are found.
771+
-}
768772
internalisePatternEnsureNoSubstitutionOrCeilOrUnsupported ::
769773
KoreDefinition ->
770774
SourceRef ->
@@ -776,16 +780,16 @@ internalisePatternEnsureNoSubstitutionOrCeilOrUnsupported partialDefinition ref
776780
(term, preds, ceilConditions, substitution, unsupported) <-
777781
withExcept (DefinitionPatternError ref) $
778782
internalisePattern AllowAlias IgnoreSubsorts maybeVars partialDefinition t
779-
unless (null substitution) $
780-
throwE $
781-
DefinitionPatternError ref SubstitutionNotAllowed
782783
unless (null ceilConditions) $
783784
throwE $
784785
DefinitionPatternError ref CeilNotAllowed
785786
unless (null unsupported) $
786787
throwE $
787788
DefinitionPatternError ref (NotSupported (head unsupported))
788-
pure (Util.modifyVariablesInT f term, map (Util.modifyVariablesInP f) preds)
789+
pure
790+
( Util.modifyVariablesInT f term
791+
, map (Util.modifyVariablesInP f) (preds <> asEquations substitution)
792+
)
789793

790794
internaliseRewriteRuleNoAlias ::
791795
KoreDefinition ->
@@ -964,12 +968,10 @@ internaliseCeil partialDef left right sortVars attrs = do
964968
internalPs <-
965969
withExcept (DefinitionPatternError (sourceRef attrs)) $
966970
internalisePredicates AllowAlias IgnoreSubsorts (Just sortVars) partialDef [p]
967-
let constraints = internalPs.boolPredicates
968-
substitutions = internalPs.substitution
971+
let
972+
-- turn substitution-like predicates back into equations
973+
constraints = internalPs.boolPredicates <> asEquations internalPs.substitution
969974
unsupported = internalPs.unsupported
970-
unless (null substitutions) $
971-
throwE $
972-
DefinitionPatternError (sourceRef attrs) SubstitutionNotAllowed
973975
unless (null unsupported) $
974976
throwE $
975977
DefinitionPatternError (sourceRef attrs) $
@@ -1005,9 +1007,6 @@ internaliseFunctionEquation partialDef requires args leftTerm right sortVars att
10051007
withExcept (DefinitionPatternError (sourceRef attrs)) $
10061008
internalisePattern AllowAlias IgnoreSubsorts (Just sortVars) partialDef $
10071009
Syntax.KJAnd leftTerm.sort [leftTerm, requires]
1008-
unless (null substitution) $
1009-
throwE $
1010-
DefinitionPatternError (sourceRef attrs) SubstitutionNotAllowed
10111010
unless (null ceils) $
10121011
throwE $
10131012
DefinitionPatternError (sourceRef attrs) CeilNotAllowed
@@ -1049,7 +1048,8 @@ internaliseFunctionEquation partialDef requires args leftTerm right sortVars att
10491048
RewriteRule
10501049
{ lhs
10511050
, rhs
1052-
, requires = map (Util.modifyVariablesInP $ Util.modifyVarName ("Eq#" <>)) preds
1051+
, requires =
1052+
map (Util.modifyVariablesInP $ Util.modifyVarName ("Eq#" <>)) (preds <> asEquations substitution)
10531053
, ensures
10541054
, attributes
10551055
, computedAttributes

booster/test/rpc-integration/test-vacuous/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Rules `init` and `AC` introduce constraints on this variable:
3737

3838
_Expected:_
3939
- The rewrite is stuck with `<k>d</k><int>N</int> \and...(contradiction)`
40+
- The `N` is substituted by value `1` in the final result (booster).
4041
- The result is simplified and discovered to be `vacuous` (with state `d`).
4142
1) _vacuous-but-rewritten_
4243

@@ -47,6 +48,7 @@ Rules `init` and `AC` introduce constraints on this variable:
4748
_Expected:_
4849
- Rewrite with `BD` (despite the contradiction)
4950
- The rewrite is stuck with `<k>d</k><int>N</int> \and...(contradiction)`
51+
- The `N` is substituted by value `1` in the final result (booster).
5052
- The result is simplified and discovered to be `vacuous` (with state `d`).
5153

5254
With `kore-rpc-dev`, some contradictions will be discovered before or while

booster/test/rpc-integration/test-vacuous/response-vacuous-but-rewritten.json

Lines changed: 61 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@
6666
"sorts": [],
6767
"args": [
6868
{
69-
"tag": "EVar",
70-
"name": "N",
69+
"tag": "DV",
7170
"sort": {
7271
"tag": "SortApp",
7372
"name": "SortInt",
7473
"args": []
75-
}
74+
},
75+
"value": "0"
7676
}
7777
]
7878
},
@@ -95,119 +95,74 @@
9595
]
9696
}
9797
},
98+
"substitution": {
99+
"format": "KORE",
100+
"version": 1,
101+
"term": {
102+
"tag": "Equals",
103+
"argSort": {
104+
"tag": "SortApp",
105+
"name": "SortInt",
106+
"args": []
107+
},
108+
"sort": {
109+
"tag": "SortApp",
110+
"name": "SortGeneratedTopCell",
111+
"args": []
112+
},
113+
"first": {
114+
"tag": "EVar",
115+
"name": "N",
116+
"sort": {
117+
"tag": "SortApp",
118+
"name": "SortInt",
119+
"args": []
120+
}
121+
},
122+
"second": {
123+
"tag": "DV",
124+
"sort": {
125+
"tag": "SortApp",
126+
"name": "SortInt",
127+
"args": []
128+
},
129+
"value": "0"
130+
}
131+
}
132+
},
98133
"predicate": {
99134
"format": "KORE",
100135
"version": 1,
101136
"term": {
102-
"tag": "And",
137+
"tag": "Equals",
138+
"argSort": {
139+
"tag": "SortApp",
140+
"name": "SortBool",
141+
"args": []
142+
},
103143
"sort": {
104144
"tag": "SortApp",
105145
"name": "SortGeneratedTopCell",
106146
"args": []
107147
},
108-
"patterns": [
109-
{
110-
"tag": "Equals",
111-
"argSort": {
112-
"tag": "SortApp",
113-
"name": "SortBool",
114-
"args": []
115-
},
116-
"sort": {
117-
"tag": "SortApp",
118-
"name": "SortGeneratedTopCell",
119-
"args": []
120-
},
121-
"first": {
122-
"tag": "DV",
123-
"sort": {
124-
"tag": "SortApp",
125-
"name": "SortBool",
126-
"args": []
127-
},
128-
"value": "true"
129-
},
130-
"second": {
131-
"tag": "App",
132-
"name": "Lbl'UndsEqlsEqls'Int'Unds'",
133-
"sorts": [],
134-
"args": [
135-
{
136-
"tag": "EVar",
137-
"name": "N",
138-
"sort": {
139-
"tag": "SortApp",
140-
"name": "SortInt",
141-
"args": []
142-
}
143-
},
144-
{
145-
"tag": "DV",
146-
"sort": {
147-
"tag": "SortApp",
148-
"name": "SortInt",
149-
"args": []
150-
},
151-
"value": "0"
152-
}
153-
]
154-
}
148+
"first": {
149+
"tag": "DV",
150+
"sort": {
151+
"tag": "SortApp",
152+
"name": "SortBool",
153+
"args": []
155154
},
156-
{
157-
"tag": "Equals",
158-
"argSort": {
159-
"tag": "SortApp",
160-
"name": "SortBool",
161-
"args": []
162-
},
163-
"sort": {
164-
"tag": "SortApp",
165-
"name": "SortGeneratedTopCell",
166-
"args": []
167-
},
168-
"first": {
169-
"tag": "DV",
170-
"sort": {
171-
"tag": "SortApp",
172-
"name": "SortBool",
173-
"args": []
174-
},
175-
"value": "true"
176-
},
177-
"second": {
178-
"tag": "App",
179-
"name": "LblnotBool'Unds'",
180-
"sorts": [],
181-
"args": [
182-
{
183-
"tag": "App",
184-
"name": "Lbl'UndsEqlsEqls'Int'Unds'",
185-
"sorts": [],
186-
"args": [
187-
{
188-
"tag": "EVar",
189-
"name": "N",
190-
"sort": {
191-
"tag": "SortApp",
192-
"name": "SortInt",
193-
"args": []
194-
}
195-
},
196-
{
197-
"tag": "DV",
198-
"sort": {
199-
"tag": "SortApp",
200-
"name": "SortInt",
201-
"args": []
202-
},
203-
"value": "0"
204-
}
205-
]
206-
}
207-
]
208-
}
209-
}
210-
]
155+
"value": "true"
156+
},
157+
"second": {
158+
"tag": "DV",
159+
"sort": {
160+
"tag": "SortApp",
161+
"name": "SortBool",
162+
"args": []
163+
},
164+
"value": "false"
165+
}
211166
}
212167
}
213168
}

0 commit comments

Comments
 (0)