Skip to content

Commit 0295692

Browse files
CVC5: Build interpolant sequence in reverse for better performance
1 parent e7857c9 commit 0295692

1 file changed

Lines changed: 51 additions & 18 deletions

File tree

src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import static org.sosy_lab.common.collect.Collections3.transformedImmutableSetCopy;
1313

1414
import com.google.common.collect.FluentIterable;
15+
import com.google.common.collect.ImmutableList;
1516
import com.google.common.collect.ImmutableMap;
1617
import com.google.common.collect.ImmutableSet;
1718
import com.google.common.collect.Sets;
@@ -20,7 +21,6 @@
2021
import io.github.cvc5.Solver;
2122
import io.github.cvc5.Term;
2223
import io.github.cvc5.TermManager;
23-
import java.util.ArrayList;
2424
import java.util.Collection;
2525
import java.util.List;
2626
import java.util.Set;
@@ -86,24 +86,57 @@ public BooleanFormula getInterpolant(Collection<String> pFormulasOfA)
8686
@Override
8787
public List<BooleanFormula> getSeqInterpolants(List<? extends Collection<String>> partitions)
8888
throws SolverException, InterruptedException {
89-
final int n = partitions.size();
90-
final List<BooleanFormula> itps = new ArrayList<>();
91-
Term previousItp = termManager.mkTrue();
92-
for (int i = 1; i < n; i++) {
93-
Collection<Term> formulasA =
94-
FluentIterable.from(partitions.get(i - 1))
95-
.transform(assertedTerms.peek()::get)
96-
.append(new Term[] {previousItp}) // class Term is Iterable<Term>, be careful here
97-
.toSet();
98-
Collection<Term> formulasB =
99-
FluentIterable.concat(partitions.subList(i, n))
100-
.transform(assertedTerms.peek()::get)
101-
.toSet();
102-
Term itp = getCVC5Interpolation(formulasA, formulasB);
103-
itps.add(creator.encapsulateBoolean(itp));
104-
previousItp = itp;
89+
List<Term> groups =
90+
FluentIterable.from(partitions)
91+
.transform(
92+
partition ->
93+
bmgr.andImpl(
94+
FluentIterable.from(partition)
95+
.transform(assertedTerms.peek()::get)
96+
.toSet()))
97+
.toList();
98+
99+
// Uses a separate Solver instance to leave the original solver-context unmodified
100+
Solver itpSolver = getNewSolver();
101+
102+
// We build the interpolant sequence in reverse:
103+
// A & B & C -> (D -> false)
104+
// (C1) A & B -> (C -> K)
105+
// (B1) A -> (B -> J)
106+
// (A1) A -> I
107+
// (A2) I & B -> J
108+
// (B2) J & C -> K
109+
// (C2) K & D -> false
110+
//
111+
// By collecting the formulas, we get the sequence:
112+
// (A1) A -> I
113+
// (A2) I & B -> J
114+
// (B2) J & C -> K
115+
// (C2) K & D -> false
116+
//
117+
// Building the interpolants in reverse works better with the CVC5 API as it allows us to keep
118+
// the "A"s on the solver stack
119+
try {
120+
for (int i = 0; i < groups.size() - 1; i++) {
121+
itpSolver.push();
122+
itpSolver.assertFormula(groups.get(i));
123+
}
124+
125+
ImmutableList.Builder<BooleanFormula> builder = ImmutableList.builder();
126+
127+
Term lastItp = termManager.mkFalse();
128+
for (int i = groups.size() - 1; i > 0; i--) {
129+
lastItp =
130+
itpSolver.simplify(itpSolver.getInterpolant(bmgr.implication(groups.get(i), lastItp)));
131+
builder.add(creator.encapsulateBoolean(lastItp));
132+
133+
itpSolver.pop();
134+
}
135+
return builder.build().reverse();
136+
137+
} finally {
138+
itpSolver.deletePointer();
105139
}
106-
return itps;
107140
}
108141

109142
@Override

0 commit comments

Comments
 (0)