Skip to content

Commit 6815ff9

Browse files
Merge pull request #701 from sosy-lab/solver-exceptions
Throw `SolverException` when interpolation fails
2 parents e7857c9 + 218f46b commit 6815ff9

5 files changed

Lines changed: 80 additions & 16 deletions

File tree

src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaInterpolatingProver.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static com.google.common.base.Preconditions.checkState;
1414

1515
import com.google.common.collect.FluentIterable;
16+
import com.google.common.collect.ImmutableSet;
1617
import com.google.common.collect.Iterables;
1718
import java.util.Collection;
1819
import java.util.List;
@@ -25,12 +26,18 @@
2526
import org.sosy_lab.java_smt.api.SolverException;
2627
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Option;
2728
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Options;
29+
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Term;
2830
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Vector_Term;
2931
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Vector_Vector_Term;
3032

3133
class BitwuzlaInterpolatingProver extends BitwuzlaAbstractProver<Integer>
3234
implements InterpolatingProverEnvironment<Integer> {
3335

36+
private static final ImmutableSet<String> ACCEPTED_INTERPOLATION_ERROR_MESSAGES =
37+
ImmutableSet.of(
38+
"interpolation queries with lemmas that use fresh variables not supported",
39+
"interpolation queries with mixed lemmas not supported");
40+
3441
BitwuzlaInterpolatingProver(
3542
BitwuzlaFormulaManager pManager,
3643
BitwuzlaFormulaCreator pCreator,
@@ -55,11 +62,25 @@ private static Options enableInterpolation(Options pSolverOptions) {
5562
@Override
5663
public BooleanFormula getInterpolant(Collection<Integer> formulasOfA)
5764
throws SolverException, InterruptedException {
58-
return creator.encapsulateBoolean(
59-
formulasOfA.isEmpty()
60-
? creator.getEnv().mk_true()
61-
: env.get_interpolant(
62-
new Vector_Term(FluentIterable.from(formulasOfA).transform(stack.peek()::get))));
65+
Term interpolant;
66+
if (formulasOfA.isEmpty()) {
67+
interpolant = creator.getEnv().mk_true();
68+
} else {
69+
Vector_Term itpVector =
70+
new Vector_Term(FluentIterable.from(formulasOfA).transform(stack.peek()::get));
71+
try {
72+
interpolant = env.get_interpolant(itpVector);
73+
74+
} catch (IllegalArgumentException e) {
75+
// TODO Starting with Bitwuzla 0.9.2 we could catch the Unsupported exception in C++
76+
if (ACCEPTED_INTERPOLATION_ERROR_MESSAGES.contains(e.getMessage())) {
77+
throw new SolverException(e.getMessage());
78+
} else {
79+
throw e;
80+
}
81+
}
82+
}
83+
return creator.encapsulateBoolean(interpolant);
6384
}
6485

6586
@Override
@@ -72,7 +93,16 @@ public List<BooleanFormula> getSeqInterpolants(
7293
FluentIterable.from(partitionedFormulas)
7394
.transform(
7495
p -> new Vector_Term(FluentIterable.from(p).transform(stack.peek()::get))));
75-
Vector_Term itps = env.get_interpolants(partitions);
96+
Vector_Term itps;
97+
try {
98+
itps = env.get_interpolants(partitions);
99+
} catch (IllegalArgumentException e) {
100+
if (ACCEPTED_INTERPOLATION_ERROR_MESSAGES.contains(e.getMessage())) {
101+
throw new SolverException(e.getMessage());
102+
} else {
103+
throw e;
104+
}
105+
}
76106
checkState(
77107
creator.getEnv().mk_false().equals(Iterables.getLast(itps)),
78108
"the last interpolant should be false");

src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ protected T addConstraintImpl(BooleanFormula pF) throws InterruptedException {
117117

118118
@SuppressWarnings("resource")
119119
@Override
120-
protected Model getModelImpl() {
120+
protected Model getModelImpl() throws SolverException {
121121
return registerEvaluator(
122122
new OpenSmtModel(
123123
this, creator, Collections2.transform(getAssertedFormulas(), creator::extractInfo)));

src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.sosy_lab.java_smt.api.FormulaManager;
2020
import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment;
2121
import org.sosy_lab.java_smt.api.SolverContext.ProverOptions;
22+
import org.sosy_lab.java_smt.api.SolverException;
2223
import org.sosy_lab.java_smt.solvers.opensmt.OpenSmtSolverContext.OpenSMTOptions;
2324
import org.sosy_lab.java_smt.solvers.opensmt.api.PTRef;
2425
import org.sosy_lab.java_smt.solvers.opensmt.api.VectorInt;
@@ -68,15 +69,29 @@ protected void popImpl() {
6869
super.popImpl();
6970
}
7071

72+
/**
73+
* Check if OpenSMT supports interpolation for the current logic, and throw an {@link
74+
* SolverException} otherwise.
75+
*/
76+
private void checkLogicSupportInterpolation() throws SolverException {
77+
if (!creator.getLogic().doesLogicSupportInterpolation()) {
78+
throw new SolverException(
79+
"OpenSMT does not support interpolation for the specified logic %s."
80+
.formatted(creator.getLogic()));
81+
}
82+
}
83+
7184
@Override
72-
public BooleanFormula getInterpolant(Collection<Integer> formulasOfA) {
85+
public BooleanFormula getInterpolant(Collection<Integer> formulasOfA) throws SolverException {
86+
checkLogicSupportInterpolation();
7387
return creator.encapsulateBoolean(
7488
osmtSolver.getInterpolationContext().getSingleInterpolant(new VectorInt(formulasOfA)));
7589
}
7690

7791
@Override
7892
public List<BooleanFormula> getSeqInterpolants(
79-
List<? extends Collection<Integer>> partitionedFormulas) {
93+
List<? extends Collection<Integer>> partitionedFormulas) throws SolverException {
94+
checkLogicSupportInterpolation();
8095
VectorVectorInt partitions = new VectorVectorInt();
8196
for (int i = 1; i < partitionedFormulas.size(); i++) {
8297
VectorInt prefix = new VectorInt();

src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtModel.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.LinkedHashMap;
1919
import java.util.List;
2020
import java.util.Map;
21+
import org.sosy_lab.java_smt.api.SolverException;
2122
import org.sosy_lab.java_smt.basicimpl.AbstractModel;
2223
import org.sosy_lab.java_smt.solvers.opensmt.api.Logic;
2324
import org.sosy_lab.java_smt.solvers.opensmt.api.Model;
@@ -38,7 +39,8 @@ class OpenSmtModel extends AbstractModel<PTRef, SRef, Logic> {
3839
OpenSmtModel(
3940
OpenSmtAbstractProver<?> pProver,
4041
OpenSmtFormulaCreator pCreator,
41-
Collection<PTRef> pAssertedTerms) {
42+
Collection<PTRef> pAssertedTerms)
43+
throws SolverException {
4244
super(pProver, pCreator);
4345

4446
osmtLogic = pCreator.getEnv();
@@ -51,7 +53,7 @@ class OpenSmtModel extends AbstractModel<PTRef, SRef, Logic> {
5153
}
5254

5355
private ImmutableList<ValueAssignment> generateModel(
54-
OpenSmtFormulaCreator pCreator, Collection<PTRef> pAssertedTerms) {
56+
OpenSmtFormulaCreator pCreator, Collection<PTRef> pAssertedTerms) throws SolverException {
5557
Map<String, PTRef> userDeclarations = new LinkedHashMap<>();
5658
for (PTRef asserted : pAssertedTerms) {
5759
userDeclarations.putAll(creator.extractVariablesAndUFs(asserted, true));
@@ -69,8 +71,9 @@ private ImmutableList<ValueAssignment> generateModel(
6971
if (osmtLogic.isArraySort(sort)) {
7072
// INFO: Disable model generation if arrays are used
7173
// https://github.com/usi-verification-and-security/opensmt/issues/630
72-
throw new UnsupportedOperationException(
73-
"OpenSMT does not support model generation when arrays are used");
74+
throw new SolverException(
75+
"OpenSMT2 can not return satisfiable assignments for arrays. To avoid wrong"
76+
+ "interpretation, we disallow model export for queries including arrays.");
7477
}
7578

7679
if (numArgs == 0) {

src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.sri.yices.InterpolationContext;
2020
import com.sri.yices.Status;
2121
import com.sri.yices.Terms;
22+
import com.sri.yices.YicesException;
2223
import java.util.ArrayList;
2324
import java.util.Collection;
2425
import java.util.List;
@@ -33,6 +34,12 @@
3334

3435
class Yices2InterpolatingProver extends Yices2AbstractProver<Integer>
3536
implements InterpolatingProverEnvironment<Integer> {
37+
38+
private static final ImmutableSet<String> ACCEPTED_INTERPOLATION_ERROR_MESSAGES =
39+
ImmutableSet.of(
40+
"mcsat: unsupported theory\n",
41+
"mcsat: assumption variable has a type that mcsat cannot decide on\n");
42+
3643
Yices2InterpolatingProver(
3744
Yices2FormulaCreator creator,
3845
Set<ProverOptions> pOptions,
@@ -61,7 +68,7 @@ public BooleanFormula getInterpolant(Collection<Integer> formulasOfA)
6168
}
6269

6370
private int interpolate(Collection<Integer> setA, Collection<Integer> setB)
64-
throws InterruptedException {
71+
throws InterruptedException, SolverException {
6572
try (var ctxA = newContext("mcsat");
6673
var ctxB = newContext("mcsat")) {
6774

@@ -72,12 +79,21 @@ private int interpolate(Collection<Integer> setA, Collection<Integer> setB)
7279
// TODO How to abort this?
7380
// For now, let's just check before and after the call:
7481
shutdownNotifier.shutdownIfNecessary();
75-
var status = context.check(DEFAULT_PARAMS, false);
82+
Status status;
83+
try {
84+
status = context.check(DEFAULT_PARAMS, false);
85+
} catch (YicesException e) {
86+
if (ACCEPTED_INTERPOLATION_ERROR_MESSAGES.contains(e.getMessage())) {
87+
throw new SolverException(e.getMessage().stripTrailing());
88+
} else {
89+
throw e;
90+
}
91+
}
7692
shutdownNotifier.shutdownIfNecessary();
7793
if (status == Status.UNSAT) {
7894
return context.getInterpolant();
7995
} else {
80-
throw new IllegalArgumentException("Solver state must be unsat");
96+
throw new IllegalStateException("Solver state must be unsat");
8197
}
8298
}
8399
}

0 commit comments

Comments
 (0)