/** * Translates a guard in an axiom to a prover expression * * @param exp * @return */ private ProverExpr guardExpression2ProverExpr(Expression exp) { if (exp instanceof BinOpExpression) { /* * TODO: this case should only occur for inlined axioms. The current * type system is a bit messed up as it does not really allow * boolean types in the Boogie program. If we do a major revision, * we should definitely take care of this */ return expression2ProverExpr(exp); } else if (exp instanceof IteExpression) { return expression2ProverExpr(exp); } else { return theoremProver.mkEq(expression2ProverExpr(exp), theoremProver.mkLiteral(1)); } }
/** * 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; } }