Skip to content

Commit 74de5d0

Browse files
committed
Princess: redirect 'System.err' to avoid cluttering the output.
This is a first step for #392 . The situation is also reported to Ostrich in uuverifiers/ostrich#95 .
1 parent 693da11 commit 74de5d0

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java

+38-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import ap.parser.ITerm;
2121
import com.google.common.base.Preconditions;
2222
import com.google.errorprone.annotations.CanIgnoreReturnValue;
23+
import java.io.IOException;
24+
import java.io.OutputStream;
25+
import java.io.PrintStream;
2326
import java.util.ArrayDeque;
2427
import java.util.ArrayList;
2528
import java.util.Collection;
@@ -29,6 +32,7 @@
2932
import java.util.List;
3033
import java.util.Optional;
3134
import java.util.Set;
35+
import java.util.function.Supplier;
3236
import org.sosy_lab.common.ShutdownNotifier;
3337
import org.sosy_lab.common.UniqueIdGenerator;
3438
import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap;
@@ -89,7 +93,8 @@ public boolean isUnsat() throws SolverException {
8993
Preconditions.checkState(!closed);
9094
wasLastSatCheckSat = false;
9195
evaluatedTerms.clear();
92-
final Value result = api.checkSat(true);
96+
97+
final Value result = callWithoutSystemErrStream(() -> api.checkSat(true));
9398
if (result.equals(SimpleAPI.ProverStatus$.MODULE$.Sat())) {
9499
wasLastSatCheckSat = true;
95100
evaluatedTerms.add(api.partialModelAsFormula());
@@ -183,7 +188,7 @@ protected PrincessModel getEvaluatorWithoutChecks() throws SolverException {
183188
* @throws SimpleAPIException if model can not be constructed.
184189
*/
185190
private PartialModel partialModel() throws SimpleAPIException {
186-
return api.partialModel();
191+
return callWithoutSystemErrStream(api::partialModel);
187192
}
188193

189194
@Override
@@ -197,7 +202,7 @@ public List<BooleanFormula> getUnsatCore() {
197202
Preconditions.checkState(!closed);
198203
checkGenerateUnsatCores();
199204
final List<BooleanFormula> result = new ArrayList<>();
200-
final Set<Object> core = asJava(api.getUnsatCore());
205+
final Set<Object> core = asJava(callWithoutSystemErrStream(api::getUnsatCore));
201206
for (Object partitionId : core) {
202207
result.add(partitions.peek().get(partitionId));
203208
}
@@ -278,4 +283,34 @@ public String toString() {
278283
return String.format("{%s, %s, %s}", booleanSymbols, theorySymbols, functionSymbols);
279284
}
280285
}
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+
}
281316
}

src/org/sosy_lab/java_smt/solvers/princess/PrincessModel.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package org.sosy_lab.java_smt.solvers.princess;
1010

11+
import static org.sosy_lab.java_smt.solvers.princess.PrincessAbstractProver.callWithoutSystemErrStream;
1112
import static scala.collection.JavaConverters.asJava;
1213

1314
import ap.api.PartialModel;
@@ -69,7 +70,8 @@ class PrincessModel extends AbstractModel<IExpression, Sort, PrincessEnvironment
6970

7071
@Override
7172
public ImmutableList<ValueAssignment> asList() {
72-
scala.collection.Map<IExpression, IExpression> interpretation = model.interpretation();
73+
scala.collection.Map<IExpression, IExpression> interpretation =
74+
callWithoutSystemErrStream(model::interpretation);
7375

7476
// get abbreviations, we do not want to export them.
7577
Set<Predicate> abbrevs = new LinkedHashSet<>();
@@ -303,16 +305,16 @@ private ITerm simplifyRational(ITerm pTerm) {
303305
ITerm term = (ITerm) expr;
304306
ITerm var = api.createConstant(newVariable, getSort(term));
305307
api.addAssertion(var.$eq$eq$eq(term));
306-
api.checkSat(true);
307-
ITerm value = simplifyRational(api.evalToTerm(var));
308+
callWithoutSystemErrStream(() -> api.checkSat(true));
309+
ITerm value = simplifyRational(callWithoutSystemErrStream(() -> api.evalToTerm(var)));
308310
api.pop();
309311
prover.addEvaluatedTerm(value.$eq$eq$eq(term));
310312
return value;
311313
} else {
312314
IFormula formula = (IFormula) expr;
313315
IFormula var = api.createBooleanVariable(newVariable);
314316
api.addAssertion(var.$less$eq$greater(formula));
315-
api.checkSat(true);
317+
callWithoutSystemErrStream(() -> api.checkSat(true));
316318
IFormula value = IBoolLit$.MODULE$.apply(api.eval(var));
317319
api.pop();
318320
prover.addEvaluatedTerm(value.$less$eq$greater(formula));

0 commit comments

Comments
 (0)