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();
  }
Example #2
0
  // TODO fix BoogieHelperFunctions s.t. we can remove qual_name and
  // returntype because they are already in proc
  public InvokeExpression(BoogieProcedure proc, LinkedList<Expression> args) {
    invokedProcedure = proc;
    qualifiedName = proc.getName();
    if (proc.getReturnVariable() != null) {
      returnType = proc.getReturnVariable().getType();
    } else {
      returnType = BoogieBaseTypes.getVoidType();
    }

    arguments = args;
  }
  /**
   * @param base
   * @param indices
   * @param rhs is null if we have Select operation, otherwise it is the value E on the right hand
   *     side of an assignment a[x]=E.
   * @param boundvars
   * @return This is needed here only for one purpose: a[x] = 5 in Boogie is translated to
   *     a__i[x__j] = 5 in SSA-Boogie but in the VC we have to write (= a__i (store a__(i-1) x__j
   *     5), so we need to be able to access the previous incarnation of array typed variables
   *     Probably, we should settle this already during SSA and introduce uninterpreted procedures
   *     for store and select.
   */
  private ProverExpr arrayExpression2ProverExpr(
      Expression base,
      LinkedList<Expression> indices,
      ProverExpr rhs,
      HashMap<Variable, ProverExpr> boundvars) {
    LinkedList<ProverExpr> args = new LinkedList<ProverExpr>();
    if (rhs != null) {
      if (base instanceof SSAVariable) {
        SSAVariable var = (SSAVariable) base;
        SSAVariable tmp = null;

        for (Variable v : proc.getVarIncarnationMap().get(((SSAVariable) base).getOriginalVar())) {
          if (v instanceof SSAVariable) {
            if (((SSAVariable) v).getIncarnation() == ((SSAVariable) base).getIncarnation() - 1) {
              tmp = (SSAVariable) v;
              break;
            }
          }
        }
        if (tmp == null) {
          tmp = new SSAVariable(var.getOriginalVar(), var.getIncarnation() - 1);
          proc.getVarIncarnationMap().get(((SSAVariable) base).getOriginalVar()).addFirst(tmp);
        }
        base = tmp;
      } else {
        Log.error(
            "org.joogie.vcgen.VCGeneration.arrayaccess2VCExpression: this case has not been considered ... Joogie will crash!");
      }
    }
    ProverExpr arr = expression2ProverExpr(base, boundvars);
    for (Expression idx : indices) {
      args.add(expression2ProverExpr(idx, boundvars));
    }
    if (rhs != null)
      return theoremProver.mkStore(
          arr, (ProverExpr[]) (args.toArray(new ProverExpr[args.size()])), rhs);
    else
      return theoremProver.mkSelect(
          arr, (ProverExpr[]) (args.toArray(new ProverExpr[args.size()])));
  }
  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);
  }