private static String getQuantifiedVariables(Set<Variable> variables) { StringBuilder sb = new StringBuilder(); for (Variable variable : variables) { sb.append("("); // TODO(AndreiS): make sure variable names are SMTLib compliant sb.append(variable.name()); sb.append(" "); String sortName; sortName = getSortName(variable); sb.append(sortName); sb.append(")\n"); } return sb.toString(); }
@Override public void visit(Rule rule) { rule.leftHandSide().accept(this); rule.rightHandSide().accept(this); rule.lookups().accept(this); for (Term term : rule.requires()) { term.accept(this); } for (Term term : rule.ensures()) { term.accept(this); } for (Variable variable : rule.freshVariables()) { variable.accept(this); } }
private static String getSortAndFunctionDeclarations( Definition definition, Set<Variable> variables) { Set<Sort> sorts = new HashSet<>(); List<Production> functions = new ArrayList<>(); for (Production production : definition.context().productions) { String smtlib = production.getAttribute(Attribute.SMTLIB_KEY); if (smtlib != null && !SMTLIB_BUILTIN_FUNCTIONS.contains(smtlib) && !smtlib.startsWith("(")) { functions.add(production); sorts.add(Sort.of(production.getSort())); for (int i = 0; i < production.getArity(); ++i) { sorts.add(Sort.of(production.getChildSort(i))); } } } for (Variable variable : variables) { sorts.add(variable.sort()); } if (!Sets.intersection(sorts, RESERVED_Z3_SORTS).isEmpty()) { throw new UnsupportedOperationException("do not use sorts " + RESERVED_Z3_SORTS); } StringBuilder sb = new StringBuilder(); for (Sort sort : Sets.difference(sorts, SMTLIB_BUILTIN_SORTS)) { sb.append("(declare-sort "); sb.append(sort); sb.append(")\n"); } for (Production production : functions) { sb.append("(declare-fun "); sb.append(production.getAttribute(Attribute.SMTLIB_KEY)); sb.append(" ("); List<String> childrenSorts = new ArrayList<>(); for (int i = 0; i < production.getArity(); ++i) { childrenSorts.add(getSortName(production.getChildNode(i))); } Joiner.on(" ").appendTo(sb, childrenSorts); sb.append(") "); sb.append(getSortName(production)); sb.append(")\n"); } return sb.toString(); }
@Override public ASTNode transform(Variable variable) { variables.add(variable); return new SMTLibTerm(variable.name()); }
@Override public ASTNode transform(KItem kItem) { if (!(kItem.kLabel() instanceof KLabelConstant)) { throw new UnsupportedOperationException(); } KLabelConstant kLabel = (KLabelConstant) kItem.kLabel(); if (!(kItem.kList() instanceof KList)) { throw new UnsupportedOperationException(); } KList kList = (KList) kItem.kList(); if (kList.hasFrame()) { throw new UnsupportedOperationException(); } String label = kLabel.smtlib(); if (label == null) { throw new UnsupportedOperationException("missing SMTLib translation for " + kLabel); } if (label.startsWith("(")) { // smtlib expression instead of operator String expression = label; for (int i = 0; i < kList.getContents().size(); i++) { expression = expression.replaceAll( "\\#" + (i + 1) + "(?![0-9])", ((SMTLibTerm) kList.get(i).accept(this)).expression()); } return new SMTLibTerm(expression); } List<Term> arguments; switch (label) { case "exists": Variable variable = (Variable) kList.get(0); label = "exists ((" + variable.name() + " " + variable.sort() + ")) "; arguments = ImmutableList.of(kList.get(1)); break; case "extract": int beginIndex = ((IntToken) kList.get(1)).intValue(); int endIndex = ((IntToken) kList.get(2)).intValue() - 1; label = "(_ extract " + endIndex + " " + beginIndex + ")"; arguments = ImmutableList.of(kList.get(0)); break; default: arguments = kList.getContents(); } if (!arguments.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("("); sb.append(label); for (Term argument : arguments) { sb.append(" "); sb.append(((SMTLibTerm) argument.accept(this)).expression()); } sb.append(")"); return new SMTLibTerm(sb.toString()); } else { return new SMTLibTerm(label); } }