private String z3_printSMT2Declarations() { StringBuilder sb = new StringBuilder(); sb.append("(set-logic AUFLIA)\n\n"); for (String s : z3_helperVars) { sb.append("(declare-fun "); sb.append(getProverFriendlyName(s)); sb.append(" () Bool"); sb.append(")\n"); } for (Entry<Variable, ProverExpr> entry : usedVariable.entrySet()) { sb.append("(declare-fun "); sb.append(getProverFriendlyName(entry.getKey().getName())); sb.append(" () "); sb.append(z3_type2SMT2(entry.getKey().getType())); sb.append(")\n"); } for (Entry<BoogieProcedure, ProverFun> entry : usedFunctions.entrySet()) { // distinguish between prelude functions that have exactly one // statement and are pure // and all the rest. if (proc.isPure() && proc.getRootBlock() != null && proc.getRootBlock().getStatements().size() == 1) { // TODO: for some reason this does not happen, // as princess already inlines those functions and they // are not added to the list of used functions. throw new RuntimeException("SMT2 Printer, unexpected prelude function"); } else { sb.append("(declare-fun "); sb.append(getProverFriendlyName(entry.getKey().getName())); sb.append("( "); // now the params for (Variable param : entry.getKey().getParameterList()) { sb.append("("); sb.append(z3_type2SMT2(param.getType())); sb.append(") "); } sb.append(") "); // done with params // not the regular return value: if (entry.getKey().getReturnVariable() != null) { sb.append(z3_type2SMT2(entry.getKey().getReturnVariable().getType())); sb.append(" "); } // TODO: at this point, the SSA should have removed all // calls to non-pure functions already, so no need to // worry about exception handling sb.append(")\n"); } } return sb.toString(); }
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); }