@@ -17,11 +17,15 @@ import Prelude.Kore
17
17
import Control.Error
18
18
( MaybeT
19
19
)
20
+ import qualified Control.Lens as Lens
21
+ import Control.Monad
22
+ ( zipWithM
23
+ )
20
24
import Control.Monad.Reader
21
25
( MonadReader
22
26
)
23
27
import qualified Control.Monad.Reader as Reader
24
- import qualified Data.Bifunctor as Bifunctor
28
+ import qualified Data.List as List
25
29
import qualified Data.Map.Strict as Map
26
30
27
31
import Kore.Attribute.Pattern.FreeVariables
@@ -171,8 +175,6 @@ generalizeMapElement freeVariables' element =
171
175
newBuiltinAssocCommCeilSimplifier
172
176
:: forall normalized variable simplifier
173
177
. InternalVariable variable
174
- => Ord (Element normalized (TermLike variable ))
175
- => Ord (Value normalized (TermLike variable ))
176
178
=> MonadReader (SideCondition variable ) simplifier
177
179
=> MonadSimplify simplifier
178
180
=> Traversable (Value normalized )
@@ -186,95 +188,112 @@ newBuiltinAssocCommCeilSimplifier mkBuiltin mkNotMember =
186
188
CeilSimplifier $ \ Ceil { ceilChild } -> do
187
189
let internalAc@ InternalAc { builtinAcChild } = ceilChild
188
190
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
222
231
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
251
283
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
273
284
274
285
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
278
297
sideCondition <- Reader. ask
279
298
Equals. makeEvaluateTermsToPredicate tMin tMax sideCondition
280
299
>>= Not. simplifyEvaluatedPredicate
@@ -283,30 +302,37 @@ definePairWiseElements mkBuiltin mkNotMember internalAc pairWiseElements = do
283
302
(tMin, tMax) = minMax t1 t2
284
303
285
304
notMember
286
- :: (Element normalized (TermLike variable ), TermLike variable )
305
+ :: TermLike variable
306
+ -> Element normalized (TermLike variable )
287
307
-> MultiAnd (OrCondition variable )
288
- notMember (element, termLike) =
308
+ notMember termLike element =
289
309
mkNotMember element termLike
290
310
& OrCondition. fromPredicate
291
311
& MultiAnd. singleton
292
312
293
- defineOpaquePair
294
- :: (TermLike variable , TermLike variable )
313
+ notMembers
314
+ :: NormalizedAc normalized Key (TermLike variable )
315
+ -> TermLike variable
295
316
-> 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'
310
336
311
337
fromElement
312
338
:: AcWrapper normalized
0 commit comments