Skip to content

Commit 931f994

Browse files
committed
Take measures into account when unfolding in partial evaluator
1 parent 3a74938 commit 931f994

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

core/src/main/scala/stainless/transformers/PartialEvaluator.scala

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,17 @@ trait PartialEvaluator extends SimplifierWithPC { self =>
1010
import symbols._
1111
import exprOps._
1212

13+
protected def strictlyPositive(tpe: Type, e: Expr): Expr = (tpe match {
14+
case IntegerType() => GreaterThan(e, IntegerLiteral(0))
15+
case BVType(signed, size) => GreaterThan(e, BVLiteral(signed, 0, size))
16+
case TupleType(tps) => and((1 to tps.length).map(i => strictlyPositive(tps(i-1), TupleSelect(e,i))): _*)
17+
case _ => sys.error(s"Type $tpe is not supported for measures")
18+
}).setPos(e)
19+
1320
override protected def simplify(e: Expr, path: Env): (Expr, Boolean) = e match {
21+
// case Annotated(e, Seq(Unchecked)) =>
22+
// simplify(e, path)
23+
1424
case fi @ FunctionInvocation(id, tps, args) =>
1525
val tfd = fi.tfd
1626
val (rargs, pargs) = args.map(simplify(_, path)).unzip
@@ -20,6 +30,23 @@ trait PartialEvaluator extends SimplifierWithPC { self =>
2030
case _ => false
2131
} (expr)
2232

33+
def validMeasure: Boolean = {
34+
println("measure: " + measureOf(tfd.fullBody))
35+
measureOf(tfd.fullBody) match {
36+
case Some(measure) =>
37+
val nextMeasure = exprOps.replaceFromSymbols(tfd.params.zip(args).toMap, measure)
38+
println("next: " + nextMeasure)
39+
val query = strictlyPositive(nextMeasure.getType, nextMeasure)
40+
println("query: " + query)
41+
val result = path.implies(query)
42+
43+
println("result: " + result)
44+
result
45+
46+
case None => false
47+
}
48+
}
49+
2350
def isProductiveUnfolding(inlined: Expr): Boolean = {
2451
def isKnown(expr: Expr): Boolean = expr match {
2552
case BooleanLiteral(_) => true
@@ -74,7 +101,7 @@ trait PartialEvaluator extends SimplifierWithPC { self =>
74101

75102
inlined
76103
.filterNot(containsChoose)
77-
.filter(isProductiveUnfolding)
104+
.filter(expr => validMeasure || isProductiveUnfolding(expr))
78105
.map(unfold)
79106
.getOrElse((
80107
FunctionInvocation(id, tps, rargs).copiedFrom(fi),

core/src/main/scala/stainless/transformers/SimplifierWithSolver.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import scala.language.existentials
77
import scala.concurrent.duration._
88

99
import inox.solvers.optCheckModels
10-
import inox.solvers.unrolling.optMaxUnfoldSteps
10+
import inox.solvers.unrolling.{optUnrollBound, optUnrollFactor}
1111

1212
trait SimplifierWithSolver extends inox.transformers.SimplifierWithPC { self =>
1313
import trees._
@@ -25,7 +25,7 @@ trait SimplifierWithSolver extends inox.transformers.SimplifierWithPC { self =>
2525
} = inox.Program(trees)(symbols)
2626

2727
protected val solver = {
28-
val solverContext = context.withOpts(optCheckModels(false), optMaxUnfoldSteps(1))
28+
val solverContext = context.withOpts(optCheckModels(false), optUnrollBound(1), optUnrollFactor(2))
2929
semantics.getSemantics(program)
3030
.getSolver(solverContext)
3131
.toAPI

0 commit comments

Comments
 (0)