|
12 | 12 | import static org.sosy_lab.common.collect.Collections3.transformedImmutableSetCopy; |
13 | 13 |
|
14 | 14 | import com.google.common.collect.FluentIterable; |
| 15 | +import com.google.common.collect.ImmutableList; |
15 | 16 | import com.google.common.collect.ImmutableMap; |
16 | 17 | import com.google.common.collect.ImmutableSet; |
17 | 18 | import com.google.common.collect.Sets; |
|
20 | 21 | import io.github.cvc5.Solver; |
21 | 22 | import io.github.cvc5.Term; |
22 | 23 | import io.github.cvc5.TermManager; |
23 | | -import java.util.ArrayList; |
24 | 24 | import java.util.Collection; |
25 | 25 | import java.util.List; |
26 | 26 | import java.util.Set; |
@@ -86,24 +86,57 @@ public BooleanFormula getInterpolant(Collection<String> pFormulasOfA) |
86 | 86 | @Override |
87 | 87 | public List<BooleanFormula> getSeqInterpolants(List<? extends Collection<String>> partitions) |
88 | 88 | 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(); |
105 | 139 | } |
106 | | - return itps; |
107 | 140 | } |
108 | 141 |
|
109 | 142 | @Override |
|
0 commit comments