@@ -149,19 +149,14 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
149
149
FramedProof [Post ](pre, body, post)(proof.blame)(proof.o)
150
150
}
151
151
152
- // def getConditions(preds: AccountedPredicate[Pre]): Seq[Expr[Pre]] =
153
- // preds match {
154
- // case UnitAccountedPredicate(pred) => getConditions(pred)
155
- // case SplitAccountedPredicate(left, right) =>
156
- // getConditions(left) ++ getConditions(right)
157
- // }
158
- //
159
- // def getConditions(e: Expr[Pre]): Seq[Expr[Pre]] =
160
- // e match {
161
- // case And(left, right) => getConditions(left) ++ getConditions(right)
162
- // case Star(left, right) => getConditions(left) ++ getConditions(right)
163
- // case other => Seq[Expr[Pre]](other)
164
- // }
152
+ override def dispatch (p : AccountedPredicate [Pre ]) : AccountedPredicate [Post ] = {
153
+ p match {
154
+ case u@ UnitAccountedPredicate (pred) =>
155
+ topLevel = true
156
+ u.rewriteDefault()
157
+ case s@ SplitAccountedPredicate (left, right) => s.rewriteDefault()
158
+ }
159
+ }
165
160
166
161
override def dispatch (loopContract : LoopContract [Pre ]): LoopContract [Post ] = {
167
162
val loopInvariant : LoopInvariant [Pre ] =
@@ -186,15 +181,18 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
186
181
187
182
topLevel = true
188
183
infoGetter.setupInfo()
184
+ val contextEverywhere = dispatch(contract.contextEverywhere)
185
+ val oldInfo = infoGetter
186
+
187
+ // Reuse information from context everywhere
189
188
val requires = dispatch(contract.requires)
190
189
equalityChecker = ExpressionEqualityCheck ()
191
- infoGetter.setupInfo()
190
+
191
+ // Again reuse information from context everywhere
192
+ infoGetter = oldInfo
192
193
val ensures = dispatch(contract.ensures)
193
- topLevel = false
194
194
equalityChecker = ExpressionEqualityCheck ()
195
-
196
- // TODO: Is context everywhere al distributed here? If not, we need to do more.
197
- val contextEverywhere = dispatch(contract.contextEverywhere)
195
+ topLevel = false
198
196
199
197
val signals = contract.signals.map(element => dispatch(element))
200
198
val givenArgs =
@@ -286,23 +284,29 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
286
284
var newBinder = false
287
285
288
286
def setData (): Unit = {
289
- val allConditions = unfoldBody(Seq ())
287
+ val allConditions = unfoldBody(Seq (), Seq () )
290
288
// Split bounds that are independent of any binding variables
291
289
val (newIndependentConditions, potentialBounds) = allConditions
292
290
.partition(indepOf(bindings, _))
293
291
independentConditions.addAll(newIndependentConditions)
294
292
getBounds(potentialBounds)
295
293
}
296
294
297
- def unfoldBody (prevConditions : Seq [Expr [Pre ]]): Seq [Expr [Pre ]] = {
295
+ def unfoldBody (prevConditions : Seq [Expr [Pre ]], scales : Seq [ Expr [ Pre ] => Expr [ Pre ]] ): Seq [Expr [Pre ]] = {
298
296
val (allConditions, mainBody) = unfoldImplies[Pre ](body)
299
297
val newConditions = prevConditions ++ allConditions
300
298
val (newVars, secondBody) =
301
299
mainBody match {
302
300
case Forall (newVars, _, secondBody) => (newVars, secondBody)
303
301
case Starall (newVars, _, secondBody) => (newVars, secondBody)
302
+ // Strip Scales
303
+ case s@ Scale (scale, res) =>
304
+ val newScales = scales :+ ((r : Expr [Pre ]) => Scale (scale, r)(s.o))
305
+ body = res
306
+ return unfoldBody(newConditions, newScales)
304
307
case _ =>
305
- body = mainBody
308
+ // Re-aply scales from right to left
309
+ body = scales.foldRight(mainBody)((s, b) => s(b))
306
310
return newConditions
307
311
}
308
312
@@ -316,7 +320,7 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
316
320
317
321
body = secondBody
318
322
319
- unfoldBody(newConditions)
323
+ unfoldBody(newConditions, scales )
320
324
}
321
325
322
326
def containsOtherBinders (e : Expr [Pre ]): Boolean = {
@@ -421,18 +425,6 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
421
425
}
422
426
}
423
427
424
- def testPairs [A ](
425
- xs : Iterable [A ],
426
- ys : Iterable [A ],
427
- f : (A , A ) => Boolean ,
428
- ): Boolean = {
429
- for (x <- xs)
430
- for (y <- ys)
431
- if (f(x, y))
432
- return true
433
- false
434
- }
435
-
436
428
/** We check if there now any binding variables which resolve to just a
437
429
* single value, which happens if it has equal lower and upper bounds. E.g.
438
430
* forall(int i,j; i == 0 && i <= j && j < 5; xs[j+i]) ==> forall(int j; 0
@@ -870,7 +862,6 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
870
862
* additionally add base_{i-1} / a_{i-1} < n_{i-1} (derived from (x_{i-1}
871
863
* < xmin_i + n_{i-1})
872
864
*/
873
- // TODO ABOVE
874
865
def check_vars_list (
875
866
vars : List [Variable [Pre ]]
876
867
): Option [SubstituteForall ] = {
@@ -989,7 +980,6 @@ case class SimplifyNestedQuantifiers[Pre <: Generation]()
989
980
Seq (PointerSubscript (newGen(arrayIndex.array), xNewVar)(
990
981
triggerBlame
991
982
))
992
- // Seq(PointerAdd(newGen(arrayIndex.array), xNewVar)(triggerBlame))
993
983
)
994
984
}
995
985
0 commit comments