@Override public List<Expression<Boolean>> getInterpolants(List<Expression<Boolean>> exprsn) { Script s = new de.uni_freiburg.informatik.ultimate.smtinterpol.smtlib2.SMTInterpol(); SMTInterpolExpressionGenerator gen = new SMTInterpolExpressionGenerator(s); ArrayList<String> names = new ArrayList<>(); s.setOption(":produce-interpolants", true); s.setLogic(Logics.QF_LIA); int i = 1; for (Expression<Boolean> e : exprsn) { Term t = gen.generateAssertion(e); // System.out.println("T: " + t); String name = "phi_" + (i++); names.add(name); s.assertTerm(s.annotate(t, new Annotation(":named", name))); } if (s.checkSat() == Script.LBool.UNSAT) { Term[] terms = new Term[names.size()]; i = 0; for (String n : names) { terms[i++] = s.term(n); } Term[] interpolants; interpolants = s.getInterpolants(terms); // System.out.println("I: " + Arrays.toString(interpolants)); // parse result ArrayList<Expression<Boolean>> ret = new ArrayList<>(); for (Term t : interpolants) { // System.out.println(t); TermParser parser = new TermParser(t, gen.getVariables()); Expression<Boolean> interpolant; try { interpolant = parser.parse(); } catch (TermParserException ex) { logger.severe(ex.getMessage()); return null; } ret.add(interpolant); } return ret; } return null; }
private Term translate(final Expression exp) { if (exp instanceof ArrayAccessExpression) { final ArrayAccessExpression arrexp = (ArrayAccessExpression) exp; final Expression[] indices = arrexp.getIndices(); Term result = translate(arrexp.getArray()); for (int i = 0; i < indices.length; i++) { final Term indexiTerm = translate(indices[i]); result = mScript.term("select", result, indexiTerm); } return result; } else if (exp instanceof ArrayStoreExpression) { final ArrayStoreExpression arrexp = (ArrayStoreExpression) exp; final Expression[] indices = arrexp.getIndices(); assert indices.length > 0; // arrayBeforeIndex[i] represents the array, where all indices // before the i'th index have already been selected final Term[] arrayBeforeIndex = new Term[indices.length]; final Term[] indexTerm = new Term[indices.length]; arrayBeforeIndex[0] = translate(arrexp.getArray()); for (int i = 0; i < indices.length - 1; i++) { indexTerm[i] = translate(indices[i]); arrayBeforeIndex[i + 1] = mScript.term("select", arrayBeforeIndex[i], indexTerm[i]); } indexTerm[indices.length - 1] = translate(indices[indices.length - 1]); Term result = translate(arrexp.getValue()); for (int i = indices.length - 1; i >= 0; i--) { result = mScript.term("store", arrayBeforeIndex[i], indexTerm[i], result); } assert (result != null); assert resultContainsNoNull(result); return result; } else if (exp instanceof BinaryExpression) { final BinaryExpression binexp = (BinaryExpression) exp; final BinaryExpression.Operator op = binexp.getOperator(); // Sort sort = mSmt2Boogie.getSort(binexp.getLeft().getType()); if (op == BinaryExpression.Operator.COMPNEQ) { final String equalityFuncname = mOperationTranslator.opTranslation( BinaryExpression.Operator.COMPEQ, binexp.getLeft().getType(), binexp.getRight().getType()); final String negationFuncname = mOperationTranslator.opTranslation( UnaryExpression.Operator.LOGICNEG, PrimitiveType.TYPE_BOOL); final BigInteger[] indices = new BigInteger[0]; return SmtUtils.termWithLocalSimplification( mScript, negationFuncname, indices, SmtUtils.termWithLocalSimplification( mScript, equalityFuncname, indices, translate(binexp.getLeft()), translate(binexp.getRight()))); } else { final String funcname = mOperationTranslator.opTranslation( op, binexp.getLeft().getType(), binexp.getRight().getType()); final BigInteger[] indices = null; return SmtUtils.termWithLocalSimplification( mScript, funcname, indices, translate(binexp.getLeft()), translate(binexp.getRight())); } } else if (exp instanceof UnaryExpression) { final UnaryExpression unexp = (UnaryExpression) exp; final UnaryExpression.Operator op = unexp.getOperator(); if (op == UnaryExpression.Operator.OLD) { mOldContextScopeDepth++; final Term term = translate(unexp.getExpr()); mOldContextScopeDepth--; return term; } else { final String funcname = mOperationTranslator.opTranslation(op, unexp.getExpr().getType()); final BigInteger[] indices = null; return SmtUtils.termWithLocalSimplification( mScript, funcname, indices, translate(unexp.getExpr())); } } else if (exp instanceof RealLiteral) { final Term result = mOperationTranslator.realTranslation((RealLiteral) exp); assert result != null; return result; } else if (exp instanceof BitvecLiteral) { final Term result = mOperationTranslator.bitvecTranslation((BitvecLiteral) exp); assert result != null; return result; } else if (exp instanceof BitVectorAccessExpression) { final BigInteger[] indices = new BigInteger[2]; indices[0] = new BigInteger(Integer.toString(((BitVectorAccessExpression) exp).getEnd() - 1)); indices[1] = new BigInteger(Integer.toString(((BitVectorAccessExpression) exp).getStart())); final Term result = mScript.term( "extract", indices, null, translate(((BitVectorAccessExpression) exp).getBitvec())); assert result != null; return result; } else if (exp instanceof BooleanLiteral) { final Term result = mOperationTranslator.booleanTranslation((BooleanLiteral) exp); assert result != null; return result; } else if (exp instanceof FunctionApplication) { final FunctionApplication func = ((FunctionApplication) exp); final Term result; final Map<String, Expression[]> attributes = mBoogie2SmtSymbolTable.getAttributes(func.getIdentifier()); final String overapproximation = Boogie2SmtSymbolTable.checkForAttributeDefinedIdentifier(attributes, s_Overapproximation); if (mOverapproximateFunctions || overapproximation != null) { final Sort resultSort = mTypeSortTranslator.getSort(exp.getType(), exp); final TermVariable auxVar = mVariableManager.constructFreshTermVariable(func.getIdentifier(), resultSort); mAuxVars.add(auxVar); mOverapproximations.put(overapproximation, exp.getLocation()); result = auxVar; } else { final BigInteger[] indices = Boogie2SmtSymbolTable.checkForIndices(attributes); final IBoogieType[] argumentTypes = new IBoogieType[func.getArguments().length]; for (int i = 0; i < func.getArguments().length; i++) { argumentTypes[i] = func.getArguments()[i].getType(); } final Sort[] params = new Sort[func.getArguments().length]; for (int i = 0; i < func.getArguments().length; i++) { params[i] = mTypeSortTranslator.getSort(func.getArguments()[i].getType(), exp); } final Term[] parameters = new Term[func.getArguments().length]; for (int i = 0; i < func.getArguments().length; i++) { parameters[i] = translate(func.getArguments()[i]); } final String funcSymb = mOperationTranslator.funcApplication(func.getIdentifier(), argumentTypes); if (funcSymb == null) { throw new IllegalArgumentException("unknown function" + func.getIdentifier()); } // result = mScript.term(funcSymb, indices, null, parameters); // overkill, this should be called only for bitvector operations. result = SmtUtils.termWithLocalSimplification(mScript, funcSymb, indices, parameters); } return result; } else if (exp instanceof IdentifierExpression) { final IdentifierExpression var = (IdentifierExpression) exp; assert var.getDeclarationInformation() != null : " no declaration information"; final Term result = getSmtIdentifier( var.getIdentifier(), var.getDeclarationInformation(), isOldContext(), exp); assert result != null; return result; } else if (exp instanceof IntegerLiteral) { final Term result = mOperationTranslator.integerTranslation((IntegerLiteral) exp); assert result != null; return result; } else if (exp instanceof IfThenElseExpression) { final IfThenElseExpression ite = (IfThenElseExpression) exp; final Term cond = translate(ite.getCondition()); final Term thenPart = translate(ite.getThenPart()); final Term elsePart = translate(ite.getElsePart()); final Term result = Util.ite(mScript, cond, thenPart, elsePart); assert result != null; return result; } else if (exp instanceof QuantifierExpression) { // throw new // UnsupportedOperationException("QuantifierExpression not implemented yet"); final QuantifierExpression quant = (QuantifierExpression) exp; final String[] typeParams = quant.getTypeParams(); final VarList[] variables = quant.getParameters(); int numvars = typeParams.length; for (int i = 0; i < variables.length; i++) { numvars += variables[i].getIdentifiers().length; } final TermVariable[] vars = new TermVariable[numvars]; // TODO is this really unused code // HashMap<String,Term> newVars = new HashMap<String, Term>(); int offset = 0; // for (int j = 0; j < typeParams.length; j++) { // vars[offset] = mScript.createTermVariable("q" + // quoteId(typeParams[j]), intSort); // typeStack.push(vars[offset]); // offset++; // } mQuantifiedVariables.beginScope(); for (int i = 0; i < variables.length; i++) { final IBoogieType type = variables[i].getType().getBoogieType(); final Sort sort = mTypeSortTranslator.getSort(type, exp); for (int j = 0; j < variables[i].getIdentifiers().length; j++) { final String identifier = variables[i].getIdentifiers()[j]; final String smtVarName = "q" + Boogie2SMT.quoteId(variables[i].getIdentifiers()[j]); vars[offset] = mScript.variable(smtVarName, sort); mQuantifiedVariables.put(identifier, vars[offset]); offset++; } } final Term form = translate(quant.getSubformula()); final Attribute[] attrs = quant.getAttributes(); int numTrigs = 0; for (final Attribute a : attrs) { if (a instanceof Trigger) { numTrigs++; } } final Term[][] triggers = new Term[numTrigs][]; offset = 0; for (final Attribute a : attrs) { if (a instanceof Trigger) { final Expression[] trigs = ((Trigger) a).getTriggers(); final Term[] smttrigs = new Term[trigs.length]; for (int i = 0; i < trigs.length; i++) { final Term trig = translate(trigs[i]); // if (trig instanceof ITETerm // && ((ITETerm)trig).getTrueCase() == ONE // && ((ITETerm)trig).getFalseCase() == ZERO) // smttrigs[i] = ((ITETerm) trig).getCondition(); // else smttrigs[i] = trig; } triggers[offset++] = smttrigs; } } // throw new // UnsupportedOperationException("QuantifierExpression not implemented yet"); // identStack.pop(); // for (int j = 0; j < typeParams.length; j++) { // typeStack.pop(); // } mQuantifiedVariables.endScope(); Term result = null; try { result = quant.isUniversal() ? mScript.quantifier(Script.FORALL, vars, form, triggers) : mScript.quantifier(Script.EXISTS, vars, form, triggers); } catch (final SMTLIBException e) { if (e.getMessage().equals("Cannot create quantifier in quantifier-free logic")) { Boogie2SMT.reportUnsupportedSyntax( exp, "Setting does not support quantifiers", mServices); throw e; } else { throw new AssertionError(); } } assert resultContainsNoNull(result); return result; } else { throw new AssertionError("Unsupported expression " + exp); } }