Skip to content

Commit d544b82

Browse files
SET.difference for symbolic values (#2011)
* Implement SET.difference for symbolic values * Test * Pedantic * Addressed comments * evalDifference: Definedness conditions include all arguments * Add Test.Kore.Builtin.Difference.differenceSet * Add Test.Kore.Builtin.Definition.builtinSet * Export Kore.Builtin.Set.evalDifference * RED test_difference_symbolic: Fix test case * Fix tests and copy differenceSet's implementation to fix builtin implementation * Lint * Use applicationEvaluator * functionEvaluator: Implement in terms of applicationEvaluator * test_difference_symbolic: Improve test names * test_difference_symbolic: Refactor * test_difference_symbolic: leaves empty set * Add Kore.Domain.Builtin.nullAc * AUR evalDifference Co-authored-by: Thomas Tuegel <[email protected]>
1 parent 6d366b2 commit d544b82

File tree

6 files changed

+249
-99
lines changed

6 files changed

+249
-99
lines changed

kore/src/Kore/Builtin/Builtin.hs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module Kore.Builtin.Builtin
2222
, binaryOperator
2323
, ternaryOperator
2424
, functionEvaluator
25+
, applicationEvaluator
2526
, verifierBug
2627
, wrongArity
2728
, runParser
@@ -270,6 +271,21 @@ type Function
270271

271272
functionEvaluator :: Function -> BuiltinAndAxiomSimplifier
272273
functionEvaluator impl =
274+
applicationEvaluator $ \app -> do
275+
let Application { applicationSymbolOrAlias = symbol } = app
276+
Application { applicationChildren = args } = app
277+
resultSort = symbolSorts symbol & applicationSortsResult
278+
impl resultSort args
279+
280+
applicationEvaluator
281+
:: ( forall variable simplifier
282+
. InternalVariable variable
283+
=> MonadSimplify simplifier
284+
=> Application Symbol (TermLike variable)
285+
-> MaybeT simplifier (Pattern variable)
286+
)
287+
-> BuiltinAndAxiomSimplifier
288+
applicationEvaluator impl =
273289
applicationAxiomSimplifier evaluator
274290
where
275291
evaluator
@@ -280,12 +296,9 @@ functionEvaluator impl =
280296
(Attribute.Pattern variable)
281297
(TermLike variable)
282298
-> simplifier (AttemptedAxiom variable)
283-
evaluator (valid :< app) = do
284-
let args = map TermLike.removeEvaluated applicationChildren
285-
getAttemptedAxiom (impl resultSort args >>= appliedFunction)
286-
where
287-
Application { applicationChildren } = app
288-
Attribute.Pattern { Attribute.patternSort = resultSort } = valid
299+
evaluator (_ :< app) = do
300+
let app' = fmap TermLike.removeEvaluated app
301+
getAttemptedAxiom (impl app' >>= appliedFunction)
289302

290303
{- | Run a parser on a verified domain value.
291304

kore/src/Kore/Builtin/Set.hs

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module Kore.Builtin.Set
2727
, evalConcat
2828
, evalElement
2929
, evalUnit
30+
, evalDifference
3031
-- * Unification
3132
, unifyEquals
3233
) where
@@ -48,6 +49,7 @@ import Data.Map.Strict
4849
)
4950
import qualified Data.Map.Strict as Map
5051
import qualified Data.Sequence as Seq
52+
import qualified Data.Set as Set
5153
import Data.Text
5254
( Text
5355
)
@@ -71,13 +73,17 @@ import qualified Kore.Domain.Builtin as Domain
7173
import Kore.IndexedModule.MetadataTools
7274
( SmtMetadataTools
7375
)
76+
import Kore.Internal.ApplicationSorts
77+
( ApplicationSorts (..)
78+
)
7479
import qualified Kore.Internal.Conditional as Conditional
7580
import Kore.Internal.Pattern
7681
( Pattern
7782
)
7883
import qualified Kore.Internal.Pattern as Pattern
7984
import Kore.Internal.Predicate
8085
( makeCeilPredicate
86+
, makeMultipleAndPredicate
8187
)
8288
import Kore.Internal.TermLike
8389
( pattern App_
@@ -324,8 +330,18 @@ evalConcat resultSort [set1, set2] =
324330
(Ac.toNormalized set2)
325331
evalConcat _ _ = Builtin.wrongArity Set.concatKey
326332

327-
evalDifference :: Builtin.Function
328-
evalDifference resultSort [_set1, _set2] = do
333+
evalDifference
334+
:: forall variable simplifier
335+
. InternalVariable variable
336+
=> MonadSimplify simplifier
337+
=> TermLike.Application TermLike.Symbol (TermLike variable)
338+
-> MaybeT simplifier (Pattern variable)
339+
evalDifference
340+
( TermLike.Application
341+
symbol@TermLike.Symbol { symbolSorts = ApplicationSorts _ resultSort }
342+
args@[_set1, _set2]
343+
)
344+
= do
329345
let rightIdentity = do
330346
_set2 <- expectConcreteBuiltinSet ctx _set2
331347
if Map.null _set2
@@ -335,10 +351,66 @@ evalDifference resultSort [_set1, _set2] = do
335351
_set1 <- expectConcreteBuiltinSet ctx _set1
336352
_set2 <- expectConcreteBuiltinSet ctx _set2
337353
returnConcreteSet resultSort (Map.difference _set1 _set2)
338-
rightIdentity <|> bothConcrete
354+
symbolic = do
355+
_set1 <- expectBuiltinSet ctx _set1
356+
_set2 <- expectBuiltinSet ctx _set2
357+
let definedArgs =
358+
filter (not . TermLike.isDefinedPattern) args
359+
& map (makeCeilPredicate resultSort)
360+
& makeMultipleAndPredicate
361+
& Conditional.fromPredicate
362+
let Domain.NormalizedAc
363+
{ concreteElements = concrete1
364+
, elementsWithVariables = symbolic1'
365+
, opaque = opaque1'
366+
}
367+
= Domain.unwrapAc _set1
368+
symbolic1 =
369+
Domain.unwrapElement <$> symbolic1'
370+
& Map.fromList
371+
opaque1 = Set.fromList opaque1'
372+
let Domain.NormalizedAc
373+
{ concreteElements = concrete2
374+
, elementsWithVariables = symbolic2'
375+
, opaque = opaque2'
376+
}
377+
= Domain.unwrapAc _set2
378+
symbolic2 =
379+
Domain.unwrapElement <$> symbolic2'
380+
& Map.fromList
381+
opaque2 = Set.fromList opaque2'
382+
let set1' =
383+
Domain.NormalizedAc
384+
{ concreteElements = Map.difference concrete1 concrete2
385+
, elementsWithVariables =
386+
Map.difference symbolic1 symbolic2
387+
& Map.toList
388+
& map Domain.wrapElement
389+
, opaque = Set.difference opaque1 opaque2 & Set.toList
390+
}
391+
set2' =
392+
Domain.NormalizedAc
393+
{ concreteElements = Map.difference concrete2 concrete1
394+
, elementsWithVariables =
395+
Map.difference symbolic2 symbolic1
396+
& Map.toList
397+
& map Domain.wrapElement
398+
, opaque = Set.difference opaque1 opaque1 & Set.toList
399+
}
400+
pat1 <- Ac.returnAc resultSort (Domain.NormalizedSet set1')
401+
pat2 <- Ac.returnAc resultSort (Domain.NormalizedSet set2')
402+
let pat
403+
| (not . Domain.nullAc) set1', (not . Domain.nullAc) set2' =
404+
differenceSet <$> pat1 <*> pat2
405+
| otherwise = pat1
406+
return (Pattern.andCondition pat definedArgs)
407+
408+
rightIdentity <|> bothConcrete <|> symbolic
339409
where
340410
ctx = Set.differenceKey
341-
evalDifference _ _ = Builtin.wrongArity Set.differenceKey
411+
differenceSet set1 set2 = TermLike.mkApplySymbol symbol [set1, set2]
412+
evalDifference _ =
413+
Builtin.wrongArity Set.differenceKey
342414

343415
evalToList :: Builtin.Function
344416
evalToList resultSort [_set] = do
@@ -399,7 +471,7 @@ builtinFunctions =
399471
, (Set.elementKey, Builtin.functionEvaluator evalElement)
400472
, (Set.unitKey, Builtin.functionEvaluator evalUnit)
401473
, (Set.inKey, Builtin.functionEvaluator evalIn)
402-
, (Set.differenceKey, Builtin.functionEvaluator evalDifference)
474+
, (Set.differenceKey, Builtin.applicationEvaluator evalDifference)
403475
, (Set.toListKey, Builtin.functionEvaluator evalToList)
404476
, (Set.sizeKey, Builtin.functionEvaluator evalSize)
405477
, (Set.intersectionKey, Builtin.functionEvaluator evalIntersection)

kore/src/Kore/Domain/Builtin.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Kore.Domain.Builtin
1818
, wrapConcreteElement
1919
, InternalAc (..)
2020
, NormalizedAc (..)
21+
, nullAc
2122
, emptyNormalizedAc
2223
, asSingleOpaqueElem
2324
, isSymbolicKeyOfAc
@@ -176,6 +177,12 @@ data NormalizedAc (collection :: Type -> Type -> Type) key child = NormalizedAc
176177
}
177178
deriving (GHC.Generic)
178179

180+
nullAc :: NormalizedAc normalized key child -> Bool
181+
nullAc normalizedAc =
182+
null (elementsWithVariables normalizedAc)
183+
&& null (concreteElements normalizedAc)
184+
&& null (opaque normalizedAc)
185+
179186
isSymbolicKeyOfAc
180187
:: AcWrapper normalized
181188
=> Eq child

kore/test/Test/Kore/Builtin/Definition.hs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Prelude.Kore
77

88
import qualified Data.Bifunctor as Bifunctor
99
import qualified Data.Default as Default
10+
import qualified Data.Foldable as Foldable
1011
import qualified Data.Map.Strict as Map
1112
import qualified Data.Sequence as Seq
1213
import Data.Text
@@ -32,6 +33,7 @@ import Kore.Attribute.Synthetic
3233
( synthesize
3334
)
3435
import qualified Kore.Builtin as Builtin
36+
import qualified Kore.Builtin.Builtin as Builtin
3537
import qualified Kore.Builtin.Endianness as Endianness
3638
import qualified Kore.Builtin.Signedness as Signedness
3739
import Kore.Domain.Builtin
@@ -614,6 +616,12 @@ differenceSetSymbol :: Internal.Symbol
614616
differenceSetSymbol =
615617
binarySymbol "differenceSet" setSort & hook "SET.difference"
616618

619+
differenceSet
620+
:: TermLike VariableName
621+
-> TermLike VariableName
622+
-> TermLike VariableName
623+
differenceSet set1 set2 = mkApplySymbol differenceSetSymbol [set1, set2]
624+
617625
toListSetSymbol :: Internal.Symbol
618626
toListSetSymbol =
619627
builtinSymbol "toListSet" listSort [setSort] & hook "SET.set2list"
@@ -1165,38 +1173,37 @@ testSortDecl :: ParsedSentence
11651173
testSortDecl = sortDecl testSort
11661174

11671175
builtinSet
1168-
:: [TermLike Concrete]
1169-
-> InternalSet (TermLike Concrete) (TermLike VariableName)
1170-
builtinSet children =
1171-
InternalAc
1176+
:: InternalVariable variable
1177+
=> Foldable f
1178+
=> f (TermLike variable)
1179+
-> [TermLike variable]
1180+
-> TermLike variable
1181+
builtinSet elements opaque =
1182+
mkBuiltin $ Domain.BuiltinSet Domain.InternalAc
11721183
{ builtinAcSort = setSort
11731184
, builtinAcUnit = unitSetSymbol
11741185
, builtinAcElement = elementSetSymbol
11751186
, builtinAcConcat = concatSetSymbol
11761187
, builtinAcChild = Domain.NormalizedSet Domain.NormalizedAc
1177-
{ elementsWithVariables = []
1178-
, concreteElements =
1179-
Map.fromList (map (\x -> (x, SetValue)) children)
1180-
, opaque = []
1181-
}
1182-
}
1183-
1184-
builtinSymbolicSet
1185-
:: [TermLike VariableName]
1186-
-> InternalSet key (TermLike VariableName)
1187-
builtinSymbolicSet children =
1188-
InternalAc
1189-
{ builtinAcSort = setSort
1190-
, builtinAcUnit = unitSetSymbol
1191-
, builtinAcElement = elementSetSymbolTestSort
1192-
, builtinAcConcat = concatSetSymbol
1193-
, builtinAcChild = Domain.NormalizedSet Domain.NormalizedAc
1194-
{ elementsWithVariables =
1195-
fmap (\x -> wrapElement (x, SetValue)) children
1196-
, concreteElements = Map.empty
1197-
, opaque = []
1188+
{ elementsWithVariables = Domain.wrapElement <$> abstractElements
1189+
, concreteElements
1190+
, opaque
11981191
}
11991192
}
1193+
where
1194+
asKey key =
1195+
(,) <$> Builtin.toKey key <*> pure Domain.SetValue
1196+
& maybe (Left (key, Domain.SetValue)) Right
1197+
(abstractElements, Map.fromList -> concreteElements) =
1198+
asKey <$> Foldable.toList elements
1199+
& partitionEithers
1200+
1201+
builtinSet_
1202+
:: InternalVariable variable
1203+
=> Foldable f
1204+
=> f (TermLike variable)
1205+
-> TermLike variable
1206+
builtinSet_ items = builtinSet items []
12001207

12011208
-- ** String
12021209

kore/test/Test/Kore/Builtin/Map.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ test_removeAll =
294294
when (set == Set.empty) discard
295295
let key = Set.elemAt 0 set
296296
diffSet = Set.delete key set
297-
patSet = Test.Set.asTermLike set
298-
patDiffSet = Test.Set.asTermLike diffSet
297+
patSet = builtinSet_ set & fromConcrete
298+
patDiffSet = builtinSet_ diffSet & fromConcrete
299299
patKey = fromConcrete key
300300
patRemoveAll1 = removeAllMap map' patSet
301301
patRemoveAll2 = removeAllMap
@@ -426,7 +426,7 @@ test_keysUnit =
426426
let
427427
patUnit = unitMap
428428
patKeys = keysMap patUnit
429-
patExpect = Test.Set.asTermLike Set.empty
429+
patExpect = builtinSet_ Set.empty
430430
predicate = mkEquals_ patExpect patKeys
431431
expect <- evaluate patExpect
432432
assertEqual "" expect =<< evaluate patKeys
@@ -440,7 +440,7 @@ test_keysElement =
440440
key <- forAll genConcreteIntegerPattern
441441
val <- forAll genIntegerPattern
442442
let patMap = asTermLike $ Map.singleton key val
443-
patKeys = Test.Set.asTermLike $ Set.singleton key
443+
patKeys = builtinSet_ (Set.singleton key) & fromConcrete
444444
patSymbolic = keysMap patMap
445445
predicate = mkEquals_ patKeys patSymbolic
446446
expect <- evaluateT patKeys
@@ -455,7 +455,7 @@ test_keys =
455455
(do
456456
map1 <- forAll (genConcreteMap genIntegerPattern)
457457
let keys1 = Map.keysSet map1
458-
patConcreteKeys = Test.Set.asTermLike keys1
458+
patConcreteKeys = builtinSet_ keys1 & fromConcrete
459459
patMap = asTermLike map1
460460
patSymbolicKeys = keysMap patMap
461461
predicate = mkEquals_ patConcreteKeys patSymbolicKeys

0 commit comments

Comments
 (0)