Skip to content

Commit e4bd3aa

Browse files
authored
Allow matching empty sets (#4009)
This PR adds rudimentary matching of internalized sets: only empty sets are allowed to match, and an indeterminate result is returned for non-empty sets.
1 parent 6fdb95b commit e4bd3aa

File tree

5 files changed

+62
-2
lines changed

5 files changed

+62
-2
lines changed

booster/library/Booster/Pattern/Match.hs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ import Data.List (partition)
2525
import Data.List.NonEmpty as NE (NonEmpty, fromList)
2626
import Data.Map (Map)
2727
import Data.Map qualified as Map
28+
import Data.Maybe (isNothing)
2829
import Data.Sequence (Seq, (><), pattern (:<|), pattern (:|>))
2930
import Data.Sequence qualified as Seq
3031

3132
import Data.Set (Set)
3233
import Data.Set qualified as Set
3334
import Prettyprinter
3435

35-
import Booster.Definition.Attributes.Base (KListDefinition, KMapDefinition)
36+
import Booster.Definition.Attributes.Base (KListDefinition, KMapDefinition, KSetDefinition)
3637
import Booster.Definition.Base
3738
import Booster.Pattern.Base
3839
import Booster.Pattern.Pretty
@@ -262,7 +263,7 @@ match1 Eval t1@KSet{} t2@Injection{}
262263
match1 _ t1@KSet{} t2@Injection{} = failWith $ DifferentSymbols t1 t2
263264
match1 _ t1@KSet{} t2@KMap{} = failWith $ DifferentSymbols t1 t2
264265
match1 _ t1@KSet{} t2@KList{} = failWith $ DifferentSymbols t1 t2
265-
match1 _ t1@KSet{} t2@KSet{} = addIndeterminate t1 t2
266+
match1 _ t1@(KSet def1 patElements patRest) t2@(KSet def2 subjElements subjRest) = if def1 == def2 then matchSets def1 patElements patRest subjElements subjRest else failWith $ DifferentSorts t1 t2
266267
match1 _ t1@KSet{} t2@ConsApplication{} = failWith $ DifferentSymbols t1 t2
267268
match1 _ t1@KSet{} t2@FunctionApplication{} = addIndeterminate t1 t2
268269
match1 Rewrite t1@KSet{} (Var t2) = failWith $ SubjectVariableMatch t1 t2
@@ -626,6 +627,25 @@ containsOtherKeys = \case
626627
Rest OtherKey{} -> True
627628
Rest _ -> False
628629

630+
------ Internalised Sets
631+
matchSets ::
632+
KSetDefinition ->
633+
[Term] ->
634+
Maybe Term ->
635+
[Term] ->
636+
Maybe Term ->
637+
StateT MatchState (Except MatchResult) ()
638+
matchSets
639+
def
640+
patElements
641+
patRest
642+
subjElements
643+
subjRest = do
644+
-- match only empty sets, indeterminate otherwise
645+
if null patElements && null subjElements && isNothing patRest && isNothing subjRest
646+
then pure ()
647+
else addIndeterminate (KSet def patElements patRest) (KSet def subjElements subjRest)
648+
629649
------ Internalised Maps
630650
matchMaps ::
631651
KMapDefinition ->

booster/unit-tests/Test/Booster/Pattern/InternalCollections.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Test.Booster.Pattern.InternalCollections (
1111
headList,
1212
tailList,
1313
mixedList,
14+
emptySet,
1415
) where
1516

1617
import Data.ByteString.Char8 qualified as BS

booster/unit-tests/Test/Booster/Pattern/MatchEval.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Booster.Pattern.Base
1717
import Booster.Pattern.Match
1818
import Booster.Syntax.Json.Internalise (trm)
1919
import Test.Booster.Fixture
20+
import Test.Booster.Pattern.InternalCollections
2021

2122
test_match_eval :: TestTree
2223
test_match_eval =
@@ -28,6 +29,7 @@ test_match_eval =
2829
, andTerms
2930
, composite
3031
, kmapTerms
32+
, internalSets
3133
]
3234

3335
symbols :: TestTree
@@ -293,6 +295,19 @@ cornerCases =
293295
let v = var "X" someSort
294296
in errors "identical variables" v v
295297

298+
internalSets :: TestTree
299+
internalSets =
300+
testGroup
301+
"Internal sets"
302+
[ test
303+
"Can match an empty set with itself"
304+
emptySet
305+
emptySet
306+
(success [])
307+
]
308+
309+
----------------------------------------
310+
296311
test :: String -> Term -> Term -> MatchResult -> TestTree
297312
test name pat subj expected =
298313
testCase name $ matchTerms Eval testDefinition pat subj @?= expected

booster/unit-tests/Test/Booster/Pattern/MatchImplies.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ test_match_implies =
3232
, sorts
3333
, injections
3434
, internalLists
35+
, internalSets
3536
, internalMaps
3637
]
3738

@@ -377,6 +378,17 @@ internalLists =
377378

378379
klist = KList testKListDef
379380

381+
internalSets :: TestTree
382+
internalSets =
383+
testGroup
384+
"Internal sets"
385+
[ test
386+
"Can match an empty set with itself"
387+
emptySet
388+
emptySet
389+
(success [])
390+
]
391+
380392
internalMaps :: TestTree
381393
internalMaps =
382394
testGroup

booster/unit-tests/Test/Booster/Pattern/MatchRewrite.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ test_match_rewrite =
3232
, sorts
3333
, injections
3434
, internalLists
35+
, internalSets
3536
, internalMaps
3637
]
3738

@@ -376,6 +377,17 @@ internalLists =
376377

377378
klist = KList testKListDef
378379

380+
internalSets :: TestTree
381+
internalSets =
382+
testGroup
383+
"Internal sets"
384+
[ test
385+
"Can match an empty set with itself"
386+
emptySet
387+
emptySet
388+
(success [])
389+
]
390+
379391
internalMaps :: TestTree
380392
internalMaps =
381393
testGroup

0 commit comments

Comments
 (0)