@@ -25,6 +25,9 @@ module Kore.Internal.SideCondition (
25
25
fromDefinedTerms ,
26
26
generateNormalizedAcs ,
27
27
simplifyConjunctionByAssumption ,
28
+ cacheSimplifiedFunctions ,
29
+ isSimplifiedFunction ,
30
+ fromSimplifiedFunctions ,
28
31
) where
29
32
30
33
import Changed
@@ -96,11 +99,13 @@ import Kore.Internal.Predicate (
96
99
import qualified Kore.Internal.Predicate as Predicate
97
100
import Kore.Internal.SideCondition.SideCondition as SideCondition
98
101
import Kore.Internal.Symbol (
102
+ Symbol ,
99
103
isConstructor ,
100
104
isFunction ,
101
105
isFunctional ,
102
106
)
103
107
import Kore.Internal.TermLike (
108
+ Application ,
104
109
Key ,
105
110
TermLike ,
106
111
pattern App_ ,
@@ -140,9 +145,12 @@ import qualified SQL
140
145
141
146
{- | Side condition used in the evaluation context.
142
147
143
- It contains a predicate assumed to be true, and a table of term replacements,
144
- which is used when simplifying terms. The table is constructed from the predicate,
145
- see 'simplifyConjunctionByAssumption'.
148
+ It contains:
149
+ * a predicate assumed to be true
150
+ * a table of term replacements which is used when simplifying terms
151
+ * a set of terms which are assumed to be defined
152
+ * a set of terms with function application at the top which are known to have been
153
+ simplified as much as possible during the current rewrite step
146
154
147
155
Warning! When simplifying a pattern, extra care should be taken that the
148
156
'SideCondition' sent to the simplifier isn't created from the same 'Condition'
@@ -158,6 +166,8 @@ data SideCondition variable = SideCondition
158
166
, replacementsPredicate ::
159
167
! (HashMap (Predicate variable ) (Predicate variable ))
160
168
, definedTerms :: ! (HashSet (TermLike variable ))
169
+ , simplifiedFunctions ::
170
+ ! (HashSet (Application Symbol (TermLike variable )))
161
171
}
162
172
deriving stock (Eq , Ord , Show )
163
173
deriving stock (GHC.Generic )
@@ -170,11 +180,14 @@ instance InternalVariable variable => SQL.Column (SideCondition variable) where
170
180
toColumn = SQL. toColumn . Pretty. renderText . Pretty. layoutOneLine . pretty
171
181
172
182
instance Ord variable => HasFreeVariables (SideCondition variable ) variable where
173
- freeVariables sideCondition@ (SideCondition _ _ _ _) =
183
+ freeVariables sideCondition@ (SideCondition _ _ _ _ _ ) =
174
184
freeVariables assumedTrue
175
185
<> foldMap freeVariables definedTerms
176
186
where
177
- SideCondition {assumedTrue, definedTerms} = sideCondition
187
+ SideCondition
188
+ { assumedTrue
189
+ , definedTerms
190
+ } = sideCondition
178
191
179
192
instance InternalVariable variable => Pretty (SideCondition variable ) where
180
193
pretty
@@ -208,7 +221,7 @@ instance InternalVariable variable => Pretty (SideCondition variable) where
208
221
]
209
222
210
223
instance From (SideCondition variable ) (MultiAnd (Predicate variable )) where
211
- from condition@ (SideCondition _ _ _ _) = assumedTrue condition
224
+ from condition@ (SideCondition _ _ _ _ _ ) = assumedTrue condition
212
225
{-# INLINE from #-}
213
226
214
227
instance
@@ -234,9 +247,10 @@ assumeTrue ::
234
247
assumeTrue assumedTrue =
235
248
SideCondition
236
249
{ assumedTrue
237
- , definedTerms = HashSet. empty
238
250
, replacementsTermLike = HashMap. empty
239
251
, replacementsPredicate = HashMap. empty
252
+ , definedTerms = HashSet. empty
253
+ , simplifiedFunctions = HashSet. empty
240
254
}
241
255
242
256
{- | Assumes a single 'Predicate' to be true in the context of another
@@ -272,25 +286,30 @@ from the combined predicate.
272
286
-}
273
287
addConditionWithReplacements ::
274
288
InternalVariable variable =>
275
- SideCondition variable ->
276
289
Condition variable ->
290
+ SideCondition variable ->
277
291
SideCondition variable
278
292
addConditionWithReplacements
279
- sideCondition
280
- (from @ ( Condition _ ) @ ( MultiAnd _ ) -> newCondition) =
293
+ (from @ ( Condition _ ) @ ( MultiAnd _ ) -> newCondition)
294
+ sideCondition =
281
295
let combinedConditions = oldCondition <> newCondition
282
296
(assumedTrue, assumptions) =
283
297
simplifyConjunctionByAssumption combinedConditions
284
298
& extract
285
299
Assumptions replacementsTermLike replacementsPredicate = assumptions
286
300
in SideCondition
287
301
{ assumedTrue
288
- , definedTerms
289
302
, replacementsTermLike
290
303
, replacementsPredicate
304
+ , definedTerms
305
+ , simplifiedFunctions
291
306
}
292
307
where
293
- SideCondition {assumedTrue = oldCondition, definedTerms} = sideCondition
308
+ SideCondition
309
+ { assumedTrue = oldCondition
310
+ , definedTerms
311
+ , simplifiedFunctions
312
+ } = sideCondition
294
313
295
314
{- | Smart constructor for creating a 'SideCondition' by just constructing
296
315
the replacement table from a conjunction of predicates.
@@ -310,6 +329,7 @@ constructReplacements predicates =
310
329
, replacementsTermLike
311
330
, replacementsPredicate
312
331
, definedTerms = HashSet. empty
332
+ , simplifiedFunctions = HashSet. empty
313
333
}
314
334
315
335
{- | Smart constructor for creating a `SideCondition` by assuming
@@ -338,9 +358,10 @@ top :: InternalVariable variable => SideCondition variable
338
358
top =
339
359
SideCondition
340
360
{ assumedTrue = MultiAnd. top
341
- , definedTerms = mempty
342
361
, replacementsTermLike = mempty
343
362
, replacementsPredicate = mempty
363
+ , definedTerms = mempty
364
+ , simplifiedFunctions = mempty
344
365
}
345
366
346
367
-- TODO(ana.pantilie): Should we look into removing this?
@@ -353,7 +374,7 @@ toPredicate ::
353
374
InternalVariable variable =>
354
375
SideCondition variable ->
355
376
Predicate variable
356
- toPredicate condition@ (SideCondition _ _ _ _) =
377
+ toPredicate condition@ (SideCondition _ _ _ _ _ ) =
357
378
Predicate. makeAndPredicate
358
379
assumedTruePredicate
359
380
definedPredicate
@@ -372,7 +393,7 @@ mapVariables ::
372
393
AdjSomeVariableName (variable1 -> variable2 ) ->
373
394
SideCondition variable1 ->
374
395
SideCondition variable2
375
- mapVariables adj condition@ (SideCondition _ _ _ _) =
396
+ mapVariables adj condition@ (SideCondition _ _ _ _ _ ) =
376
397
let assumedTrue' =
377
398
MultiAnd. map (Predicate. mapVariables adj) assumedTrue
378
399
replacementsTermLike' =
@@ -381,18 +402,22 @@ mapVariables adj condition@(SideCondition _ _ _ _) =
381
402
mapKeysAndValues (Predicate. mapVariables adj) replacementsPredicate
382
403
definedTerms' =
383
404
HashSet. map (TermLike. mapVariables adj) definedTerms
405
+ simplifiedFunctions' =
406
+ (HashSet. map . fmap ) (TermLike. mapVariables adj) simplifiedFunctions
384
407
in SideCondition
385
408
{ assumedTrue = assumedTrue'
386
409
, replacementsTermLike = replacementsTermLike'
387
410
, replacementsPredicate = replacementsPredicate'
388
411
, definedTerms = definedTerms'
412
+ , simplifiedFunctions = simplifiedFunctions'
389
413
}
390
414
where
391
415
SideCondition
392
416
{ assumedTrue
393
- , definedTerms
394
417
, replacementsTermLike
395
418
, replacementsPredicate
419
+ , definedTerms
420
+ , simplifiedFunctions
396
421
} = condition
397
422
398
423
-- | Utility function for mapping on the keys and values of a 'HashMap'.
@@ -414,11 +439,18 @@ fromDefinedTerms ::
414
439
fromDefinedTerms definedTerms =
415
440
top{definedTerms}
416
441
442
+ {- | Prepares the 'SideCondition' for storing in the term attributes.
443
+ Any metadata information used only in particular places during execution
444
+ is erased.
445
+ -}
417
446
toRepresentation ::
418
447
InternalVariable variable =>
419
448
SideCondition variable ->
420
449
SideCondition. Representation
421
- toRepresentation = mkRepresentation
450
+ toRepresentation sideCondition =
451
+ let sideCondition' =
452
+ sideCondition{simplifiedFunctions = HashSet. empty}
453
+ in mkRepresentation sideCondition'
422
454
423
455
-- | Looks up the term in the table of replacements.
424
456
replaceTerm ::
@@ -908,3 +940,114 @@ generateNormalizedAcs internalAc =
908
940
isDefinedInternal :: TermLike variable -> Bool
909
941
isDefinedInternal =
910
942
Attribute. isDefined . TermLike. termDefined . TermLike. extractAttributes
943
+
944
+ fromSimplifiedFunctions ::
945
+ InternalVariable variable =>
946
+ HashSet (Application Symbol (TermLike variable )) ->
947
+ SideCondition variable
948
+ fromSimplifiedFunctions simplifiedFunctions =
949
+ top{simplifiedFunctions}
950
+
951
+ {- | Stores all non-constructor function symbols appearing in a term.
952
+ Inside a rewrite step, this information is used to avoid trying to
953
+ reevaluate functions which could not be evaluated during the 'Simplify'
954
+ stage of execution.
955
+
956
+ See 'isSimplifiedFunction'.
957
+ -}
958
+ cacheSimplifiedFunctions ::
959
+ forall variable .
960
+ InternalVariable variable =>
961
+ TermLike variable ->
962
+ SideCondition variable
963
+ cacheSimplifiedFunctions =
964
+ fromSimplifiedFunctions
965
+ . extractSimplifiedFunctions
966
+ where
967
+ extractSimplifiedFunctions ::
968
+ TermLike variable ->
969
+ HashSet (Application Symbol (TermLike variable ))
970
+ extractSimplifiedFunctions (Recursive. project -> _ :< termF) =
971
+ case termF of
972
+ TermLike. ApplySymbolF symbolApp ->
973
+ let symbol = TermLike. applicationSymbolOrAlias symbolApp
974
+ children = TermLike. applicationChildren symbolApp
975
+ childrenSet = foldMap extractSimplifiedFunctions children
976
+ in if isFunction symbol && not (isConstructor symbol)
977
+ then HashSet. singleton symbolApp <> childrenSet
978
+ else childrenSet
979
+ TermLike. AndF and' ->
980
+ foldMap extractSimplifiedFunctions and'
981
+ TermLike. ApplyAliasF aliasApp ->
982
+ foldMap extractSimplifiedFunctions aliasApp
983
+ TermLike. BottomF bottom ->
984
+ foldMap extractSimplifiedFunctions bottom
985
+ TermLike. CeilF ceil ->
986
+ foldMap extractSimplifiedFunctions ceil
987
+ TermLike. DomainValueF dv ->
988
+ foldMap extractSimplifiedFunctions dv
989
+ TermLike. EqualsF equals ->
990
+ foldMap extractSimplifiedFunctions equals
991
+ TermLike. ExistsF exists ->
992
+ foldMap extractSimplifiedFunctions exists
993
+ TermLike. FloorF floor' ->
994
+ foldMap extractSimplifiedFunctions floor'
995
+ TermLike. ForallF forall' ->
996
+ foldMap extractSimplifiedFunctions forall'
997
+ TermLike. IffF iff ->
998
+ foldMap extractSimplifiedFunctions iff
999
+ TermLike. ImpliesF implies ->
1000
+ foldMap extractSimplifiedFunctions implies
1001
+ TermLike. InF in' ->
1002
+ foldMap extractSimplifiedFunctions in'
1003
+ TermLike. MuF mu ->
1004
+ foldMap extractSimplifiedFunctions mu
1005
+ TermLike. NextF next ->
1006
+ foldMap extractSimplifiedFunctions next
1007
+ TermLike. NotF not' ->
1008
+ foldMap extractSimplifiedFunctions not'
1009
+ TermLike. NuF nu ->
1010
+ foldMap extractSimplifiedFunctions nu
1011
+ TermLike. OrF or' ->
1012
+ foldMap extractSimplifiedFunctions or'
1013
+ TermLike. RewritesF rewrites ->
1014
+ foldMap extractSimplifiedFunctions rewrites
1015
+ TermLike. TopF top' ->
1016
+ foldMap extractSimplifiedFunctions top'
1017
+ TermLike. InhabitantF inh ->
1018
+ foldMap extractSimplifiedFunctions inh
1019
+ TermLike. StringLiteralF stringLit ->
1020
+ foldMap extractSimplifiedFunctions stringLit
1021
+ TermLike. InternalBoolF bool ->
1022
+ foldMap extractSimplifiedFunctions bool
1023
+ TermLike. InternalBytesF bytes ->
1024
+ foldMap extractSimplifiedFunctions bytes
1025
+ TermLike. InternalIntF int ->
1026
+ foldMap extractSimplifiedFunctions int
1027
+ TermLike. InternalStringF string ->
1028
+ foldMap extractSimplifiedFunctions string
1029
+ TermLike. InternalListF list ->
1030
+ foldMap extractSimplifiedFunctions list
1031
+ TermLike. InternalMapF map' ->
1032
+ foldMap extractSimplifiedFunctions map'
1033
+ TermLike. InternalSetF set ->
1034
+ foldMap extractSimplifiedFunctions set
1035
+ TermLike. VariableF var ->
1036
+ foldMap extractSimplifiedFunctions var
1037
+ TermLike. EndiannessF end ->
1038
+ foldMap extractSimplifiedFunctions end
1039
+ TermLike. SignednessF sign ->
1040
+ foldMap extractSimplifiedFunctions sign
1041
+ TermLike. InjF inj ->
1042
+ foldMap extractSimplifiedFunctions inj
1043
+
1044
+ {- | Decides whether a function can be further simplified or not.
1045
+ See also 'cacheSimplifiedFunctions'.
1046
+ -}
1047
+ isSimplifiedFunction ::
1048
+ InternalVariable variable =>
1049
+ Application Symbol (TermLike variable ) ->
1050
+ SideCondition variable ->
1051
+ Bool
1052
+ isSimplifiedFunction app SideCondition {simplifiedFunctions} =
1053
+ HashSet. member app simplifiedFunctions
0 commit comments