Skip to content

Implement SET.intersection #632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,15 @@ The union of both arguments.
[hook{}("SET.concat")]
~~~

### SET.intersection

The intersection of both arguments

~~~
hooked-symbol intersect{}(Set{}, Set{}) : Set{}
[hook{}("SET.intersection")]
~~~

### SET.in

Is the element a member of the given set?
Expand Down
24 changes: 24 additions & 0 deletions kore/src/Kore/Builtin/Set.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module Kore.Builtin.Set
, differenceKey
, toListKey
, sizeKey
, intersectionKey
-- * Unification
, unifyEquals
) where
Expand Down Expand Up @@ -171,6 +172,9 @@ symbolVerifiers =
, ( sizeKey
, Builtin.verifySymbol Int.assertSort [assertSort]
)
, ( intersectionKey
, Builtin.verifySymbol assertSort [assertSort, assertSort]
)
]

type Builtin = Set (TermLike Concrete)
Expand Down Expand Up @@ -350,6 +354,22 @@ evalSize = Builtin.functionEvaluator evalSize0
. Set.size
$ _set

evalIntersection :: Builtin.Function
evalIntersection =
Builtin.functionEvaluator evalIntersection0
where
ctx = intersectionKey
evalIntersection0 :: Builtin.FunctionImplementation
evalIntersection0 tools _ resultSort = \arguments ->
Builtin.getAttemptedAxiom $ do
let (_set1, _set2) =
case arguments of
[_set1, _set2] -> (_set1, _set2)
_ -> Builtin.wrongArity intersectionKey
_set1 <- expectBuiltinSet ctx tools _set1
_set2 <- expectBuiltinSet ctx tools _set2
returnSet tools resultSort (Set.intersection _set1 _set2)

{- | Implement builtin function evaluation.
-}
builtinFunctions :: Map Text Builtin.Function
Expand All @@ -362,6 +382,7 @@ builtinFunctions =
, (differenceKey, evalDifference)
, (toListKey, evalToList)
, (sizeKey, evalSize)
, (intersectionKey, evalIntersection)
]

{- | Render a 'Set' as an internal domain value pattern of the given sort.
Expand Down Expand Up @@ -452,6 +473,9 @@ toListKey = "SET.set2list"
sizeKey :: IsString s => s
sizeKey = "SET.size"

intersectionKey :: IsString s => s
intersectionKey = "SET.intersection"

{- | Find the symbol hooked to @SET.get@ in an indexed module.
-}
lookupSymbolIn
Expand Down
18 changes: 18 additions & 0 deletions kore/test/Test/Kore/Builtin/Definition.hs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ pairSymbol lSort rSort =
unitSetSymbol :: SymbolOrAlias
unitSetSymbol = builtinSymbol "unitSet"

unitSet :: TermLike Variable
unitSet = mkApp setSort unitSetSymbol []

elementSetSymbol :: SymbolOrAlias
elementSetSymbol = builtinSymbol "elementSet"

Expand All @@ -287,6 +290,16 @@ toListSetSymbol = builtinSymbol "toListSet"
sizeSetSymbol :: SymbolOrAlias
sizeSetSymbol = builtinSymbol "sizeSet"

intersectionSetSymbol :: SymbolOrAlias
intersectionSetSymbol = builtinSymbol "intersectionSet"

intersectionSet
:: TermLike Variable
-> TermLike Variable
-> TermLike Variable
intersectionSet set1 set2 =
mkApp setSort intersectionSetSymbol [set1, set2]

-- ** String

ltStringSymbol :: SymbolOrAlias
Expand Down Expand Up @@ -1112,6 +1125,11 @@ setModule =
intSort
[setSort]
[hookAttribute Set.sizeKey]
, hookedSymbolDecl
intersectionSetSymbol
setSort
[setSort, setSort]
[hookAttribute Set.intersectionKey]
]
}

Expand Down
21 changes: 21 additions & 0 deletions kore/test/Test/Kore/Builtin/Set.hs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,27 @@ test_size =
(===) Pattern.top =<< evaluate predicate
)

test_intersection_unit :: TestTree
test_intersection_unit =
testPropertyWithSolver "intersection(as, unit()) === unit()" $ do
as <- forAll genSetPattern
let
original = intersectionSet as unitSet
expect = Pattern.fromTermLike (asInternal Set.empty)
(===) expect =<< evaluate original
(===) Pattern.top =<< evaluate (mkEquals_ original unitSet)

test_intersection_idem :: TestTree
test_intersection_idem =
testPropertyWithSolver "intersection(as, as) === as" $ do
as <- forAll genConcreteSet
let
termLike = asTermLike as
original = intersectionSet termLike termLike
expect = Pattern.fromTermLike (asInternal as)
(===) expect =<< evaluate original
(===) Pattern.top =<< evaluate (mkEquals_ original termLike)

setVariableGen :: Sort -> Gen (Set Variable)
setVariableGen sort =
Gen.set (Range.linear 0 32) (standaloneGen $ variableGen sort)
Expand Down