Skip to content

Commit 0b2dc01

Browse files
authored
Merge pull request #797 from viperproject/meilers_exhale_ext_qp_fix
Using loss with substituted receiver terms in exhaleExt
2 parents 91de4df + fc5ad3a commit 0b2dc01

4 files changed

Lines changed: 17 additions & 9 deletions

File tree

src/main/scala/rules/ChunkSupporter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ object chunkSupporter extends ChunkSupportRules {
104104
val id = ChunkIdentifier(resource, s.program)
105105
if (s.exhaleExt) {
106106
val failure = createFailure(ve, v, s)
107-
magicWandSupporter.transfer(s, perms, failure, v)(consumeGreedy(_, _, id, args, _, _))((s1, optCh, v1) =>
107+
magicWandSupporter.transfer(s, perms, failure, Seq(), v)(consumeGreedy(_, _, id, args, _, _))((s1, optCh, v1) =>
108108
Q(s1, h, optCh.flatMap(ch => Some(ch.snap)), v1))
109109
} else {
110110
executionFlowController.tryOrFail2[Heap, Option[Term]](s.copy(h = h), v)((s1, v1, QS) =>
@@ -162,7 +162,7 @@ object chunkSupporter extends ChunkSupportRules {
162162
newHeap = newHeap + newChunk
163163
assumeProperties(newChunk, newHeap)
164164
}
165-
(ConsumptionResult(PermMinus(perms, toTake), v, 0), s, newHeap, takenChunk)
165+
(ConsumptionResult(PermMinus(perms, toTake), Seq(), v, 0), s, newHeap, takenChunk)
166166
} else {
167167
if (v.decider.check(ch.perm !== NoPerm, Verifier.config.checkTimeout())) {
168168
v.decider.assume(PermLess(perms, ch.perm))

src/main/scala/rules/ConsumptionResult.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
package viper.silicon.rules
88

9-
import viper.silicon.state.terms.Term
9+
import viper.silicon.state.terms.{Forall, Term, Var}
1010
import viper.silicon.state.terms.perms.IsNonPositive
1111
import viper.silicon.verifier.Verifier
1212

@@ -26,8 +26,13 @@ private case class Incomplete(permsNeeded: Term) extends ConsumptionResult {
2626
}
2727

2828
object ConsumptionResult {
29-
def apply(term: Term, v: Verifier, timeout: Int): ConsumptionResult = {
30-
if (v.decider.check(IsNonPositive(term), timeout))
29+
def apply(term: Term, qvars: Seq[Var], v: Verifier, timeout: Int): ConsumptionResult = {
30+
val toCheck = if (qvars.isEmpty) {
31+
IsNonPositive(term)
32+
} else {
33+
Forall(qvars, IsNonPositive(term), Seq())
34+
}
35+
if (v.decider.check(toCheck, timeout))
3136
Complete()
3237
else
3338
Incomplete(term)

src/main/scala/rules/MagicWandSupporter.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,13 @@ object magicWandSupporter extends SymbolicExecutionRules {
129129
hs: Stack[Heap],
130130
pLoss: Term,
131131
failure: Failure,
132+
qvars: Seq[Var],
132133
v: Verifier)
133134
(consumeFunction: (State, Heap, Term, Verifier) => (ConsumptionResult, State, Heap, Option[CH]))
134135
(Q: (State, Stack[Heap], Stack[Option[CH]], Verifier) => VerificationResult)
135136
: VerificationResult = {
136137

137-
val initialConsumptionResult = ConsumptionResult(pLoss, v, Verifier.config.checkTimeout())
138+
val initialConsumptionResult = ConsumptionResult(pLoss, qvars, v, Verifier.config.checkTimeout())
138139
/* TODO: Introduce a dedicated timeout for the permission check performed by ConsumptionResult,
139140
* instead of using checkTimeout. Reason: checkTimeout is intended for checks that are
140141
* optimisations, e.g. detecting if a chunk provided no permissions or if a branch is
@@ -397,6 +398,7 @@ object magicWandSupporter extends SymbolicExecutionRules {
397398
(s: State,
398399
perms: Term,
399400
failure: Failure,
401+
qvars: Seq[Var],
400402
v: Verifier)
401403
(consumeFunction: (State, Heap, Term, Verifier) => (ConsumptionResult, State, Heap, Option[CH]))
402404
(Q: (State, Option[CH], Verifier) => VerificationResult)
@@ -414,7 +416,7 @@ object magicWandSupporter extends SymbolicExecutionRules {
414416
*/
415417
val preMark = v.decider.setPathConditionMark()
416418
executionFlowController.tryOrFail2[Stack[Heap], Stack[Option[CH]]](s, v)((s1, v1, QS) =>
417-
magicWandSupporter.consumeFromMultipleHeaps(s1, s1.reserveHeaps.tail, perms, failure, v1)(consumeFunction)(QS)
419+
magicWandSupporter.consumeFromMultipleHeaps(s1, s1.reserveHeaps.tail, perms, failure, qvars, v1)(consumeFunction)(QS)
418420
)((s2, hs2, chs2, v2) => {
419421
val conservedPcs = s2.conservedPcs.head :+ v2.decider.pcs.after(preMark)
420422
val s3 = s2.copy(conservedPcs = conservedPcs +: s2.conservedPcs.tail, reserveHeaps = s.reserveHeaps.head +: hs2)

src/main/scala/rules/QuantifiedChunkSupport.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,8 +1124,9 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
11241124
if (s.exhaleExt) {
11251125
magicWandSupporter.transfer[QuantifiedBasicChunk](
11261126
s.copy(smCache = smCache1),
1127-
loss,
1127+
lossOfInvOfLoc,
11281128
createFailure(pve dueTo insufficientPermissionReason/*InsufficientPermission(acc.loc)*/, v, s),
1129+
formalQVars,
11291130
v)((s2, heap, rPerm, v2) => {
11301131
val (relevantChunks, otherChunks) =
11311132
quantifiedChunkSupporter.splitHeap[QuantifiedBasicChunk](
@@ -1241,7 +1242,7 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
12411242
case wand: ast.MagicWand => createFailure(pve dueTo MagicWandChunkNotFound(wand), v, s)
12421243
case _ => sys.error(s"Found resource $resourceAccess, which is not yet supported as a quantified resource.")
12431244
}
1244-
magicWandSupporter.transfer(s, permissions, failure, v)((s1, h1, rPerm, v1) => {
1245+
magicWandSupporter.transfer(s, permissions, failure, Seq(), v)((s1, h1, rPerm, v1) => {
12451246
val (relevantChunks, otherChunks) =
12461247
quantifiedChunkSupporter.splitHeap[QuantifiedBasicChunk](h1, chunkIdentifier)
12471248
val (result, s2, remainingChunks) = quantifiedChunkSupporter.removePermissions(

0 commit comments

Comments
 (0)