@@ -3,36 +3,44 @@ const execSync = require('child_process').execSync;
3
3
const fs = require ( 'fs' ) ;
4
4
const tmp = require ( 'tmp' ) ;
5
5
6
+ // Timeout in ms.
6
7
const timeout = 10000 ;
7
8
8
9
const potentialSolvers = [
9
10
{
10
11
name : 'z3' ,
12
+ command : 'z3' ,
11
13
params : '-smt2 rlimit=20000000 rewriter.pull_cheap_ite=true fp.spacer.q3.use_qgen=true fp.spacer.mbqi=false fp.spacer.ground_pobs=false'
12
14
} ,
15
+ {
16
+ name : 'Eldarica' ,
17
+ command : 'eld' ,
18
+ params : '-horn -t:' + ( timeout / 1000 )
19
+ } ,
13
20
{
14
21
name : 'cvc4' ,
22
+ command : 'cvc4' ,
15
23
params : '--lang=smt2 --tlimit=' + timeout
16
24
}
17
25
] ;
18
- const solvers = potentialSolvers . filter ( solver => commandExistsSync ( solver . name ) ) ;
19
26
20
- function solve ( query ) {
21
- if ( solvers . length === 0 ) {
22
- throw new Error ( 'No SMT solver available. Assertion checking will not be performed.' ) ;
27
+ const solvers = potentialSolvers . filter ( solver => commandExistsSync ( solver . command ) ) ;
28
+
29
+ function solve ( query , solver ) {
30
+ if ( solver === undefined ) {
31
+ if ( solvers . length === 0 ) {
32
+ throw new Error ( 'No SMT solver available. Assertion checking will not be performed.' ) ;
33
+ } else {
34
+ solver = solvers [ 0 ] ;
35
+ }
23
36
}
24
37
25
38
const tmpFile = tmp . fileSync ( { postfix : '.smt2' } ) ;
26
39
fs . writeFileSync ( tmpFile . name , query ) ;
27
- // TODO For now only the first SMT solver found is used.
28
- // At some point a computation similar to the one done in
29
- // SMTPortfolio::check should be performed, where the results
30
- // given by different solvers are compared and an error is
31
- // reported if solvers disagree (i.e. SAT vs UNSAT).
32
40
let solverOutput ;
33
41
try {
34
42
solverOutput = execSync (
35
- solvers [ 0 ] . name + ' ' + solvers [ 0 ] . params + ' ' + tmpFile . name , {
43
+ solver . command + ' ' + solver . params + ' ' + tmpFile . name , {
36
44
stdio : 'pipe'
37
45
}
38
46
) . toString ( ) ;
@@ -44,7 +52,9 @@ function solve (query) {
44
52
if (
45
53
! solverOutput . startsWith ( 'sat' ) &&
46
54
! solverOutput . startsWith ( 'unsat' ) &&
47
- ! solverOutput . startsWith ( 'unknown' )
55
+ ! solverOutput . startsWith ( 'unknown' ) &&
56
+ ! solverOutput . startsWith ( '(error' ) &&
57
+ ! solverOutput . startsWith ( 'error' )
48
58
) {
49
59
throw new Error ( 'Failed to solve SMT query. ' + e . toString ( ) ) ;
50
60
}
@@ -56,5 +66,5 @@ function solve (query) {
56
66
57
67
module . exports = {
58
68
smtSolver : solve ,
59
- availableSolvers : solvers . length
69
+ availableSolvers : solvers
60
70
} ;
0 commit comments