-
Notifications
You must be signed in to change notification settings - Fork 52
CVC5: Add parser support #474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0d463c8
323a1ef
5aee817
0804d33
7f3d727
57e4356
0586c30
6d974bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,9 +34,7 @@ | |
import java.lang.reflect.Array; | ||
import java.math.BigInteger; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
import org.sosy_lab.common.rationals.Rational; | ||
import org.sosy_lab.java_smt.api.ArrayFormula; | ||
|
@@ -72,13 +70,9 @@ public class CVC5FormulaCreator extends FormulaCreator<Term, Sort, TermManager, | |
/** CVC5 does not allow using some key-functions from SMTLIB2 as identifiers. */ | ||
private static final ImmutableSet<String> UNSUPPORTED_IDENTIFIERS = ImmutableSet.of("let"); | ||
|
||
// private static final Pattern FLOATING_POINT_PATTERN = Pattern.compile("^\\(fp #b(?<sign>\\d) | ||
// #b(?<exp>\\d+) #b(?<mant>\\d+)$"); | ||
/** We use a variable cache to keep track of variables/Ufs that have already been defined. */ | ||
private final Table<String, Sort, Term> variablesCache = HashBasedTable.create(); | ||
|
||
// <Name, Sort.toString, Term> because CVC5 returns distinct pointers for types, while the | ||
// String representation is equal (and they are equal) | ||
private final Table<String, String, Term> variablesCache = HashBasedTable.create(); | ||
private final Map<String, Term> functionsCache = new HashMap<>(); | ||
private final TermManager termManager; | ||
private final Solver solver; | ||
|
||
|
@@ -98,9 +92,13 @@ public Solver getSolver() { | |
return solver; | ||
} | ||
|
||
Table<String, Sort, Term> getDeclaredVariables() { | ||
return variablesCache; | ||
} | ||
|
||
@Override | ||
public Term makeVariable(Sort sort, String name) { | ||
Term existingVar = variablesCache.get(name, sort.toString()); | ||
Term existingVar = variablesCache.get(name, sort); | ||
if (existingVar != null) { | ||
return existingVar; | ||
} | ||
|
@@ -124,7 +122,7 @@ public Term makeVariable(Sort sort, String name) { | |
.getKey()); | ||
} | ||
Term newVar = termManager.mkConst(sort, name); | ||
variablesCache.put(name, sort.toString(), newVar); | ||
variablesCache.put(name, sort, newVar); | ||
return newVar; | ||
} | ||
|
||
|
@@ -426,21 +424,14 @@ public <R> R visit(FormulaVisitor<R> visitor, Formula formula, final Term f) { | |
getFormulaType(f), | ||
f.getKind())); | ||
|
||
} else if (f.getKind() == Kind.VARIABLE) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What changed that there are no more bound variables? We still support quantifiers, so there should be bound variables. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bound variables are substituted when the quantifier is matched here. I think this makes this code unreachable as there should be no way to create a bound variable by itself? Then again it probably wouldn't hurt to leave the code in. |
||
// BOUND vars are used for all vars that are bound to a quantifier in CVC5. | ||
// We resubstitute them back to the original free. | ||
// CVC5 doesn't give you the de-brujin index | ||
Term originalVar = accessVariablesCache(formula.toString(), sort); | ||
return visitor.visitBoundVariable(encapsulate(originalVar), 0); | ||
|
||
} else if (f.getKind() == Kind.FORALL || f.getKind() == Kind.EXISTS) { | ||
// QUANTIFIER: replace bound variable with free variable for visitation | ||
assert f.getNumChildren() == 2; | ||
Term body = f.getChild(1); | ||
List<Formula> freeVars = new ArrayList<>(); | ||
for (Term boundVar : f.getChild(0)) { // unpack grand-children of f. | ||
String name = getName(boundVar); | ||
Term freeVar = Preconditions.checkNotNull(accessVariablesCache(name, boundVar.getSort())); | ||
Term freeVar = makeVariable(boundVar.getSort(), name); | ||
body = body.substitute(boundVar, freeVar); | ||
freeVars.add(encapsulate(freeVar)); | ||
} | ||
|
@@ -520,7 +511,7 @@ public <R> R visit(FormulaVisitor<R> visitor, Formula formula, final Term f) { | |
* back to a common one. | ||
*/ | ||
private Term normalize(Term operator) { | ||
Term function = functionsCache.get(getName(operator)); | ||
Term function = variablesCache.get(getName(operator), operator.getSort()); | ||
if (function != null) { | ||
checkState( | ||
function.getId() == operator.getId(), | ||
|
@@ -766,20 +757,19 @@ private void checkSymbol(String symbol) { | |
public Term declareUFImpl(String pName, Sort pReturnType, List<Sort> pArgTypes) { | ||
checkSymbol(pName); | ||
|
||
Term exp = functionsCache.get(pName); | ||
// Ufs in CVC5 can't have 0 arity. We just use a variable as a workaround. | ||
Sort termSort = | ||
pArgTypes.isEmpty() | ||
? pReturnType | ||
: environment.mkFunctionSort(pArgTypes.toArray(new Sort[0]), pReturnType); | ||
Term exp = variablesCache.get(pName, termSort); | ||
|
||
if (exp == null) { | ||
// Ufs in CVC5 can't have 0 arity. We just use a variable as a workaround. | ||
Sort sort = | ||
pArgTypes.isEmpty() | ||
? pReturnType | ||
: termManager.mkFunctionSort(pArgTypes.toArray(new Sort[0]), pReturnType); | ||
exp = termManager.mkConst(sort, pName); | ||
functionsCache.put(pName, exp); | ||
|
||
exp = termManager.mkConst(termSort, pName); | ||
variablesCache.put(pName, exp.getSort(), exp); | ||
} else { | ||
Preconditions.checkArgument( | ||
exp.getSort().equals(exp.getSort()), | ||
pReturnType.equals(exp.getSort().getFunctionCodomainSort()), | ||
"Symbol %s already in use for different return type %s", | ||
exp, | ||
exp.getSort()); | ||
|
@@ -801,6 +791,11 @@ public Term declareUFImpl(String pName, Sort pReturnType, List<Sort> pArgTypes) | |
return exp; | ||
} | ||
|
||
@Override | ||
public Object convertValue(Term pValue) { | ||
return convertValue(pValue, pValue); | ||
} | ||
|
||
@Override | ||
public Object convertValue(Term expForType, Term value) { | ||
final Sort type = expForType.getSort(); | ||
|
@@ -857,28 +852,4 @@ private FloatingPointNumber convertFloatingPoint(Term value) throws CVC5ApiExcep | |
final var bits = bvValue.getBitVectorValue(); | ||
return FloatingPointNumber.of(bits, expWidth, mantWidth); | ||
} | ||
|
||
private Term accessVariablesCache(String name, Sort sort) { | ||
Term existingVar = variablesCache.get(name, sort.toString()); | ||
if (existingVar == null) { | ||
throw new IllegalArgumentException( | ||
"Symbol " | ||
+ name | ||
+ " requested with type " | ||
+ sort | ||
+ ", but " | ||
+ "already " | ||
+ "used " | ||
+ "with " | ||
+ "type" | ||
+ variablesCache | ||
.rowMap() | ||
.get(name) | ||
.entrySet() | ||
.toArray((java.util.Map.Entry[]) Array.newInstance(java.util.Map.Entry.class, 0))[ | ||
0] | ||
.getKey()); | ||
} | ||
return existingVar; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as i remember i chose the string representation as it was possible to get equal sorts that were not equal, thus it was not possible to find already existing variables. Have you checked for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can look into that, but so far I've not had any issues with it. Do you still remember if it used to fail for any specific sorts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went thought the git log and it seems like we switched to using the String representation here. I wasn't able to reproduce the problem with Bitvector sorts even when using the old version of the commit.
Could it be that this was linked to the parallel issues that CVC5 has? Sorts are "per thread" in CVC5 and this may have caused issues with finding existing variables in the cache.