@@ -17,11 +17,15 @@ import Prelude.Kore
1717import Control.Error
1818 ( MaybeT
1919 )
20+ import qualified Control.Lens as Lens
21+ import Control.Monad
22+ ( zipWithM
23+ )
2024import Control.Monad.Reader
2125 ( MonadReader
2226 )
2327import qualified Control.Monad.Reader as Reader
24- import qualified Data.Bifunctor as Bifunctor
28+ import qualified Data.List as List
2529import qualified Data.Map.Strict as Map
2630
2731import Kore.Attribute.Pattern.FreeVariables
@@ -171,8 +175,6 @@ generalizeMapElement freeVariables' element =
171175newBuiltinAssocCommCeilSimplifier
172176 :: forall normalized variable simplifier
173177 . InternalVariable variable
174- => Ord (Element normalized (TermLike variable ))
175- => Ord (Value normalized (TermLike variable ))
176178 => MonadReader (SideCondition variable ) simplifier
177179 => MonadSimplify simplifier
178180 => Traversable (Value normalized )
@@ -186,95 +188,112 @@ newBuiltinAssocCommCeilSimplifier mkBuiltin mkNotMember =
186188 CeilSimplifier $ \ Ceil { ceilChild } -> do
187189 let internalAc@ InternalAc { builtinAcChild } = ceilChild
188190 sideCondition <- Reader. ask
189- let symbolicKeys = getSymbolicKeysOfAc builtinAcChild
190- symbolicValues = getSymbolicValuesOfAc builtinAcChild
191- concreteValues = getConcreteValuesOfAc builtinAcChild
192- opaqueElements = opaque . unwrapAc $ builtinAcChild
193- definedKeysAndOpaque <-
194- traverse
195- (makeEvaluateTermCeil sideCondition)
196- (symbolicKeys <> opaqueElements)
197- & fmap MultiAnd. make
198- definedValues <-
199- traverse
200- (defineValue sideCondition)
201- (symbolicValues <> concreteValues)
202- & fmap mconcat
203- definedSubCollections <-
204- definePairWiseElements mkBuiltin mkNotMember internalAc
205- . generatePairWiseElements
206- $ builtinAcChild
207- let conditions =
208- definedKeysAndOpaque
209- <> definedValues
210- <> definedSubCollections
211- And. simplifyEvaluatedMultiPredicate sideCondition conditions
212- where
213- defineValue
214- :: SideCondition variable
215- -> Value normalized (TermLike variable )
216- -> MaybeT simplifier (MultiAnd (OrCondition variable ))
217- defineValue sideCondition = foldlM worker mempty
218- where
219- worker multiAnd termLike = do
220- evaluated <- makeEvaluateTermCeil sideCondition termLike
221- return (multiAnd <> MultiAnd. singleton evaluated)
191+ let normalizedAc :: NormalizedAc normalized Key (TermLike variable )
192+ normalizedAc = unwrapAc builtinAcChild
193+ NormalizedAc
194+ { elementsWithVariables = abstractElements
195+ , concreteElements
196+ , opaque
197+ }
198+ = normalizedAc
199+
200+ let defineOpaquePair
201+ :: TermLike variable
202+ -> TermLike variable
203+ -> MultiAnd (OrCondition variable )
204+ defineOpaquePair opaque1 opaque2 =
205+ internalAc
206+ { builtinAcChild =
207+ wrapAc
208+ emptyNormalizedAc { opaque = [opaque1, opaque2] }
209+ }
210+ & mkBuiltin
211+ & makeCeilPredicate
212+ -- TODO (thomas.tuegel): Do not mark this simplified.
213+ -- Marking here may prevent user-defined axioms from applying.
214+ -- At present, we wouldn't apply such an axiom, anyway.
215+ & Predicate. markSimplifiedMaybeConditional Nothing
216+ & OrCondition. fromPredicate
217+ & MultiAnd. singleton
218+
219+ defineOpaquePairs
220+ :: TermLike variable
221+ -> [TermLike variable ]
222+ -> MultiAnd (OrCondition variable )
223+ defineOpaquePairs this others =
224+ foldMap (defineOpaquePair this) others
225+
226+ definedOpaquePairs :: MultiAnd (OrCondition variable )
227+ definedOpaquePairs =
228+ mconcat
229+ $ zipWith defineOpaquePairs opaque
230+ $ tail $ List. tails opaque
222231
223- definePairWiseElements
224- :: forall variable normalized simplifier
225- . MonadSimplify simplifier
226- => InternalVariable variable
227- => MonadReader (SideCondition variable ) simplifier
228- => AcWrapper normalized
229- => MkBuiltinAssocComm normalized variable
230- -> MkNotMember normalized variable
231- -> InternalAc Key normalized (TermLike variable )
232- -> PairWiseElements normalized Key (TermLike variable )
233- -> MaybeT simplifier (MultiAnd (OrCondition variable ))
234- definePairWiseElements mkBuiltin mkNotMember internalAc pairWiseElements = do
235- definedKeyPairs <-
236- traverse
237- distinctKey
238- (symbolicKeyPairs <> symbolicConcreteKeyPairs)
239- & fmap MultiAnd. make
240- let definedElementOpaquePairs =
241- foldMap
242- notMember
243- (symbolicOpaquePairs <> concreteOpaquePairs')
244- definedOpaquePairs =
245- foldMap defineOpaquePair opaquePairs
246- return . fold $
247- [ definedKeyPairs
248- , definedElementOpaquePairs
249- , definedOpaquePairs
250- ]
232+ let abstractKeys, concreteKeys
233+ :: [TermLike variable ]
234+ abstractValues, concreteValues, allValues
235+ :: [Value normalized (TermLike variable )]
236+ (abstractKeys, abstractValues) =
237+ unzip (unwrapElement <$> abstractElements)
238+ concreteKeys = from @ Key <$> Map. keys concreteElements
239+ concreteValues = Map. elems concreteElements
240+ allValues = concreteValues <> abstractValues
241+
242+ let makeEvaluateTerm, defineAbstractKey, defineOpaque
243+ :: TermLike variable -> MaybeT simplifier (OrCondition variable )
244+ makeEvaluateTerm = makeEvaluateTermCeil sideCondition
245+ defineAbstractKey = makeEvaluateTerm
246+ defineOpaque = makeEvaluateTerm
247+
248+ defineValue
249+ :: Value normalized (TermLike variable )
250+ -> MaybeT simplifier (MultiAnd (OrCondition variable ))
251+ defineValue = foldlM worker mempty
252+ where
253+ worker multiAnd termLike = do
254+ evaluated <- makeEvaluateTerm termLike
255+ return (multiAnd <> MultiAnd. singleton evaluated)
256+
257+ TermLike. assertConstructorLikeKeys concreteKeys $ return ()
258+
259+ -- concreteKeys are defined by assumption
260+ definedKeys <- traverse defineAbstractKey abstractKeys
261+ definedOpaque <- traverse defineOpaque opaque
262+ definedValues <- traverse defineValue allValues
263+ -- concreteKeys are distinct by assumption
264+ distinctConcreteKeys <-
265+ traverse (flip distinctKey concreteKeys) abstractKeys
266+ distinctAbstractKeys <-
267+ zipWithM distinctKey
268+ abstractKeys
269+ (tail $ List. tails abstractKeys)
270+ let conditions :: MultiAnd (OrCondition variable )
271+ conditions =
272+ mconcat
273+ [ MultiAnd. make definedKeys
274+ , MultiAnd. make definedOpaque
275+ , mconcat definedValues
276+ , mconcat distinctConcreteKeys
277+ , mconcat distinctAbstractKeys
278+ , foldMap (notMembers normalizedAc) opaque
279+ , definedOpaquePairs
280+ ]
281+
282+ And. simplifyEvaluatedMultiPredicate sideCondition conditions
251283 where
252- PairWiseElements
253- { symbolicPairs
254- , opaquePairs
255- , symbolicConcretePairs
256- , symbolicOpaquePairs
257- , concreteOpaquePairs
258- } = pairWiseElements
259- symbolicKeyPairs =
260- Bifunctor. bimap
261- (fst . unwrapElement)
262- (fst . unwrapElement)
263- <$> symbolicPairs
264- symbolicConcreteKeyPairs =
265- Bifunctor. bimap
266- (fst . unwrapElement)
267- (from @ Key @ (TermLike variable ) . fst )
268- <$> symbolicConcretePairs
269- concreteOpaquePairs' =
270- Bifunctor. first
271- wrapConcreteElement
272- <$> concreteOpaquePairs
273284
274285 distinctKey
275- :: (TermLike variable , TermLike variable )
276- -> MaybeT simplifier (OrCondition variable )
277- distinctKey (t1, t2) = do
286+ :: TermLike variable
287+ -> [TermLike variable ]
288+ -> MaybeT simplifier (MultiAnd (OrCondition variable ))
289+ distinctKey thisKey otherKeys =
290+ MultiAnd. make <$> traverse (notEquals thisKey) otherKeys
291+
292+ notEquals
293+ :: TermLike variable
294+ -> TermLike variable
295+ -> MaybeT simplifier (OrCondition variable )
296+ notEquals t1 t2 = do
278297 sideCondition <- Reader. ask
279298 Equals. makeEvaluateTermsToPredicate tMin tMax sideCondition
280299 >>= Not. simplifyEvaluatedPredicate
@@ -283,30 +302,37 @@ definePairWiseElements mkBuiltin mkNotMember internalAc pairWiseElements = do
283302 (tMin, tMax) = minMax t1 t2
284303
285304 notMember
286- :: (Element normalized (TermLike variable ), TermLike variable )
305+ :: TermLike variable
306+ -> Element normalized (TermLike variable )
287307 -> MultiAnd (OrCondition variable )
288- notMember (element, termLike) =
308+ notMember termLike element =
289309 mkNotMember element termLike
290310 & OrCondition. fromPredicate
291311 & MultiAnd. singleton
292312
293- defineOpaquePair
294- :: (TermLike variable , TermLike variable )
313+ notMembers
314+ :: NormalizedAc normalized Key (TermLike variable )
315+ -> TermLike variable
295316 -> MultiAnd (OrCondition variable )
296- defineOpaquePair (opaque1, opaque2) =
297- internalAc
298- { builtinAcChild =
299- wrapAc
300- emptyNormalizedAc { opaque = [opaque1, opaque2] }
301- }
302- & mkBuiltin
303- & makeCeilPredicate
304- -- TODO (thomas.tuegel): Do not mark this simplified.
305- -- Marking here may prevent user-defined axioms from applying.
306- -- At present, we wouldn't apply such an axiom, anyway.
307- & Predicate. markSimplifiedMaybeConditional Nothing
308- & OrCondition. fromPredicate
309- & MultiAnd. singleton
317+ notMembers normalizedAc termLike =
318+ Lens. foldMapOf foldElements (notMember termLike) normalizedAc
319+
320+ foldElements
321+ :: AcWrapper collection
322+ => InternalVariable variable
323+ => Lens. Fold
324+ (NormalizedAc collection Key (TermLike variable ))
325+ (Element collection (TermLike variable ))
326+ foldElements =
327+ Lens. folding $ \ normalizedAc ->
328+ let
329+ concreteElements' =
330+ concreteElements normalizedAc
331+ & Map. toList
332+ & map wrapConcreteElement
333+ symbolicElements' = elementsWithVariables normalizedAc
334+ in
335+ concreteElements' <> symbolicElements'
310336
311337fromElement
312338 :: AcWrapper normalized
0 commit comments