Skip to content

Commit 195258d

Browse files
committed
QuantifiedFormulaManager: disallow an empty variable list for quantification.
Most solvers already enforced a non-empty list of variables for quantification. This step unifies the precondition check and improves the error message.
1 parent 5a87fdc commit 195258d

File tree

4 files changed

+43
-32
lines changed

4 files changed

+43
-32
lines changed

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

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

99
package org.sosy_lab.java_smt.basicimpl;
1010

11+
import static com.google.common.base.Preconditions.checkArgument;
12+
1113
import com.google.common.collect.Lists;
1214
import java.util.List;
1315
import org.sosy_lab.java_smt.api.BooleanFormula;
@@ -41,6 +43,8 @@ protected abstract TFormulaInfo eliminateQuantifiers(TFormulaInfo pExtractInfo)
4143
@Override
4244
public BooleanFormula mkQuantifier(
4345
Quantifier q, List<? extends Formula> pVariables, BooleanFormula pBody) {
46+
checkArgument(
47+
!pVariables.isEmpty(), "Missing variables for quantifier '%s' and body '%s'.", q, pBody);
4448
return wrap(
4549
mkQuantifier(q, Lists.transform(pVariables, this::extractInfo), extractInfo(pBody)));
4650
}

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

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

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

11+
import static com.google.common.base.Preconditions.checkArgument;
12+
1113
import edu.stanford.CVC4.Expr;
1214
import edu.stanford.CVC4.ExprManager;
1315
import edu.stanford.CVC4.Kind;
@@ -72,23 +74,22 @@ protected Expr eliminateQuantifiers(Expr pExtractInfo)
7274
*/
7375
@Override
7476
public Expr mkQuantifier(Quantifier pQ, List<Expr> pVars, Expr pBody) {
75-
if (pVars.isEmpty()) {
76-
throw new IllegalArgumentException("Empty variable list for quantifier.");
77-
} else {
78-
// CVC4 uses its own lists for quantifier that may only have bound vars
79-
vectorExpr vec = new vectorExpr();
80-
Expr substBody = pBody;
81-
// every free needs a bound copy. As the internal Id is different for every variable, even
82-
// with the same name, this is fine.
83-
for (Expr var : pVars) {
84-
Expr boundCopy = ((CVC4FormulaCreator) formulaCreator).makeBoundCopy(var);
85-
vec.add(boundCopy);
86-
substBody = substBody.substitute(var, boundCopy);
87-
}
88-
Expr quantifiedVars = exprManager.mkExpr(Kind.BOUND_VAR_LIST, vec);
77+
checkArgument(
78+
!pVars.isEmpty(), "Missing variables for quantifier '%s' and body '%s'.", pQ, pBody);
8979

90-
Kind quant = pQ == Quantifier.EXISTS ? Kind.EXISTS : Kind.FORALL;
91-
return exprManager.mkExpr(quant, quantifiedVars, substBody);
80+
// CVC4 uses its own lists for quantifier that may only have bound vars
81+
vectorExpr vec = new vectorExpr();
82+
Expr substBody = pBody;
83+
// every free needs a bound copy. As the internal Id is different for every variable, even
84+
// with the same name, this is fine.
85+
for (Expr var : pVars) {
86+
Expr boundCopy = ((CVC4FormulaCreator) formulaCreator).makeBoundCopy(var);
87+
vec.add(boundCopy);
88+
substBody = substBody.substitute(var, boundCopy);
9289
}
90+
Expr quantifiedVars = exprManager.mkExpr(Kind.BOUND_VAR_LIST, vec);
91+
92+
Kind quant = pQ == Quantifier.EXISTS ? Kind.EXISTS : Kind.FORALL;
93+
return exprManager.mkExpr(quant, quantifiedVars, substBody);
9394
}
9495
}

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

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

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

11+
import static com.google.common.base.Preconditions.checkArgument;
12+
1113
import io.github.cvc5.Kind;
1214
import io.github.cvc5.Solver;
1315
import io.github.cvc5.Sort;
@@ -63,22 +65,21 @@ protected Term eliminateQuantifiers(Term input) throws SolverException, Interrup
6365
*/
6466
@Override
6567
public Term mkQuantifier(Quantifier pQ, List<Term> pVars, Term pBody) {
66-
if (pVars.isEmpty()) {
67-
throw new IllegalArgumentException("Empty variable list for quantifier.");
68-
} else {
69-
List<Term> boundVars = new ArrayList<>();
70-
Term substBody = pBody;
71-
// every free needs a bound copy. As the internal Id is different for every variable, even
72-
// with the same name, this is fine.
73-
for (Term var : pVars) {
74-
Term boundCopy = ((CVC5FormulaCreator) formulaCreator).makeBoundCopy(var);
75-
boundVars.add(boundCopy);
76-
substBody = substBody.substitute(var, boundCopy);
77-
}
68+
checkArgument(
69+
!pVars.isEmpty(), "Missing variables for quantifier '%s' and body '%s'.", pQ, pBody);
7870

79-
Kind quant = pQ == Quantifier.EXISTS ? Kind.EXISTS : Kind.FORALL;
80-
Term boundVarsList = termManager.mkTerm(Kind.VARIABLE_LIST, boundVars.toArray(new Term[0]));
81-
return termManager.mkTerm(quant, boundVarsList, substBody);
71+
List<Term> boundVars = new ArrayList<>();
72+
Term substBody = pBody;
73+
// every free needs a bound copy. As the internal Id is different for every variable, even
74+
// with the same name, this is fine.
75+
for (Term var : pVars) {
76+
Term boundCopy = ((CVC5FormulaCreator) formulaCreator).makeBoundCopy(var);
77+
boundVars.add(boundCopy);
78+
substBody = substBody.substitute(var, boundCopy);
8279
}
80+
81+
Kind quant = pQ == Quantifier.EXISTS ? Kind.EXISTS : Kind.FORALL;
82+
Term boundVarsList = termManager.mkTerm(Kind.VARIABLE_LIST, boundVars.toArray(new Term[0]));
83+
return termManager.mkTerm(quant, boundVarsList, substBody);
8384
}
8485
}

src/org/sosy_lab/java_smt/solvers/z3/Z3QuantifiedFormulaManager.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ class Z3QuantifiedFormulaManager extends AbstractQuantifiedFormulaManager<Long,
2929

3030
@Override
3131
public Long mkQuantifier(Quantifier q, List<Long> pVariables, Long pBody) {
32-
checkArgument(!pVariables.isEmpty(), "List of quantified variables can not be empty");
32+
checkArgument(
33+
!pVariables.isEmpty(),
34+
"Missing variables for quantifier '%s' and body '%s'.",
35+
q,
36+
Native.astToString(z3context, pBody));
37+
3338
return Native.mkQuantifierConst(
3439
z3context,
3540
q == Quantifier.FORALL,

0 commit comments

Comments
 (0)