Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using loss with substituted receiver terms in exhaleExt #797

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/scala/rules/ChunkSupporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ object chunkSupporter extends ChunkSupportRules {
val id = ChunkIdentifier(resource, s.program)
if (s.exhaleExt) {
val failure = createFailure(ve, v, s)
magicWandSupporter.transfer(s, perms, failure, v)(consumeGreedy(_, _, id, args, _, _))((s1, optCh, v1) =>
magicWandSupporter.transfer(s, perms, failure, Seq(), v)(consumeGreedy(_, _, id, args, _, _))((s1, optCh, v1) =>
Q(s1, h, optCh.flatMap(ch => Some(ch.snap)), v1))
} else {
executionFlowController.tryOrFail2[Heap, Option[Term]](s.copy(h = h), v)((s1, v1, QS) =>
Expand Down Expand Up @@ -162,7 +162,7 @@ object chunkSupporter extends ChunkSupportRules {
newHeap = newHeap + newChunk
assumeProperties(newChunk, newHeap)
}
(ConsumptionResult(PermMinus(perms, toTake), v, 0), s, newHeap, takenChunk)
(ConsumptionResult(PermMinus(perms, toTake), Seq(), v, 0), s, newHeap, takenChunk)
} else {
if (v.decider.check(ch.perm !== NoPerm, Verifier.config.checkTimeout())) {
v.decider.assume(PermLess(perms, ch.perm))
Expand Down
11 changes: 8 additions & 3 deletions src/main/scala/rules/ConsumptionResult.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

package viper.silicon.rules

import viper.silicon.state.terms.Term
import viper.silicon.state.terms.{Forall, Term, Var}
import viper.silicon.state.terms.perms.IsNonPositive
import viper.silicon.verifier.Verifier

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

object ConsumptionResult {
def apply(term: Term, v: Verifier, timeout: Int): ConsumptionResult = {
if (v.decider.check(IsNonPositive(term), timeout))
def apply(term: Term, qvars: Seq[Var], v: Verifier, timeout: Int): ConsumptionResult = {
val toCheck = if (qvars.isEmpty) {
IsNonPositive(term)
} else {
Forall(qvars, IsNonPositive(term), Seq())
}
if (v.decider.check(toCheck, timeout))
Complete()
else
Incomplete(term)
Expand Down
6 changes: 4 additions & 2 deletions src/main/scala/rules/MagicWandSupporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,13 @@ object magicWandSupporter extends SymbolicExecutionRules {
hs: Stack[Heap],
pLoss: Term,
failure: Failure,
qvars: Seq[Var],
v: Verifier)
(consumeFunction: (State, Heap, Term, Verifier) => (ConsumptionResult, State, Heap, Option[CH]))
(Q: (State, Stack[Heap], Stack[Option[CH]], Verifier) => VerificationResult)
: VerificationResult = {

val initialConsumptionResult = ConsumptionResult(pLoss, v, Verifier.config.checkTimeout())
val initialConsumptionResult = ConsumptionResult(pLoss, qvars, v, Verifier.config.checkTimeout())
/* TODO: Introduce a dedicated timeout for the permission check performed by ConsumptionResult,
* instead of using checkTimeout. Reason: checkTimeout is intended for checks that are
* optimisations, e.g. detecting if a chunk provided no permissions or if a branch is
Expand Down Expand Up @@ -397,6 +398,7 @@ object magicWandSupporter extends SymbolicExecutionRules {
(s: State,
perms: Term,
failure: Failure,
qvars: Seq[Var],
v: Verifier)
(consumeFunction: (State, Heap, Term, Verifier) => (ConsumptionResult, State, Heap, Option[CH]))
(Q: (State, Option[CH], Verifier) => VerificationResult)
Expand All @@ -414,7 +416,7 @@ object magicWandSupporter extends SymbolicExecutionRules {
*/
val preMark = v.decider.setPathConditionMark()
executionFlowController.tryOrFail2[Stack[Heap], Stack[Option[CH]]](s, v)((s1, v1, QS) =>
magicWandSupporter.consumeFromMultipleHeaps(s1, s1.reserveHeaps.tail, perms, failure, v1)(consumeFunction)(QS)
magicWandSupporter.consumeFromMultipleHeaps(s1, s1.reserveHeaps.tail, perms, failure, qvars, v1)(consumeFunction)(QS)
)((s2, hs2, chs2, v2) => {
val conservedPcs = s2.conservedPcs.head :+ v2.decider.pcs.after(preMark)
val s3 = s2.copy(conservedPcs = conservedPcs +: s2.conservedPcs.tail, reserveHeaps = s.reserveHeaps.head +: hs2)
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/rules/QuantifiedChunkSupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1124,8 +1124,9 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
if (s.exhaleExt) {
magicWandSupporter.transfer[QuantifiedBasicChunk](
s.copy(smCache = smCache1),
loss,
lossOfInvOfLoc,
createFailure(pve dueTo insufficientPermissionReason/*InsufficientPermission(acc.loc)*/, v, s),
formalQVars,
v)((s2, heap, rPerm, v2) => {
val (relevantChunks, otherChunks) =
quantifiedChunkSupporter.splitHeap[QuantifiedBasicChunk](
Expand Down Expand Up @@ -1241,7 +1242,7 @@ object quantifiedChunkSupporter extends QuantifiedChunkSupport {
case wand: ast.MagicWand => createFailure(pve dueTo MagicWandChunkNotFound(wand), v, s)
case _ => sys.error(s"Found resource $resourceAccess, which is not yet supported as a quantified resource.")
}
magicWandSupporter.transfer(s, permissions, failure, v)((s1, h1, rPerm, v1) => {
magicWandSupporter.transfer(s, permissions, failure, Seq(), v)((s1, h1, rPerm, v1) => {
val (relevantChunks, otherChunks) =
quantifiedChunkSupporter.splitHeap[QuantifiedBasicChunk](h1, chunkIdentifier)
val (result, s2, remainingChunks) = quantifiedChunkSupporter.removePermissions(
Expand Down
Loading