Skip to content

Commit fcf5910

Browse files
Add generic equality and distinct to the API
1 parent 91f7618 commit fcf5910

16 files changed

+372
-0
lines changed

src/org/sosy_lab/java_smt/api/FormulaManager.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package org.sosy_lab.java_smt.api;
1010

11+
import com.google.common.collect.ImmutableList;
1112
import com.google.common.collect.ImmutableMap;
1213
import com.google.errorprone.annotations.CanIgnoreReturnValue;
1314
import java.util.List;
@@ -131,6 +132,18 @@ <T extends Formula> T makeApplication(
131132
*/
132133
<T extends Formula> T makeApplication(FunctionDeclaration<T> declaration, Formula... args);
133134

135+
default BooleanFormula equal(Formula... pArgs) {
136+
return equal(ImmutableList.copyOf(pArgs));
137+
}
138+
139+
BooleanFormula equal(List<Formula> pArgs);
140+
141+
default BooleanFormula distinct(Formula... pArgs) {
142+
return distinct(ImmutableList.copyOf(pArgs));
143+
}
144+
145+
BooleanFormula distinct(List<Formula> pArgs);
146+
134147
/** Returns the type of the given Formula. */
135148
<T extends Formula> FormulaType<T> getFormulaType(T formula);
136149

src/org/sosy_lab/java_smt/basicimpl/AbstractFormulaManager.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.common.collect.ImmutableMap;
2020
import com.google.common.collect.ImmutableSet;
2121
import com.google.common.collect.Iterables;
22+
import com.google.common.collect.Lists;
2223
import java.io.IOException;
2324
import java.util.List;
2425
import java.util.Map;
@@ -264,6 +265,58 @@ public EnumerationFormulaManager getEnumerationFormulaManager() {
264265
return enumManager;
265266
}
266267

268+
/** Override if the solver API only supports binary equality. */
269+
protected TFormulaInfo equalImpl(TFormulaInfo pArg1, TFormulaInfo pArgs) {
270+
return equalImpl(ImmutableList.of(pArg1, pArgs));
271+
}
272+
273+
/** Override if the solver API supports equality with many arguments. */
274+
protected TFormulaInfo equalImpl(List<TFormulaInfo> pArgs) {
275+
ImmutableList.Builder<TFormulaInfo> builder = ImmutableList.builder();
276+
for (int i = 1; i < pArgs.size(); i++) {
277+
builder.add(equalImpl(pArgs.get(i - 1), pArgs.get(i)));
278+
}
279+
return booleanManager.andImpl(builder.build());
280+
}
281+
282+
@Override
283+
public BooleanFormula equal(List<Formula> pArgs) {
284+
Preconditions.checkArgument(
285+
pArgs.size() > 1,
286+
"Called `equal` with %s arguments, but at least two are needed",
287+
pArgs.size());
288+
Preconditions.checkArgument(
289+
ImmutableSet.copyOf(Lists.transform(pArgs, formulaCreator::getFormulaType)).size() == 1,
290+
"All arguments to `equal` must have the same type, but found %s different types",
291+
Lists.transform(pArgs, formulaCreator::getFormulaType).size());
292+
return formulaCreator.encapsulateBoolean(
293+
equalImpl(Lists.transform(pArgs, formulaCreator::extractInfo)));
294+
}
295+
296+
/** Override if the solver API supports <code>distinct</code>. */
297+
protected TFormulaInfo distinctImpl(List<TFormulaInfo> pArgs) {
298+
ImmutableList.Builder<TFormulaInfo> builder = ImmutableList.builder();
299+
for (int i = 0; i < pArgs.size(); i++) {
300+
for (int j = i + 1; j < pArgs.size(); j++) {
301+
builder.add(booleanManager.not(equalImpl(pArgs.get(i), pArgs.get(j))));
302+
}
303+
}
304+
return booleanManager.andImpl(builder.build());
305+
}
306+
307+
@Override
308+
public BooleanFormula distinct(List<Formula> pArgs) {
309+
Preconditions.checkArgument(
310+
pArgs.size() > 1,
311+
"Called `distinct` with %s arguments, but at least two are needed",
312+
pArgs.size());
313+
Preconditions.checkArgument(
314+
ImmutableSet.copyOf(Lists.transform(pArgs, formulaCreator::getFormulaType)).size() == 1,
315+
"All arguments to `distinct` must have the same type, but found %s different types",
316+
Lists.transform(pArgs, formulaCreator::getFormulaType).size());
317+
return formulaCreator.encapsulateBoolean(distinctImpl(formulaCreator.extractInfo(pArgs)));
318+
}
319+
267320
protected abstract TFormulaInfo parseImpl(String formulaStr) throws IllegalArgumentException;
268321

269322
/**

src/org/sosy_lab/java_smt/delegate/debugging/DebuggingFormulaManager.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,28 @@ public <T extends Formula> T makeApplication(
148148
return result;
149149
}
150150

151+
@Override
152+
public BooleanFormula equal(List<Formula> pArgs) {
153+
debugging.assertThreadLocal();
154+
for (Formula f : pArgs) {
155+
debugging.assertFormulaInContext(f);
156+
}
157+
BooleanFormula result = delegate.equal(pArgs);
158+
debugging.addFormulaTerm(result);
159+
return result;
160+
}
161+
162+
@Override
163+
public BooleanFormula distinct(List<Formula> pArgs) {
164+
debugging.assertThreadLocal();
165+
for (Formula f : pArgs) {
166+
debugging.assertFormulaInContext(f);
167+
}
168+
BooleanFormula result = delegate.distinct(pArgs);
169+
debugging.addFormulaTerm(result);
170+
return result;
171+
}
172+
151173
@Override
152174
public <T extends Formula> FormulaType<T> getFormulaType(T formula) {
153175
debugging.assertThreadLocal();

src/org/sosy_lab/java_smt/delegate/statistics/StatisticsFormulaManager.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,18 @@ public <T extends Formula> T makeApplication(
121121
return delegate.makeApplication(pDeclaration, pArgs);
122122
}
123123

124+
@Override
125+
public BooleanFormula equal(List<Formula> pArgs) {
126+
stats.booleanOperations.getAndIncrement(); // TODO Check the formula type?
127+
return delegate.equal(pArgs);
128+
}
129+
130+
@Override
131+
public BooleanFormula distinct(List<Formula> pArgs) {
132+
stats.booleanOperations.getAndIncrement(); // TODO Check the formula type?
133+
throw new UnsupportedOperationException();
134+
}
135+
124136
@Override
125137
public <T extends Formula> FormulaType<T> getFormulaType(T pFormula) {
126138
return delegate.getFormulaType(pFormula);

src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedFormulaManager.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ public <T extends Formula> T makeApplication(
151151
}
152152
}
153153

154+
@Override
155+
public BooleanFormula equal(List<Formula> pArgs) {
156+
synchronized (sync) {
157+
return delegate.equal(pArgs);
158+
}
159+
}
160+
161+
@Override
162+
public BooleanFormula distinct(List<Formula> pArgs) {
163+
synchronized (sync) {
164+
return delegate.distinct(pArgs);
165+
}
166+
}
167+
154168
@Override
155169
public <T extends Formula> FormulaType<T> getFormulaType(T pFormula) {
156170
synchronized (sync) {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
import org.sosy_lab.java_smt.basicimpl.AbstractFormulaManager;
1919
import org.sosy_lab.java_smt.basicimpl.Tokenizer;
2020
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Bitwuzla;
21+
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Kind;
2122
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Map_TermTerm;
2223
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Options;
2324
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Parser;
2425
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Sort;
2526
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Term;
27+
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Vector_Int;
2628
import org.sosy_lab.java_smt.solvers.bitwuzla.api.Vector_Term;
2729

2830
public final class BitwuzlaFormulaManager
@@ -57,6 +59,18 @@ public final class BitwuzlaFormulaManager
5759
bitwuzlaOption = pBitwuzlaOptions;
5860
}
5961

62+
@Override
63+
public Term equalImpl(List<Term> pArgs) {
64+
return creator.getTermManager().mk_term(Kind.EQUAL, new Vector_Term(pArgs), new Vector_Int());
65+
}
66+
67+
@Override
68+
public Term distinctImpl(List<Term> pArgs) {
69+
return creator
70+
.getTermManager()
71+
.mk_term(Kind.DISTINCT, new Vector_Term(pArgs), new Vector_Int());
72+
}
73+
6074
@Override
6175
public Term parseImpl(String formulaStr) throws IllegalArgumentException {
6276
// Split the input string into a list of SMT-LIB2 commands

src/org/sosy_lab/java_smt/solvers/boolector/BoolectorFormulaManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ final class BoolectorFormulaManager extends AbstractFormulaManager<Long, Long, L
3434
null);
3535
}
3636

37+
@Override
38+
protected Long equalImpl(Long pArg1, Long pArgs) {
39+
return BtorJNI.boolector_eq(getEnvironment(), pArg1, pArgs);
40+
}
41+
3742
@Override
3843
public Long parseImpl(String pS) throws IllegalArgumentException {
3944
throw new UnsupportedOperationException("Boolector can not parse single formulas.");

src/org/sosy_lab/java_smt/solvers/cvc4/CVC4FormulaManager.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
import de.uni_freiburg.informatik.ultimate.logic.PrintTerm;
1414
import edu.stanford.CVC4.Expr;
1515
import edu.stanford.CVC4.ExprManager;
16+
import edu.stanford.CVC4.Kind;
1617
import edu.stanford.CVC4.Type;
18+
import edu.stanford.CVC4.vectorExpr;
1719
import java.io.IOException;
1820
import java.io.OutputStream;
1921
import java.util.LinkedHashMap;
22+
import java.util.List;
2023
import java.util.Map;
2124
import org.sosy_lab.java_smt.api.Formula;
2225
import org.sosy_lab.java_smt.api.FormulaType;
@@ -63,6 +66,20 @@ static Expr getCVC4Expr(Formula pT) {
6366
"Cannot get the formula info of type " + pT.getClass().getSimpleName() + " in the Solver!");
6467
}
6568

69+
@Override
70+
public Expr equalImpl(Expr pArg1, Expr pArgs) {
71+
return getEnvironment().mkExpr(Kind.EQUAL, pArg1, pArgs);
72+
}
73+
74+
@Override
75+
public Expr distinctImpl(List<Expr> pArgs) {
76+
vectorExpr vec = new vectorExpr();
77+
for (Expr e : pArgs) {
78+
vec.add(e);
79+
}
80+
return getEnvironment().mkExpr(Kind.DISTINCT, vec);
81+
}
82+
6683
@Override
6784
public Expr parseImpl(String formulaStr) throws IllegalArgumentException {
6885
throw new UnsupportedOperationException();

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import io.github.cvc5.Term;
1818
import io.github.cvc5.TermManager;
1919
import java.util.LinkedHashMap;
20+
import java.util.List;
2021
import java.util.Map;
2122
import org.sosy_lab.java_smt.api.Formula;
2223
import org.sosy_lab.java_smt.api.FormulaType;
@@ -64,6 +65,16 @@ static Term getCVC5Term(Formula pT) {
6465
"Cannot get the formula info of type " + pT.getClass().getSimpleName() + " in the Solver!");
6566
}
6667

68+
@Override
69+
public Term equalImpl(List<Term> pArgs) {
70+
return getEnvironment().mkTerm(Kind.EQUAL, pArgs.toArray(new Term[0]));
71+
}
72+
73+
@Override
74+
public Term distinctImpl(List<Term> pArgs) {
75+
return getEnvironment().mkTerm(Kind.DISTINCT, pArgs.toArray(new Term[0]));
76+
}
77+
6778
@Override
6879
public Term parseImpl(String formulaStr) throws IllegalArgumentException {
6980
throw new UnsupportedOperationException();

src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5FormulaManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_apply_substitution;
1212
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_from_smtlib2;
1313
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_copy_from;
14+
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_eq;
1415
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_simplify;
1516
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_to_smtlib2;
1617
import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_to_smtlib2_ext;
@@ -68,6 +69,11 @@ static long[] getMsatTerm(Collection<? extends Formula> pFormulas) {
6869
return Longs.toArray(Collections2.transform(pFormulas, Mathsat5FormulaManager::getMsatTerm));
6970
}
7071

72+
@Override
73+
protected Long equalImpl(Long pArg1, Long pArgs) {
74+
return msat_make_eq(getEnvironment(), pArg1, pArgs);
75+
}
76+
7177
@Override
7278
public Long parseImpl(String pS) throws IllegalArgumentException {
7379
return msat_from_smtlib2(getEnvironment(), pS);

0 commit comments

Comments
 (0)