Skip to content

Commit fd7ffbb

Browse files
Leonardo Altaxic
authored andcommitted
Fix SMT when Z3 returns UNSAT
1 parent 690590b commit fd7ffbb

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

smtsolver.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var tmp = require('tmp');
66
var potentialSolvers = [
77
{
88
name: 'z3',
9-
params: ''
9+
params: '-smt2'
1010
},
1111
{
1212
name: 'cvc4',
@@ -20,17 +20,36 @@ function solve (query) {
2020
throw new Error('No SMT solver available. Assertion checking will not be performed.');
2121
}
2222

23-
var tmpFile = tmp.fileSync();
23+
var tmpFile = tmp.fileSync({ postfix: '.smt2' });
2424
fs.writeFileSync(tmpFile.name, query);
2525
// TODO For now only the first SMT solver found is used.
2626
// At some point a computation similar to the one done in
2727
// SMTPortfolio::check should be performed, where the results
2828
// given by different solvers are compared and an error is
2929
// reported if solvers disagree (i.e. SAT vs UNSAT).
30-
var solverOutput = execSync(solvers[0].name + ' ' + solvers[0].params + ' ' + tmpFile.name);
30+
var solverOutput;
31+
try {
32+
solverOutput = execSync(
33+
solvers[0].name + ' ' + solvers[0].params + ' ' + tmpFile.name, {
34+
timeout: 10000
35+
}
36+
).toString();
37+
} catch (e) {
38+
// execSync throws if the process times out or returns != 0.
39+
// The latter might happen with z3 if the query asks for a model
40+
// for an UNSAT formula. We can still use stdout.
41+
solverOutput = e.stdout.toString();
42+
if (
43+
!solverOutput.startsWith('sat') &&
44+
!solverOutput.startsWith('unsat') &&
45+
!solverOutput.startsWith('unknown')
46+
) {
47+
throw new Error('Failed solve SMT query. ' + e.toString());
48+
}
49+
}
3150
// Trigger early manual cleanup
3251
tmpFile.removeCallback();
33-
return solverOutput.toString();
52+
return solverOutput;
3453
}
3554

3655
module.exports = {

0 commit comments

Comments
 (0)