Skip to content

Commit

Permalink
Merge pull request #754 from viperproject/meilers_unfold_none
Browse files Browse the repository at this point in the history
Unfold, fold, and unfolding must have a strictly positive permission amount
  • Loading branch information
marcoeilers authored Oct 9, 2023
2 parents 6617d23 + ace7052 commit e85c426
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/rules/Evaluator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ object evaluator extends EvaluationRules {
if (s.cycles(predicate) < Verifier.config.recursivePredicateUnfoldings()) {
evals(s, eArgs, _ => pve, v)((s1, tArgs, v1) =>
eval(s1, ePerm, pve, v1)((s2, tPerm, v2) =>
v2.decider.assert(IsNonNegative(tPerm)) { // TODO: Replace with permissionSupporter.assertNotNegative
v2.decider.assert(IsPositive(tPerm)) {
case true =>
joiner.join[Term, Term](s2, v2)((s3, v3, QB) => {
val s4 = s3.incCycleCounter(predicate)
Expand Down Expand Up @@ -832,7 +832,7 @@ object evaluator extends EvaluationRules {
eval(s10, eIn, pve, v5)(QB)})})
})(join(v2.symbolConverter.toSort(eIn.typ), "joined_unfolding", s2.relevantQuantifiedVariables, v2))(Q)
case false =>
createFailure(pve dueTo NegativePermission(ePerm), v2, s2)}))
createFailure(pve dueTo NonPositivePermission(ePerm), v2, s2)}))
} else {
val unknownValue = v.decider.appliedFresh("recunf", v.symbolConverter.toSort(eIn.typ), s.relevantQuantifiedVariables)
Q(s, unknownValue, v)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/rules/Executor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ object executor extends ExecutionRules {
val pve = FoldFailed(fold)
evals(s, eArgs, _ => pve, v)((s1, tArgs, v1) =>
eval(s1, ePerm, pve, v1)((s2, tPerm, v2) =>
permissionSupporter.assertNotNegative(s2, tPerm, ePerm, pve, v2)((s3, v3) => {
permissionSupporter.assertPositive(s2, tPerm, ePerm, pve, v2)((s3, v3) => {
val wildcards = s3.constrainableARPs -- s1.constrainableARPs
predicateSupporter.fold(s3, predicate, tArgs, tPerm, wildcards, pve, v3)(Q)})))

Expand All @@ -529,7 +529,7 @@ object executor extends ExecutionRules {
s2.smCache
}

permissionSupporter.assertNotNegative(s2, tPerm, ePerm, pve, v2)((s3, v3) => {
permissionSupporter.assertPositive(s2, tPerm, ePerm, pve, v2)((s3, v3) => {
val wildcards = s3.constrainableARPs -- s1.constrainableARPs
predicateSupporter.unfold(s3.copy(smCache = smCache1), predicate, tArgs, tPerm, wildcards, pve, v3, pa)(Q)
})
Expand Down
19 changes: 17 additions & 2 deletions src/main/scala/rules/PermissionSupporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import viper.silver.ast
import viper.silver.verifier.PartialVerificationError
import viper.silicon.interfaces.VerificationResult
import viper.silicon.state.State
import viper.silicon.state.terms.{Term, perms, Var}
import viper.silicon.state.terms.{Term, Var, perms}
import viper.silicon.verifier.Verifier
import viper.silver.verifier.reasons.NegativePermission
import viper.silver.verifier.reasons.{NegativePermission, NonPositivePermission}

object permissionSupporter extends SymbolicExecutionRules {
def assertNotNegative(s: State, tPerm: Term, ePerm: ast.Exp, pve: PartialVerificationError, v: Verifier)
Expand All @@ -29,4 +29,19 @@ object permissionSupporter extends SymbolicExecutionRules {
}
}
}

def assertPositive(s: State, tPerm: Term, ePerm: ast.Exp, pve: PartialVerificationError, v: Verifier)
(Q: (State, Verifier) => VerificationResult)
: VerificationResult = {

tPerm match {
case k: Var if s.constrainableARPs.contains(k) =>
Q(s, v)
case _ =>
v.decider.assert(perms.IsPositive(tPerm)) {
case true => Q(s, v)
case false => createFailure(pve dueTo NonPositivePermission(ePerm), v, s)
}
}
}
}

0 comments on commit e85c426

Please sign in to comment.