Skip to content

Commit 11911e8

Browse files
authored
Merge pull request #159 from jad-hamza/strings
Add string parsing alternative for Z3 4.8.12 + Respect timeouts/interrupts in non-incremental solver
2 parents 2f66f5a + fe8e5ce commit 11911e8

File tree

3 files changed

+51
-29
lines changed

3 files changed

+51
-29
lines changed

src/main/scala/inox/solvers/combinators/NonIncrementalSolver.scala

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,55 @@ trait NonIncrementalSolver extends AbstractSolver { self =>
2525
def assertCnstr(expression: Trees): Unit = assertions += expression
2626
def reset(): Unit = assertions.clear()
2727
def free(): Unit = for (solver <- currentSolver) solver.free()
28-
def interrupt(): Unit = for (solver <- currentSolver) solver.interrupt()
28+
29+
var interrupted = false
30+
31+
def interrupt(): Unit = {
32+
interrupted = true
33+
for (solver <- currentSolver) solver.interrupt()
34+
}
2935

3036
override def check(config: CheckConfiguration): config.Response[Model, Assumptions] = {
31-
assert(currentSolver.isEmpty,
32-
"`currentSolver` should be empty when invoking `check` in NonIncrementalSolver")
33-
val newSolver = underlying()
34-
try {
35-
currentSolver = Some(newSolver)
36-
for (expression <- assertions)
37-
newSolver.assertCnstr(expression)
38-
val res = newSolver.check(config)
39-
currentSolver = None
40-
res
41-
} finally {
42-
newSolver.free()
37+
if (!interrupted) {
38+
assert(currentSolver.isEmpty,
39+
"`currentSolver` should be empty when invoking `check` in NonIncrementalSolver")
40+
val newSolver = underlying()
41+
try {
42+
currentSolver = Some(newSolver)
43+
for (expression <- assertions)
44+
newSolver.assertCnstr(expression)
45+
val res = newSolver.check(config)
46+
currentSolver = None
47+
res
48+
} finally {
49+
newSolver.free()
50+
}
51+
} else {
52+
config.cast(SolverResponses.Unknown)
4353
}
4454
}
4555

4656
override def checkAssumptions(config: Configuration)
4757
(assumptions: Set[Trees]): config.Response[Model, Assumptions] = {
48-
assert(currentSolver.isEmpty,
49-
"`currentSolver` should be empty when invoking `checkAssumptions` in NonIncrementalSolver")
50-
val newSolver = underlying()
51-
try {
52-
currentSolver = Some(newSolver)
53-
for (expression <- assertions)
54-
newSolver.assertCnstr(expression)
55-
// we assert the assumptions to address: https://github.com/Z3Prover/z3/issues/5257
56-
for (assumption <- assumptions)
57-
newSolver.assertCnstr(assumption)
58-
val res = newSolver.checkAssumptions(config)(Set())
59-
currentSolver = None
60-
res
61-
} finally {
62-
newSolver.free()
58+
if (!interrupted) {
59+
assert(currentSolver.isEmpty,
60+
"`currentSolver` should be empty when invoking `checkAssumptions` in NonIncrementalSolver")
61+
val newSolver = underlying()
62+
try {
63+
currentSolver = Some(newSolver)
64+
for (expression <- assertions)
65+
newSolver.assertCnstr(expression)
66+
// we assert the assumptions to address: https://github.com/Z3Prover/z3/issues/5257
67+
for (assumption <- assumptions)
68+
newSolver.assertCnstr(assumption)
69+
val res = newSolver.checkAssumptions(config)(Set())
70+
currentSolver = None
71+
res
72+
} finally {
73+
newSolver.free()
74+
}
75+
} else {
76+
config.cast(SolverResponses.Unknown)
6377
}
6478
}
6579

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ trait SMTLIBParser {
224224
val MapType(from, to) = fromSMT(sort)
225225
FiniteMap(Seq.empty, d, from, to)
226226

227-
case _ => throw new MissformedSMTException(term, "Unknown SMT term of class: " + term.getClass)
227+
case _ => throw new MissformedSMTException(term,
228+
s"Unknown SMT term of class: ${term.getClass}:\n$term"
229+
)
228230
}
229231

230232
protected def fromSMT(sort: Sort)(implicit context: Context): Type = sort match {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,17 @@ trait Z3Target extends SMTLIBTarget with SMTLIBDebugger {
153153
case (FunctionApplication(QualifiedIdentifier(SimpleIdentifier(SSymbol("seq.unit")), None), Seq(SHexadecimal(hex))), _) =>
154154
StringLiteral(utils.StringUtils.decode(hex.repr))
155155

156+
case (FunctionApplication(QualifiedIdentifier(SimpleIdentifier(SSymbol("seq.unit")), None), args), Some(StringType())) =>
157+
StringLiteral(args.map(fromSMT(_, Some(CharType())).asInstanceOf[CharLiteral].value).mkString)
158+
156159
case (FunctionApplication(QualifiedIdentifier(SimpleIdentifier(SSymbol("str.++")), None), strs), _) =>
157160
val strings = strs.map(fromSMT(_, Some(StringType())))
158161
if (strings.isEmpty) StringLiteral("")
159162
else strings.tail.foldRight(strings.head)(StringConcat(_, _))
160163

164+
case (QualifiedIdentifier(SMTIdentifier(SSymbol("Char"), Seq(SNumeral(n))), None), Some(CharType())) =>
165+
CharLiteral(n.toChar)
166+
161167
case (QualifiedIdentifier(ExtendedIdentifier(SSymbol("as-array"), k: SSymbol), _), Some(tpe @ MapType(keyType, valueType))) =>
162168
val Some(Lambda(Seq(arg), body)) = context.getFunction(k, FunctionType(Seq(keyType), valueType))
163169

0 commit comments

Comments
 (0)