@@ -12,6 +12,12 @@ import parser.Parser
12
12
import lexer .Lexer
13
13
import printer .RecursivePrinter
14
14
import interpreters ._
15
+ import smtlib .trees .Commands .*
16
+ import smtlib .trees .Terms .Term
17
+ import smtlib .trees .Tree
18
+ import smtlib .trees .TreesOps
19
+ import smtlib .theories .FixedSizeBitVectors .BitVectorSort
20
+ import smtlib .theories .FloatingPoint .FloatingPointSort
15
21
16
22
/** Provide helper functions to test solver interfaces and files.
17
23
*
@@ -43,6 +49,7 @@ trait TestHelpers {
43
49
def getZ3Interpreter : Interpreter = Z3Interpreter .buildDefault
44
50
def getCVC4Interpreter : Interpreter = CVC4Interpreter .buildDefault
45
51
def getCVC5Interpreter : Interpreter = CVC5Interpreter .buildDefault
52
+ def getBitwuzlaInterpreter : Interpreter = BitwuzlaInterpreter .buildDefault
46
53
47
54
def isZ3Available : Boolean = try {
48
55
val _: String = " z3 -help" .!!
@@ -67,6 +74,13 @@ trait TestHelpers {
67
74
case _ : Exception => false
68
75
}
69
76
77
+ def isBitwuzlaAvailable : Boolean = try {
78
+ val _: String = " bitwuzla --version" .!!
79
+ true
80
+ } catch {
81
+ case _ : Exception => false
82
+ }
83
+
70
84
def executeZ3 (file : File )(f : (String ) => Unit ): Unit = {
71
85
Seq (" z3" , " -smt2" , file.getPath) ! ProcessLogger (f, s => ())
72
86
}
@@ -79,5 +93,47 @@ trait TestHelpers {
79
93
Seq (" cvc5" , " --lang" , " smt" , file.getPath) ! ProcessLogger (f, s => ())
80
94
}
81
95
96
+ def executeBitwuzla (file : File )(f : (String ) => Unit ): Unit = {
97
+ Seq (" bitwuzla" , " -v" , " 0" , " --lang" , " --smt2" , file.getPath) ! ProcessLogger (f, s => ())
98
+ }
99
+
100
+ // //////////////////////////////////////////////////////////////
101
+ // Solver specific helpers
102
+
103
+ /**
104
+ * Is test in the fragment supported by bitwuzla?
105
+ *
106
+ * May not contain ints, reals, arrays, ADTs
107
+ *
108
+ */
109
+ def testIsBitwuzlaCompatible (cmds : Seq [Command ], formula : Term ): Boolean =
110
+ def isCompat (term : Term ): Boolean =
111
+ def violatingTerm (term : Tree , children : Seq [Boolean ]): Boolean = {
112
+ import smtlib .theories .*
113
+ term match
114
+ case FixedSizeBitVectors .BitVectorConstant (_, _) => false // internally contains IntNumeral, but in a valid place
115
+ case Ints .NumeralLit (_) => true
116
+ case Reals .DecimalLit (_) => true
117
+ case FixedSizeBitVectors .Int2BV (_, _) => true
118
+ case FixedSizeBitVectors .BV2Nat (_) => true
119
+ // this is enough to rule out the current problematic tests,
120
+ // but may need refinement
121
+ case _ => children.contains(true )
122
+ }
123
+ ! TreesOps .fold(violatingTerm)(term)
124
+
125
+ def compatibleCommand (cmd : Command ): Boolean =
126
+ cmd match
127
+ case DeclareFun (_, paramSorts, sort) => (sort +: paramSorts).forall {
128
+ case BitVectorSort (_) => true
129
+ case FloatingPointSort (_, _) => true
130
+ case _ => false
131
+ }
132
+ case DeclareSort (_, _) => false
133
+ case DeclareDatatypes (_) => false
134
+ case Assert (term) => isCompat(term)
135
+ case _ => true // may need refinement
136
+ cmds.forall(compatibleCommand) && (isCompat(formula))
137
+
82
138
}
83
139
0 commit comments