@@ -36,6 +36,7 @@ import Control.Error
3636 , runMaybeT
3737 )
3838import qualified Control.Monad as Monad
39+ import qualified Data.Foldable as Foldable
3940import qualified Data.HashMap.Strict as HashMap
4041import Data.Map.Strict
4142 ( Map
@@ -63,21 +64,25 @@ import qualified Kore.Builtin.Builtin as Builtin
6364import qualified Kore.Builtin.Int as Int
6465import qualified Kore.Builtin.List as Builtin.List
6566import qualified Kore.Builtin.Map.Map as Map
66- import qualified Kore.Builtin.Set as Set
67+ import qualified Kore.Builtin.Set as Builtin. Set
6768import qualified Kore.Domain.Builtin as Domain
6869import Kore.IndexedModule.MetadataTools
6970 ( SmtMetadataTools
7071 )
7172import qualified Kore.Internal.Condition as Condition
73+ import qualified Kore.Internal.OrPattern as OrPattern
7274import Kore.Internal.Pattern
73- ( Pattern
75+ ( Condition
76+ , Pattern
7477 )
7578import qualified Kore.Internal.Pattern as Pattern
7679import Kore.Internal.Predicate
7780 ( makeCeilPredicate
7881 )
82+ import qualified Kore.Internal.SideCondition as SideCondition
7983import Kore.Internal.Symbol
80- ( symbolHook
84+ ( Symbol (.. )
85+ , symbolHook
8186 )
8287import Kore.Internal.TermLike
8388 ( pattern App_
@@ -89,6 +94,7 @@ import qualified Kore.Internal.TermLike as TermLike
8994import Kore.Sort
9095 ( Sort
9196 )
97+ import qualified Kore.Sort as Sort
9298import Kore.Step.Simplification.NotSimplifier
9399import Kore.Step.Simplification.Simplify as Simplifier
94100import Kore.Syntax.Sentence
@@ -97,6 +103,7 @@ import Kore.Syntax.Sentence
97103import Kore.Unification.Unify
98104 ( MonadUnify
99105 )
106+ import qualified Kore.Unification.Unify as Unify
100107import qualified Kore.Unification.Unify as Monad.Unify
101108import Kore.Variables.Fresh
102109
@@ -186,7 +193,7 @@ symbolVerifiers =
186193 , Builtin. verifySymbol Bool. assertSort [acceptAnySort, assertSort]
187194 )
188195 , ( Map. keysKey
189- , Builtin. verifySymbol Set. assertSort [assertSort]
196+ , Builtin. verifySymbol Builtin. Set. assertSort [assertSort]
190197 )
191198 , ( Map. keys_listKey
192199 , Builtin. verifySymbol Builtin.List. assertSort [assertSort]
@@ -195,7 +202,7 @@ symbolVerifiers =
195202 , Builtin. verifySymbol assertSort [assertSort, acceptAnySort]
196203 )
197204 , ( Map. removeAllKey
198- , Builtin. verifySymbol assertSort [assertSort, Set. assertSort]
205+ , Builtin. verifySymbol assertSort [assertSort, Builtin. Set. assertSort]
199206 )
200207 , ( Map. sizeKey
201208 , Builtin. verifySymbol Int. assertSort [assertSort]
@@ -384,7 +391,7 @@ evalKeys :: Builtin.Function
384391evalKeys resultSort [_map] = do
385392 _map <- expectConcreteBuiltinMap Map. keysKey _map
386393 fmap (const Domain. SetValue ) _map
387- & Set. returnConcreteSet resultSort
394+ & Builtin. Set. returnConcreteSet resultSort
388395evalKeys _ _ = Builtin. wrongArity Map. keysKey
389396
390397evalKeysList :: Builtin. Function
@@ -420,7 +427,7 @@ evalRemoveAll resultSort [_map, _set] = do
420427 bothConcrete = do
421428 _map <- expectConcreteBuiltinMap Map. removeAllKey _map
422429 _set <-
423- Set. expectConcreteBuiltinSet
430+ Builtin. Set. expectConcreteBuiltinSet
424431 Map. removeAllKey
425432 _set
426433 Map. difference _map _set
@@ -568,26 +575,30 @@ unifyEquals unifyEqualsChildren first second = do
568575 :: Ac. NormalizedOrBottom Domain. NormalizedMap variable
569576 normalizedOrBottom = Ac. toNormalized patt
570577
571- newtype InKeys term = InKeys { getInKeys :: Set. InKeys term }
578+ data InKeys term =
579+ InKeys
580+ { symbol :: ! Symbol
581+ , keyTerm , mapTerm :: ! term
582+ }
572583
573584instance
574585 InternalVariable variable
575586 => Injection (TermLike variable ) (InKeys (TermLike variable ))
576587 where
577- inject ( InKeys Set. InKeys { symbol, keyTerm, mapTerm } ) =
588+ inject InKeys { symbol, keyTerm, mapTerm } =
578589 TermLike. mkApplySymbol symbol [keyTerm, mapTerm]
579590
580591 retract (App_ symbol [keyTerm, mapTerm]) = do
581592 hook2 <- (getHook . symbolHook) symbol
582593 Monad. guard (hook2 == Map. in_keysKey)
583- return $ InKeys Set. InKeys { symbol, keyTerm, mapTerm }
594+ return InKeys { symbol, keyTerm, mapTerm }
584595 retract _ = empty
585596
586597matchInKeys
587598 :: InternalVariable variable
588599 => TermLike variable
589- -> Maybe (Set. InKeys (TermLike variable ))
590- matchInKeys = fmap getInKeys . retract
600+ -> Maybe (InKeys (TermLike variable ))
601+ matchInKeys = retract
591602
592603unifyNotInKeys
593604 :: forall variable unifier
@@ -598,8 +609,73 @@ unifyNotInKeys
598609 -> TermLike variable
599610 -> TermLike variable
600611 -> MaybeT unifier (Pattern variable )
601- unifyNotInKeys =
602- Set. unifyNotInKeys
603- (Ac. toNormalized @ Domain. NormalizedMap )
604- matchInKeys
605- (inject . InKeys )
612+ unifyNotInKeys unifyChildren (NotSimplifier notSimplifier) a b =
613+ worker a b <|> worker b a
614+ where
615+ normalizedOrBottom
616+ :: TermLike variable
617+ -> Ac. NormalizedOrBottom Domain. NormalizedMap variable
618+ normalizedOrBottom = Ac. toNormalized
619+
620+ defineTerm :: TermLike variable -> MaybeT unifier (Condition variable )
621+ defineTerm termLike =
622+ makeEvaluateTermCeil SideCondition. topTODO Sort. predicateSort termLike
623+ >>= Unify. scatter
624+ & lift
625+
626+ eraseTerm =
627+ Pattern. fromCondition_ . Pattern. withoutTerm
628+
629+ unifyAndNegate t1 t2 = do
630+ -- Erasing the unified term is valid here because
631+ -- the terms are all wrapped in \ceil below.
632+ unificationSolutions <-
633+ fmap eraseTerm
634+ <$> Unify. gather (unifyChildren t1 t2)
635+ notSimplifier
636+ SideCondition. top
637+ (OrPattern. fromPatterns unificationSolutions)
638+ >>= Unify. scatter
639+
640+ collectConditions terms =
641+ Foldable. fold terms
642+ & Pattern. fromCondition_
643+
644+ worker
645+ :: TermLike variable
646+ -> TermLike variable
647+ -> MaybeT unifier (Pattern variable )
648+ worker termLike1 termLike2
649+ | Just boolValue <- Bool. matchBool termLike1
650+ , not boolValue
651+ , Just inKeys@ InKeys { keyTerm, mapTerm } <- matchInKeys termLike2
652+ , Ac. Normalized normalizedMap <- normalizedOrBottom mapTerm
653+ = do
654+ let symbolicKeys = Domain. getSymbolicKeysOfAc normalizedMap
655+ concreteKeys =
656+ TermLike. fromConcrete
657+ <$> Domain. getConcreteKeysOfAc normalizedMap
658+ mapKeys = symbolicKeys <> concreteKeys
659+ opaqueElements = Domain. opaque . Domain. unwrapAc $ normalizedMap
660+ if null mapKeys && null opaqueElements then
661+ return Pattern. top
662+ else do
663+ Monad. guard (not (null mapKeys) || (length opaqueElements > 1 ))
664+ -- Concrete keys are constructor-like, therefore they are defined
665+ TermLike. assertConstructorLikeKeys concreteKeys $ return ()
666+ definedKey <- defineTerm keyTerm
667+ definedMap <- defineTerm mapTerm
668+ keyConditions <- lift $ traverse (unifyAndNegate keyTerm) mapKeys
669+
670+ let keyInKeysOpaque =
671+ (\ term -> inject @ (TermLike _ ) inKeys { mapTerm = term })
672+ <$> opaqueElements
673+
674+ opaqueConditions <-
675+ lift $ traverse (unifyChildren termLike1) keyInKeysOpaque
676+ let conditions =
677+ fmap Pattern. withoutTerm (keyConditions <> opaqueConditions)
678+ <> [definedKey, definedMap]
679+ return $ collectConditions conditions
680+
681+ worker _ _ = empty
0 commit comments