Skip to content

Commit 18f40f6

Browse files
authored
Merge pull request #136 from jad-hamza/more-z3
Add support for smt-z3 with custom executable name
2 parents 6bcf926 + 8db811f commit 18f40f6

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

src/main/scala/inox/Options.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ object optSelectedSolvers extends SetOptionDef[String] {
223223
val name = "solvers"
224224
val default = Set("nativez3")
225225
val elementParser: OptionParser[String] = { s =>
226-
stringParser(s).filter(solvers.SolverFactory.solverNames contains _)
226+
stringParser(s).filter(solvers.SolverFactory.supportedSolver)
227227
}
228228

229229
val usageRhs = "s1,s2,..."

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

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ object SolverFactory {
6565
import unrolling._
6666

6767
val solverNames = Map(
68-
"nativez3" -> "Native Z3 with z3-templates for unrolling",
69-
"nativez3-opt" -> "Native Z3 optimizer with z3-templates for unrolling",
70-
"unrollz3" -> "Native Z3 with inox-templates for unrolling",
71-
"smt-cvc4" -> "CVC4 through SMT-LIB",
72-
"smt-z3" -> "Z3 through SMT-LIB",
73-
"smt-z3-opt" -> "Z3 optimizer through SMT-LIB",
74-
"princess" -> "Princess with inox unrolling"
68+
"nativez3" -> "Native Z3 with z3-templates for unrolling",
69+
"nativez3-opt" -> "Native Z3 optimizer with z3-templates for unrolling",
70+
"unrollz3" -> "Native Z3 with inox-templates for unrolling",
71+
"smt-cvc4" -> "CVC4 through SMT-LIB",
72+
"smt-z3" -> "Z3 through SMT-LIB",
73+
"smt-z3-opt" -> "Z3 optimizer through SMT-LIB",
74+
"smt-z3:<exec>" -> "Z3 through SMT-LIB with custom executable name",
75+
"princess" -> "Princess with inox unrolling"
7576
)
7677

7778
private val fallbacks = Map(
@@ -86,6 +87,9 @@ object SolverFactory {
8687

8788
private var reported: Boolean = false
8889

90+
// extract <exec> in "smt-z3:<exec>"
91+
private def getZ3Executable(name: String): String = name.drop(7)
92+
8993
def getFromName(name: String, force: Boolean = false)
9094
(p: Program, ctx: Context)
9195
(enc: ProgramTransformer {
@@ -109,6 +113,17 @@ object SolverFactory {
109113
replacement
110114

111115
case Some(_) => name
116+
case None if name.startsWith("smt-z3:") =>
117+
val z3Exec = getZ3Executable(name)
118+
val hasZ3Exec = try {
119+
new Z3Interpreter(z3Exec, Array("-in", "-smt2"))
120+
true
121+
} catch {
122+
case _: java.io.IOException => false
123+
}
124+
125+
if (hasZ3Exec) name
126+
else throw FatalError("Unknown solver: " + z3Exec)
112127

113128
case _ => throw FatalError("Unknown solver: " + name)
114129
}
@@ -189,7 +204,7 @@ object SolverFactory {
189204
}
190205
})
191206

192-
case "smt-z3" => create(p)(finalName, {
207+
case "smt-z3-opt" => create(p)(finalName, {
193208
val chooseEnc = ChooseEncoder(p)(enc)
194209
val fullEnc = enc andThen chooseEnc
195210
val theoryEnc = theories.Z3(fullEnc.targetProgram)
@@ -201,7 +216,7 @@ object SolverFactory {
201216
val program: p.type = p
202217
val context = ctx
203218
val encoder: enc.type = enc
204-
} with UnrollingSolver with TimeoutSolver with tip.TipDebugger {
219+
} with UnrollingOptimizer with TimeoutSolver {
205220
override protected val semantics = sem
206221
override protected val chooses: chooseEnc.type = chooseEnc
207222
override protected val theories: theoryEnc.type = theoryEnc
@@ -213,25 +228,26 @@ object SolverFactory {
213228
protected val underlying = new {
214229
val program: progEnc.targetProgram.type = progEnc.targetProgram
215230
val context = ctx
216-
} with smtlib.Z3Solver {
231+
} with smtlib.optimization.Z3Optimizer {
217232
val semantics: program.Semantics = targetSem
218233
}
219234
}
220235
})
221236

222-
case "smt-z3-opt" => create(p)(finalName, {
237+
case _ if finalName == "smt-z3" || finalName.startsWith("smt-z3:") => create(p)(finalName, {
223238
val chooseEnc = ChooseEncoder(p)(enc)
224239
val fullEnc = enc andThen chooseEnc
225240
val theoryEnc = theories.Z3(fullEnc.targetProgram)
226241
val progEnc = fullEnc andThen theoryEnc
227242
val targetProg = progEnc.targetProgram
228243
val targetSem = targetProg.getSemantics
244+
val executableName = if (finalName == "smt-z3") "z3" else getZ3Executable(finalName)
229245

230246
() => new {
231247
val program: p.type = p
232248
val context = ctx
233249
val encoder: enc.type = enc
234-
} with UnrollingOptimizer with TimeoutSolver {
250+
} with UnrollingSolver with TimeoutSolver with tip.TipDebugger {
235251
override protected val semantics = sem
236252
override protected val chooses: chooseEnc.type = chooseEnc
237253
override protected val theories: theoryEnc.type = theoryEnc
@@ -243,8 +259,9 @@ object SolverFactory {
243259
protected val underlying = new {
244260
val program: progEnc.targetProgram.type = progEnc.targetProgram
245261
val context = ctx
246-
} with smtlib.optimization.Z3Optimizer {
262+
} with smtlib.Z3Solver {
247263
val semantics: program.Semantics = targetSem
264+
override def targetName = executableName
248265
}
249266
}
250267
})
@@ -307,7 +324,7 @@ object SolverFactory {
307324
}
308325
}
309326

310-
val solvers: Set[String] = solverNames.map(_._1).toSet
327+
def supportedSolver(s: String) = solverNames.contains(s) || s.startsWith("smt-z3:")
311328

312329
def getFromSettings(p: Program, ctx: Context)
313330
(enc: ProgramTransformer {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ trait Z3Target extends SMTLIBTarget with SMTLIBDebugger {
5858
protected val interpreter = {
5959
val opts = interpreterOpts
6060
reporter.debug("Invoking solver "+targetName+" with "+opts.mkString(" "))
61-
new Z3Interpreter("z3", opts.toArray) {
61+
new Z3Interpreter(targetName, opts.toArray) {
6262
override lazy val parser: Z3Parser = new Z3Parser(new Lexer(out))
6363
}
6464
}

0 commit comments

Comments
 (0)