/** * translate boogie statement to prover expression * * @param s * @return */ protected ProverExpr statement2ProverExpr(Statement s) { if (s instanceof AssignStatement) { AssignStatement st = (AssignStatement) s; if (st.getLeft() instanceof SimpleHeapAccess || st.getLeft() instanceof ArrayReadExpression) { return arrayWrite2ProverExpr(st.getLeft(), expression2ProverExpr(st.getRight())); } else { return theoremProver.mkEq( expression2ProverExpr(st.getLeft()), expression2ProverExpr(st.getRight())); } } else if (s instanceof AssumeStatement) { AssumeStatement st = (AssumeStatement) s; return guardExpression2ProverExpr(st.getExpression()); } else if (s instanceof AssertStatement) { AssertStatement st = (AssertStatement) s; return guardExpression2ProverExpr(st.getExpression()); } else if (s instanceof InvokeStatement) { InvokeStatement st = (InvokeStatement) s; if (st.getReturnTargets().size() > 1) { Log.error("A method with too many return parameters! Should have been removed in SSA"); return null; } ProverFun fun = procedure2ProverExpr(st.getInvokedProcedure()); Log.error( "This should not happen as calls are removed by SSA: " + fun.toString()); // TODO: proper error handling? // This can never happen. LinkedList<ProverExpr> args = new LinkedList<ProverExpr>(); for (Expression e : st.getArguments()) { args.add(expression2ProverExpr(e)); } ProverExpr ret = fun.mkExpr((ProverExpr[]) args.toArray(new ProverExpr[args.size()])); if (st.getReturnTargets().size() > 0) { ProverExpr lhs = expression2ProverExpr(st.getReturnTargets().get(0)); if (st.getReturnTargets().get(0) instanceof SimpleHeapAccess || st.getReturnTargets().get(0) instanceof ArrayReadExpression) { ret = arrayWrite2ProverExpr(st.getReturnTargets().get(0), ret); // ((NAryExpression)lhs).addArgument(ret); // ret = VCExpressionGenerator.binOp(TmpConstants.Eq, // ((NAryExpression)lhs).getArgument(0),lhs); } else { ret = theoremProver.mkEq(lhs, ret); } } return ret; } else if (s instanceof ExpressionStatement) { ExpressionStatement es = (ExpressionStatement) s; return expression2ProverExpr(es.getExpression()); } else { Log.error("Unmatched Statement " + s.toString()); return null; } }
private ProverFun procedure2ProverExpr(BoogieProcedure proc) { HashMap<Variable, ProverExpr> localbound = new HashMap<Variable, ProverExpr>(); if (!usedFunctions.containsKey(proc)) { LinkedList<ProverType> args = new LinkedList<ProverType>(); int idx = 0; for (Variable v : proc.getParameterList()) { ProverExpr arg = theoremProver.mkBoundVariable(idx++, type2ProverSort(v.getType())); args.add(arg.getType()); localbound.put(v, arg); } ProverFun vcf = null; ProverType[] arr = args.toArray(new ProverType[args.size()]); if (proc.isPure() && proc.getRootBlock() != null && proc.getRootBlock().getStatements().size() == 1) { // TODO: this is a hack: // we assume that this case only occurs for prelude functions // which have only one statement // this will not work in any other case Statement stmt = proc.getRootBlock().getStatements().get(0); ProverExpr b = null; if (stmt instanceof ExpressionStatement) { ExpressionStatement es = (ExpressionStatement) stmt; b = expression2ProverExpr(es.getExpression(), localbound); } else { throw new RuntimeException("procedure2ProverExpr failed"); } vcf = theoremProver.mkDefinedFunction(getProverFriendlyName(proc.getName()), arr, b); } else { vcf = theoremProver.mkUnintFunction( getProverFriendlyName(proc.getName()), arr, type2ProverSort(proc.getReturnVariable().getType())); // TODO: uninterpreted functions? } usedFunctions.put(proc, vcf); } return usedFunctions.get(proc); }