Skip to content

Commit f3709ec

Browse files
committed
Add support for non-incremental solver
1 parent be112cb commit f3709ec

File tree

6 files changed

+108
-9
lines changed

6 files changed

+108
-9
lines changed

src/it/scala/inox/tip/TipTestSuite.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ class TipTestSuite extends TestSuite with ResourceUtils {
1313
Seq(optSelectedSolvers(Set("nativez3")), optCheckModels(true)),
1414
Seq(optSelectedSolvers(Set("smt-z3")), optCheckModels(true)),
1515
Seq(optSelectedSolvers(Set("smt-cvc4")), optCheckModels(true)),
16-
Seq(optSelectedSolvers(Set("smt-z3")), optCheckModels(true), optAssumeChecked(true))
16+
Seq(optSelectedSolvers(Set("smt-z3")), optCheckModels(true), optAssumeChecked(true)),
17+
Seq(optSelectedSolvers(Set("smt-z3")), optCheckModels(true), optNonIncremental(true))
1718
)
1819

1920
override protected def optionsString(options: Options): String = {
2021
"solver=" + options.findOptionOrDefault(optSelectedSolvers).head +
21-
(if (options.findOptionOrDefault(optAssumeChecked)) " assumechecked" else "")
22+
(if (options.findOptionOrDefault(optAssumeChecked)) " assumechecked" else "") +
23+
(if (options.findOptionOrDefault(optNonIncremental)) " --no-incremental" else "")
2224
}
2325

2426
private def ignoreSAT(ctx: Context, file: java.io.File): FilterStatus =

src/main/scala/inox/Main.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ trait MainHelpers {
1111
protected def getDebugSections: Set[DebugSection] = Set(
1212
utils.DebugSectionTimers,
1313
solvers.DebugSectionSolver,
14+
solvers.smtlib.DebugSectionSMT,
1415
tip.DebugSectionTip
1516
)
1617

@@ -45,6 +46,7 @@ trait MainHelpers {
4546
protected def getOptions: Map[OptionDef[_], Description] = Map(
4647
optHelp -> Description(General, "Show help message"),
4748
optNoColors -> Description(General, "Disable colored output and non-ascii characters (enable this option for better support in IDEs)"),
49+
optNonIncremental -> Description(General, "Disable incremental mode in solvers"),
4850
optTimeout -> Description(General, "Set a timeout for the solver (in sec.)"),
4951
optSelectedSolvers -> Description(General, {
5052
"Use solvers s1,s2,...\nAvailable: " +

src/main/scala/inox/Options.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,5 @@ object optSelectedSolvers extends SetOptionDef[String] {
232232
}
233233

234234
object optNoColors extends inox.FlagOptionDef("no-colors", false)
235+
236+
object optNonIncremental extends inox.FlagOptionDef("no-incremental", false)

src/main/scala/inox/solvers/SolverFactory.scala

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,40 @@ object SolverFactory {
9797
val targetProgram: Program { val trees: inox.trees.type }
9898
})(implicit sem: p.Semantics): SolverFactory { val program: p.type; type S <: TimeoutSolver { val program: p.type } } = {
9999

100+
val nonIncremental = ctx.options.findOptionOrDefault(optNonIncremental)
101+
def nonIncrementalWrap[T, M](targetProgram: Program)(
102+
nme: String,
103+
targetSem: targetProgram.Semantics,
104+
underlyingSolver: () => AbstractSolver {
105+
val program: targetProgram.type
106+
type Trees = T
107+
type Model = M
108+
}):
109+
AbstractSolver {
110+
val program: targetProgram.type
111+
type Trees = T
112+
type Model = M
113+
} = {
114+
115+
if (nonIncremental) {
116+
new {
117+
val program: targetProgram.type = targetProgram
118+
val context = ctx
119+
} with NonIncrementalSolver {
120+
type Trees = T
121+
type Model = M
122+
val semantics: targetProgram.Semantics = targetSem
123+
def name = s"no-inc:$nme"
124+
125+
def underlying() = underlyingSolver()
126+
}
127+
} else {
128+
underlyingSolver()
129+
}
130+
}
131+
100132
val finalName = if (force) {
101-
name
133+
name
102134
} else {
103135
fallbacks.get(name) match {
104136
case Some((guard, names, requirement)) if !guard() =>
@@ -129,6 +161,15 @@ object SolverFactory {
129161
}
130162
}
131163

164+
if (
165+
nonIncremental &&
166+
finalName != "smt-cvc4" &&
167+
finalName != "unrollz3" &&
168+
finalName != "smt-z3" &&
169+
!finalName.startsWith("smt-z3:")
170+
)
171+
throw FatalError(s"Option --no-incremental is not compatible with solver $finalName")
172+
132173
finalName match {
133174
case "nativez3" => create(p)(finalName, {
134175
val chooseEnc = ChooseEncoder(p)(enc)
@@ -195,12 +236,12 @@ object SolverFactory {
195236
override protected lazy val targetProgram: targetProg.type = targetProg
196237
override protected val targetSemantics = targetSem
197238

198-
protected val underlying = new {
239+
protected val underlying = nonIncrementalWrap(progEnc.targetProgram)(finalName, targetSem, () => new {
199240
val program: progEnc.targetProgram.type = progEnc.targetProgram
200241
val context = ctx
201242
} with z3.UninterpretedZ3Solver {
202243
val semantics: program.Semantics = targetSem
203-
}
244+
})
204245
}
205246
})
206247

@@ -256,13 +297,13 @@ object SolverFactory {
256297
override protected lazy val targetProgram: targetProg.type = targetProg
257298
override protected val targetSemantics = targetSem
258299

259-
protected val underlying = new {
300+
protected val underlying = nonIncrementalWrap(progEnc.targetProgram)(finalName, targetSem, () => new {
260301
val program: progEnc.targetProgram.type = progEnc.targetProgram
261302
val context = ctx
262303
} with smtlib.Z3Solver {
263304
val semantics: program.Semantics = targetSem
264305
override def targetName = executableName
265-
}
306+
})
266307
}
267308
})
268309

@@ -288,12 +329,12 @@ object SolverFactory {
288329
override protected lazy val targetProgram: targetProg.type = targetProg
289330
override protected val targetSemantics = targetSem
290331

291-
protected val underlying = new {
332+
protected val underlying = nonIncrementalWrap(progEnc.targetProgram)(finalName, targetSem, () => new {
292333
val program: progEnc.targetProgram.type = progEnc.targetProgram
293334
val context = ctx
294335
} with smtlib.CVC4Solver {
295336
val semantics: program.Semantics = targetSem
296-
}
337+
})
297338
}
298339
})
299340

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* Copyright 2009-2018 EPFL, Lausanne */
2+
3+
package inox
4+
package solvers
5+
package combinators
6+
7+
import utils._
8+
import scala.concurrent.duration._
9+
import scala.collection.mutable.ArrayBuffer
10+
11+
trait NonIncrementalSolver extends AbstractSolver { self =>
12+
import program.trees._
13+
import SolverResponses._
14+
15+
protected def underlying(): AbstractSolver {
16+
val program: self.program.type
17+
type Trees = self.Trees
18+
type Model = self.Model
19+
}
20+
21+
val assertions: IncrementalSet[Trees] = new IncrementalSet[Trees]
22+
23+
val allSolvers: ArrayBuffer[AbstractSolver] = ArrayBuffer()
24+
25+
def assertCnstr(expression: Trees): Unit = assertions += expression
26+
def reset(): Unit = assertions.clear()
27+
def free(): Unit = for (solver <- allSolvers) solver.free()
28+
def interrupt(): Unit = for (solver <- allSolvers) solver.interrupt()
29+
30+
override def check(config: CheckConfiguration): config.Response[Model, Assumptions] = {
31+
val newSolver = underlying()
32+
allSolvers.append(newSolver)
33+
for (expression <- assertions)
34+
newSolver.assertCnstr(expression)
35+
newSolver.check(config)
36+
}
37+
38+
override def checkAssumptions(config: Configuration)
39+
(assumptions: Set[Trees]): config.Response[Model, Assumptions] = {
40+
val newSolver = underlying()
41+
allSolvers.append(newSolver)
42+
for (expression <- assertions)
43+
newSolver.assertCnstr(expression)
44+
newSolver.checkAssumptions(config)(assumptions)
45+
}
46+
47+
def push(): Unit = assertions.push()
48+
def pop(): Unit = assertions.pop()
49+
}

src/main/scala/inox/solvers/smtlib/SMTLIBDebugger.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package smtlib
77
import utils._
88
import _root_.smtlib.trees.Terms._
99

10+
case object DebugSectionSMT extends DebugSection("smt")
11+
1012
trait SMTLIBDebugger extends SMTLIBTarget {
1113
import context._
1214
import program._
@@ -22,6 +24,7 @@ trait SMTLIBDebugger extends SMTLIBTarget {
2224

2325
/* Printing VCs */
2426
protected lazy val debugOut: Option[java.io.FileWriter] = {
27+
implicit val debugSection = DebugSectionSMT
2528
if (reporter.isDebugEnabled) {
2629
val file = options.findOptionOrDefault(Main.optFiles).headOption.map(_.getName).getOrElse("NA")
2730
val n = DebugFileNumbers.next(targetName + file)

0 commit comments

Comments
 (0)