Skip to content

Commit ba4537a

Browse files
authored
Fixing wildcards that are marked as constrainable for too long (#893)
1 parent eb09327 commit ba4537a

5 files changed

Lines changed: 20 additions & 13 deletions

File tree

silver

src/main/scala/rules/Consumer.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ object consumer extends ConsumptionRules {
277277
negativePermissionReason = NegativePermission(acc.perm),
278278
notInjectiveReason = QPAssertionNotInjective(acc.loc),
279279
insufficientPermissionReason = InsufficientPermission(acc.loc),
280-
v1)(Q)
280+
v1)((s2, h2, snap, v2) => Q(s2.copy(constrainableARPs = s.constrainableARPs), h2, snap, v2))
281281
case (s1, _, _, _, _, None, v1) => Q(s1, h, if (returnSnap) Some(Unit) else None, v1)
282282
}
283283

@@ -323,7 +323,7 @@ object consumer extends ConsumptionRules {
323323
negativePermissionReason = NegativePermission(acc.perm),
324324
notInjectiveReason = QPAssertionNotInjective(acc.loc),
325325
insufficientPermissionReason = InsufficientPermission(acc.loc),
326-
v1)(Q)
326+
v1)((s2, h2, snap, v2) => Q(s2.copy(constrainableARPs = s.constrainableARPs), h2, snap, v2))
327327
case (s1, _, _, _, _, None, v1) => Q(s1, h, if (returnSnap) Some(Unit) else None, v1)
328328
}
329329

@@ -365,8 +365,8 @@ object consumer extends ConsumptionRules {
365365
negativePermissionReason = NegativePermission(ePerm),
366366
notInjectiveReason = sys.error("Quantified wand not injective"), /*ReceiverNotInjective(...)*/
367367
insufficientPermissionReason = MagicWandChunkNotFound(wand), /*InsufficientPermission(...)*/
368-
v1)(Q)
369-
case (s1, _, _, _, _, None, v1) => Q(s1, h, if (returnSnap) Some(Unit) else None, v1)
368+
v1)((s2, h2, snap, v2) => Q(s2.copy(constrainableARPs = s.constrainableARPs), h2, snap, v2))
369+
case (s1, _, _, _, _, None, v1) => Q(s1.copy(constrainableARPs = s.constrainableARPs), h, if (returnSnap) Some(Unit) else None, v1)
370370
}
371371

372372
case accPred@ast.AccessPredicate(loc @ ast.FieldAccess(eRcvr, field), ePerm)

src/main/scala/rules/Evaluator.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,13 +1006,14 @@ object evaluator extends EvaluationRules {
10061006
val s7 = s6.scalePermissionFactor(tPerm, ePermNew)
10071007
val argsPairs: List[(Term, Option[ast.Exp])] = if (withExp) tArgs zip eArgsNew.get.map(Some(_)) else tArgs zip Seq.fill(tArgs.size)(None)
10081008
val insg = s7.g + Store(predicate.formalArgs map (_.localVar) zip argsPairs)
1009-
val s7a = s7.copy(g = insg)
1009+
val s7a = s7.copy(g = insg).setConstrainable(s7.constrainableARPs, false)
10101010
produce(s7a, toSf(snap.get), body, pve, v4)((s8, v5) => {
10111011
val s9 = s8.copy(g = s7.g,
10121012
functionRecorder = s8.functionRecorder.changeDepthBy(-1),
10131013
recordVisited = s3.recordVisited,
10141014
permissionScalingFactor = s6.permissionScalingFactor,
1015-
permissionScalingFactorExp = s6.permissionScalingFactorExp)
1015+
permissionScalingFactorExp = s6.permissionScalingFactorExp,
1016+
constrainableARPs = s1.constrainableARPs)
10161017
.decCycleCounter(predicate)
10171018
val s10 = v5.stateConsolidator(s9).consolidateOptionally(s9, v5)
10181019
eval(s10, eIn, pve, v5)((s9, t9, e9, v9) => QB(s9, (t9, e9), v9))})})

src/main/scala/rules/Executor.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ object executor extends ExecutionRules {
602602
Q(s6, v3)})})})
603603

604604
case fold @ ast.Fold(pap @ ast.PredicateAccessPredicate(predAcc @ ast.PredicateAccess(eArgs, predicateName), _)) =>
605+
assert(s.constrainableARPs.isEmpty)
605606
v.decider.startDebugSubExp()
606607
val ePerm = pap.perm
607608
val predicate = s.program.findPredicate(predicateName)
@@ -617,6 +618,7 @@ object executor extends ExecutionRules {
617618
)})))
618619

619620
case unfold @ ast.Unfold(pap @ ast.PredicateAccessPredicate(pa @ ast.PredicateAccess(eArgs, predicateName), _)) =>
621+
assert(s.constrainableARPs.isEmpty)
620622
v.decider.startDebugSubExp()
621623
val ePerm = pap.perm
622624
val predicate = s.program.findPredicate(predicateName)

src/main/scala/rules/Producer.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ object producer extends ProductionRules {
321321
val perm = accPred.perm
322322
eval(s, eRcvr, pve, v)((s1, tRcvr, eRcvrNew, v1) =>
323323
eval(s1, perm, pve, v1)((s2, tPerm, ePermNew, v2) =>
324-
permissionSupporter.assertNotNegative(s2, tPerm, perm, ePermNew, pve, v2)((s3, v3) => {
324+
permissionSupporter.assertNotNegative(s2, tPerm, perm, ePermNew, pve, v2)((s2a, v3) => {
325+
val s3 = s2a.copy(constrainableARPs = s.constrainableARPs)
325326
val snap = sf(v3.symbolConverter.toSort(field.typ), v3)
326327
val gain = if (!Verifier.config.unsafeWildcardOptimization() || s2.permLocations.contains(field))
327328
PermTimes(tPerm, s3.permissionScalingFactor)
@@ -347,7 +348,8 @@ object producer extends ProductionRules {
347348
val perm = accPred.perm
348349
evals(s, eArgs, _ => pve, v)((s1, tArgs, eArgsNew, v1) =>
349350
eval(s1, perm, pve, v1)((s1a, tPerm, ePermNew, v1a) =>
350-
permissionSupporter.assertNotNegative(s1a, tPerm, perm, ePermNew, pve, v1a)((s2, v2) => {
351+
permissionSupporter.assertNotNegative(s1a, tPerm, perm, ePermNew, pve, v1a)((s1b, v2) => {
352+
val s2 = s1b.copy(constrainableARPs = s.constrainableARPs)
351353
val snap = sf(
352354
predicate.body.map(v2.snapshotSupporter.optimalSnapshotSort(_, s.program)._1)
353355
.getOrElse(sorts.Snap), v2)
@@ -430,8 +432,9 @@ object producer extends ProductionRules {
430432
evalQuantified(s, Forall, forall.variables, Seq(cond), Seq(acc.loc.rcv, acc.perm), optTrigger, qid, pve, v) {
431433
case (s1, qvars, qvarExps, Seq(tCond), eCondNew, Some((Seq(tRcvr, tPerm), rcvrPerm, tTriggers, (auxGlobals, auxNonGlobals), auxExps)), v1) =>
432434
val tSnap = sf(sorts.FieldValueFunction(v1.symbolConverter.toSort(acc.loc.field.typ), acc.loc.field.name), v1)
435+
val s1a = s1.copy(constrainableARPs = s.constrainableARPs)
433436
quantifiedChunkSupporter.produce(
434-
s1,
437+
s1a,
435438
forall,
436439
acc.loc.field,
437440
qvars, qvarExps, Seq(`?r`),
@@ -454,7 +457,7 @@ object producer extends ProductionRules {
454457
QPAssertionNotInjective(acc.loc),
455458
v1
456459
)(Q)
457-
case (s1, _, _, _, _, None, v1) => Q(s1, v1)
460+
case (s1, _, _, _, _, None, v1) => Q(s1.copy(constrainableARPs = s.constrainableARPs), v1)
458461
}
459462

460463
case QuantifiedPermissionAssertion(forall, cond, acc: ast.PredicateAccessPredicate) =>
@@ -468,8 +471,9 @@ object producer extends ProductionRules {
468471
evalQuantified(s, Forall, forall.variables, Seq(cond), acc.perm +: acc.loc.args, optTrigger, qid, pve, v) {
469472
case (s1, qvars, qvarExps, Seq(tCond), eCondNew, Some((Seq(tPerm, tArgs @ _*), permArgs, tTriggers, (auxGlobals, auxNonGlobals), auxExps)), v1) =>
470473
val tSnap = sf(sorts.PredicateSnapFunction(s1.predicateSnapMap(predicate), predicate.name), v1)
474+
val s1a = s1.copy(constrainableARPs = s.constrainableARPs)
471475
quantifiedChunkSupporter.produce(
472-
s1,
476+
s1a,
473477
forall,
474478
predicate,
475479
qvars,
@@ -495,7 +499,7 @@ object producer extends ProductionRules {
495499
QPAssertionNotInjective(acc.loc),
496500
v1
497501
)(Q)
498-
case (s1, _, _, _, _, None, v1) => Q(s1, v1)
502+
case (s1, _, _, _, _, None, v1) => Q(s1.copy(constrainableARPs = s.constrainableARPs), v1)
499503
}
500504

501505
case QuantifiedPermissionAssertion(forall, cond, wand: ast.MagicWand) =>

0 commit comments

Comments
 (0)