diff --git a/silver b/silver index 07dce2bf8..820db76e9 160000 --- a/silver +++ b/silver @@ -1 +1 @@ -Subproject commit 07dce2bf8a90f6be9443ece6d1697b0e2767fb48 +Subproject commit 820db76e92646c57b180c7ccdc8dee0465118e62 diff --git a/src/main/scala/rules/Evaluator.scala b/src/main/scala/rules/Evaluator.scala index d8688acc8..5d9d53827 100644 --- a/src/main/scala/rules/Evaluator.scala +++ b/src/main/scala/rules/Evaluator.scala @@ -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) @@ -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) diff --git a/src/main/scala/rules/Executor.scala b/src/main/scala/rules/Executor.scala index 69fe5e98a..8b95259ad 100644 --- a/src/main/scala/rules/Executor.scala +++ b/src/main/scala/rules/Executor.scala @@ -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)}))) @@ -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) }) diff --git a/src/main/scala/rules/PermissionSupporter.scala b/src/main/scala/rules/PermissionSupporter.scala index 63cd54194..1dd0daae1 100644 --- a/src/main/scala/rules/PermissionSupporter.scala +++ b/src/main/scala/rules/PermissionSupporter.scala @@ -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) @@ -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) + } + } + } }