/** * Translates a BoogieType to a Prover Type * * @param t * @return */ private ProverType type2ProverSort(BoogieType t) { if (t.getName().compareTo("int") == 0) { return theoremProver.getIntType(); } else if (t.getName().compareTo("bool") == 0) { return theoremProver.getBooleanType(); } else if (t.getName().compareTo("$stringsizetype") == 0) { ProverType[] argTypes = {theoremProver.getIntType()}; return theoremProver.getArrayType(argTypes, theoremProver.getIntType()); } else if (t instanceof BoogieFieldType) { return theoremProver.getIntType(); } else if (t instanceof BoogieArrayType) { ProverType[] argTypes = {theoremProver.getIntType()}; return theoremProver.getArrayType( argTypes, type2ProverSort(((BoogieArrayType) t).getNestedType())); } else if (t instanceof HeapType) { ProverType[] argTypes = {theoremProver.getIntType(), theoremProver.getIntType()}; return theoremProver.getArrayType(argTypes, theoremProver.getIntType()); } else if (t instanceof BoogieObjectType) { return theoremProver.getIntType(); } // TODO: not tested! return theoremProver.getIntType(); }
/** * generates a prover expression from an expression e * * @param e * @param boundvars * @return */ private ProverExpr expression2ProverExpr(Expression e, HashMap<Variable, ProverExpr> boundvars) { try { if (e instanceof ArrayReadExpression) { ArrayReadExpression exp = (ArrayReadExpression) e; return arrayExpression2ProverExpr( exp.getBaseExpression(), new LinkedList<Expression>(Arrays.asList(new Expression[] {exp.getIndexExpression()})), null, boundvars); } else if (e instanceof InvokeExpression) { InvokeExpression exp = (InvokeExpression) e; ProverFun fun = procedure2ProverExpr(exp.getInvokedProcedure()); LinkedList<ProverExpr> args = new LinkedList<ProverExpr>(); for (Expression e2 : exp.getArguments()) { args.add(expression2ProverExpr(e2, boundvars)); } return fun.mkExpr((ProverExpr[]) args.toArray(new ProverExpr[args.size()])); } else if (e instanceof SimpleHeapAccess) { SimpleHeapAccess exp = (SimpleHeapAccess) e; return arrayExpression2ProverExpr( exp.getHeapVariable(), new LinkedList<Expression>( Arrays.asList( new Expression[] {exp.getBaseExpression(), exp.getFieldExpression()})), null, boundvars); } else if (e instanceof TypeExpression) { TypeExpression exp = (TypeExpression) e; return expression2ProverExpr(exp.getTypeVariable(), boundvars); } else if (e instanceof Variable) { Variable exp = (Variable) e; if (boundvars.containsKey(exp)) { return boundvars.get(exp); } if (!usedVariable.containsKey(exp)) { ProverExpr pe = theoremProver.mkVariable( getProverFriendlyName(exp.getName()), type2ProverSort(exp.getType())); usedVariable.put(exp, pe); } return usedVariable.get(exp); } else if (e instanceof UboundedIntConstant) { UboundedIntConstant exp = (UboundedIntConstant) e; return theoremProver.mkLiteral(BigInteger.valueOf(exp.getValue())); } else if (e instanceof Constant) { Log.error("DEBUG-ERROR, there should not be any constant but Integers! VC will be wrong!"); return expression2ProverExpr(BoogieProgram.v().getNullReference(), boundvars); } else if (e instanceof QuantifiedExpression) { // TODO: right now, Quantifiers can only be used in Axioms QuantifiedExpression qe = (QuantifiedExpression) e; HashMap<Variable, ProverExpr> bvars = new HashMap<Variable, ProverExpr>(boundvars); // LinkedList<ProverExpr> localBound = new // LinkedList<ProverExpr>(); int idx = 0; for (Variable v : qe.getBoundVariables()) { ProverExpr boundvar = theoremProver.mkBoundVariable(idx++, type2ProverSort(v.getType())); bvars.put(v, boundvar); // localBound.add(boundvar); } ProverExpr boundExp = expression2ProverExpr(qe.getExpression(), bvars); if (qe.getQuantifier() == Quantifier.ForAll) { return theoremProver.mkAll(boundExp, theoremProver.getBooleanType()); } else { return theoremProver.mkEx(boundExp, theoremProver.getBooleanType()); } } else if (e instanceof BinOpExpression) { BinOpExpression be = (BinOpExpression) e; ProverExpr left = (expression2ProverExpr(be.getLhs(), boundvars)); ProverExpr right = (expression2ProverExpr(be.getRhs(), boundvars)); switch (be.getOp()) { case Eq: { return theoremProver.mkEq(left, right); } case Lt: { return theoremProver.mkLt(left, right); } case Le: { return theoremProver.mkLeq(left, right); } case Gt: { return theoremProver.mkGt(left, right); } case Ge: { return theoremProver.mkGeq(left, right); } case Neq: { return theoremProver.mkNot(theoremProver.mkEq(left, right)); } case Implies: { return theoremProver.mkOr(theoremProver.mkNot(left), right); } case LAnd: { return theoremProver.mkAnd(left, right); } case LOr: { return theoremProver.mkOr(left, right); } case Plus: { return theoremProver.mkPlus(left, right); } case Minus: { return theoremProver.mkMinus(left, right); } case Mul: { return theoremProver.mkMult(left, right); } default: { throw new RuntimeException("Unmatched binop: " + be.getOp().toString()); // TODO: a proper exception might be nice. // However, this case can only occur if we screw up the // implementation } } } else if (e instanceof IteExpression) { IteExpression ite = (IteExpression) e; ProverExpr condE = expression2ProverExpr(ite.getCond(), boundvars); ProverExpr thenE = expression2ProverExpr(ite.getThen(), boundvars); ProverExpr elseE = expression2ProverExpr(ite.getElse(), boundvars); return theoremProver.mkIte(condE, thenE, elseE); } else { Log.error("Unmatched Expression " + e.toString()); return null; } } catch (Exception exc) { Log.error("expression2ProverExpr failed: " + exc.toString()); Log.error("Called on expression: " + e.toString()); if (e instanceof BinOpExpression) { BinOpExpression boe = (BinOpExpression) e; Log.error(boe.getLhs().getType().toString() + " and " + boe.getRhs().getType()); } return null; } }
protected ProverExpr makeHelperVar(String name) { z3_helperVars.add(name); return theoremProver.mkVariable(name, theoremProver.getBooleanType()); }