20
20
import ap .parser .ITerm ;
21
21
import com .google .common .base .Preconditions ;
22
22
import com .google .errorprone .annotations .CanIgnoreReturnValue ;
23
+ import java .io .IOException ;
24
+ import java .io .OutputStream ;
25
+ import java .io .PrintStream ;
23
26
import java .util .ArrayDeque ;
24
27
import java .util .ArrayList ;
25
28
import java .util .Collection ;
29
32
import java .util .List ;
30
33
import java .util .Optional ;
31
34
import java .util .Set ;
35
+ import java .util .function .Supplier ;
32
36
import org .sosy_lab .common .ShutdownNotifier ;
33
37
import org .sosy_lab .common .UniqueIdGenerator ;
34
38
import org .sosy_lab .common .collect .PathCopyingPersistentTreeMap ;
@@ -89,7 +93,8 @@ public boolean isUnsat() throws SolverException {
89
93
Preconditions .checkState (!closed );
90
94
wasLastSatCheckSat = false ;
91
95
evaluatedTerms .clear ();
92
- final Value result = api .checkSat (true );
96
+
97
+ final Value result = callWithoutSystemErrStream (() -> api .checkSat (true ));
93
98
if (result .equals (SimpleAPI .ProverStatus$ .MODULE$ .Sat ())) {
94
99
wasLastSatCheckSat = true ;
95
100
evaluatedTerms .add (api .partialModelAsFormula ());
@@ -183,7 +188,7 @@ protected PrincessModel getEvaluatorWithoutChecks() throws SolverException {
183
188
* @throws SimpleAPIException if model can not be constructed.
184
189
*/
185
190
private PartialModel partialModel () throws SimpleAPIException {
186
- return api . partialModel ( );
191
+ return callWithoutSystemErrStream ( api :: partialModel );
187
192
}
188
193
189
194
@ Override
@@ -197,7 +202,7 @@ public List<BooleanFormula> getUnsatCore() {
197
202
Preconditions .checkState (!closed );
198
203
checkGenerateUnsatCores ();
199
204
final List <BooleanFormula > result = new ArrayList <>();
200
- final Set <Object > core = asJava (api . getUnsatCore ( ));
205
+ final Set <Object > core = asJava (callWithoutSystemErrStream ( api :: getUnsatCore ));
201
206
for (Object partitionId : core ) {
202
207
result .add (partitions .peek ().get (partitionId ));
203
208
}
@@ -278,4 +283,34 @@ public String toString() {
278
283
return String .format ("{%s, %s, %s}" , booleanSymbols , theorySymbols , functionSymbols );
279
284
}
280
285
}
286
+
287
+ /**
288
+ * Princess uses Ostrich as internal library. Ostrich logs to `System.err`. We redirect this
289
+ * stream to the void to avoid cluttering the output.
290
+ *
291
+ * <p>Technical dept: `System.err` is a global static field, we redirect all logging. :-(
292
+ *
293
+ * @param fn the function to call
294
+ */
295
+ @ SuppressWarnings (value = "IllegalInstantiation" )
296
+ @ CanIgnoreReturnValue
297
+ static <R > R callWithoutSystemErrStream (Supplier <R > fn ) {
298
+ final PrintStream originalErrStream = System .err ;
299
+ try (OutputStream nullOutput = new NullOutputStream ();
300
+ PrintStream nullStream = new PrintStream (nullOutput )) {
301
+ System .setErr (nullStream );
302
+ return fn .get ();
303
+ } catch (IOException ioException ) {
304
+ throw new AssertionError (ioException );
305
+ } finally {
306
+ System .setErr (originalErrStream );
307
+ }
308
+ }
309
+
310
+ private static final class NullOutputStream extends OutputStream {
311
+ @ Override
312
+ public void write (int b ) {
313
+ // do nothing
314
+ }
315
+ }
281
316
}
0 commit comments