Example #1
0
 public /*@Nullable*/ String translate(IExpr expr) throws IVisitor.VisitorException {
   Translator t = new Translator(typemap, smtConfig);
   String r = expr.accept(t);
   if (t.conjuncts.isEmpty()) return r;
   String and = "(AND ";
   for (String c : t.conjuncts) {
     and = and + c + " ";
   }
   and = and + r + " )";
   return and;
 }
Example #2
0
 @Override
 public IResponse get_value(IExpr... terms) {
   TypeChecker tc = new TypeChecker(symTable);
   try {
     for (IExpr term : terms) {
       term.accept(tc);
     }
   } catch (IVisitor.VisitorException e) {
     tc.result.add(smtConfig.responseFactory.error(e.getMessage()));
   } finally {
     if (!tc.result.isEmpty()) return tc.result.get(0); // FIXME - report all errors?
   }
   // FIXME - do we really want to call get-option here? it involves going to the solver?
   if (!Utils.TRUE.equals(get_option(smtConfig.exprFactory.keyword(Utils.PRODUCE_MODELS)))) {
     return smtConfig.responseFactory.error(
         "The get-value command is only valid if :produce-models has been enabled");
   }
   if (!smtConfig.responseFactory.sat().equals(checkSatStatus)
       && !smtConfig.responseFactory.unknown().equals(checkSatStatus)) {
     return smtConfig.responseFactory.error(
         "A get-value command is valid only after check-sat has returned sat or unknown");
   }
   return smtConfig.responseFactory.unsupported();
 }
Example #3
0
    @Override
    public String visit(IFcnExpr e) throws IVisitor.VisitorException {
      boolean resultIsFormula = this.isFormula;
      StringBuilder sb = new StringBuilder();
      try {
        Iterator<IExpr> iter = e.args().iterator();
        if (!iter.hasNext())
          throw new VisitorException("Did not expect an empty argument list", e.pos());
        if (!(e.head() instanceof ISymbol)) {
          throw new VisitorException(
              "Have not yet implemented parameterized bit-vector functions", e.pos());
        }
        ISymbol fcn = (ISymbol) e.head();
        String newName = fcn.accept(this);

        // Determine if the arguments are formulas or terms
        if (resultIsFormula) {
          if (newName != null && logicNames.contains(newName)) {
            // Propositional boolean item
            this.isFormula = true;
          } else if (e.args().size() <= 1) {
            this.isFormula = false;
          } else {
            IExpr arg = e.args().get(1); // Use argument 1 for ite's sake
            ISort sort = typemap.get(arg);
            if (sort == null) {
              throw new VisitorException(
                  "INTERNAL ERROR: Encountered an un-sorted expression node: "
                      + smtConfig.defaultPrinter.toString(arg),
                  arg.pos());
            }
            if (sort.isBool()) {
              // Some functions can take both bool and non-bool arguments:
              //   EQ NEQ DISTINCT ite
              this.isFormula = resultIsFormula;
              if ("EQ".equals(newName)) newName = "IFF";
            } else {
              // Arguments must be terms
              this.isFormula = false;
            }
          }
        } else {
          this.isFormula = false;
        }

        ISort s = typemap.get(e);
        if (s == null) {
          throw new VisitorException(
              "INTERNAL ERROR: Encountered an un-sorted expression node: "
                  + smtConfig.defaultPrinter.toString(e),
              e.pos());
        }
        if (s.isBool() && !resultIsFormula) {
          throw new VisitorException(
              "Use of boolean in a term position is not yet implemented in the Simplify adapter",
              e.pos()); // FIXME - booleans as terms
        }

        if (isFormula && newName.equals("NEQ")) {
          // for formulas, NEQ is (NOT (IFF p q ...))
          // In simplify, IFF is not implicitly chainable
          int length = e.args().size();
          if ((length & 1) == 0) sb.append("(NOT ");
          sb.append(leftassoc("IFF", length, iter));
          if ((length & 1) == 0) sb.append(")");

        } else if (newName.equals("IMPLIES")) {
          // right-associative operators that need grouping
          if (!iter.hasNext()) {
            throw new VisitorException("implies (=>) operation without arguments", e.pos());
          }
          sb.append(rightassoc(newName, iter));

        } else if (newName.equals("DISTINCT")) {
          // in simplify, DISTINCT is just for term arguments but the result is a formula
          if (isFormula) {
            // arguments are formulas, result is formula
            if (e.args().size() > 2) {
              // More than two distinct boolean values?
              sb.append("FALSE");
            } else {
              sb.append("(NOT (IFF");
              while (iter.hasNext()) {
                sb.append(" ");
                sb.append(iter.next().accept(this));
              }
              sb.append(" ))");
            }
          } else if (resultIsFormula) {
            // arguments are terms, result is formula - standard use in Simplify
            sb.append("(DISTINCT");
            while (iter.hasNext()) {
              sb.append(" ");
              sb.append(iter.next().accept(this));
            }
            sb.append(")");
          } else {
            // used in a term position
            throw new VisitorException(
                "Use of DISTINCT in a term position is not yet implemented in the Simplify adapter",
                e.pos()); // FIXME - distinact as a term
          }
        } else if (ite_term.equals(newName)) {
          if (isFormula) {
            sb.append("(AND (IMPLIES ");
            sb.append(e.args().get(0).accept(this));
            sb.append(" ");
            sb.append(e.args().get(1).accept(this));
            sb.append(")");
            sb.append("(IMPLIES (NOT ");
            sb.append(e.args().get(0).accept(this));
            sb.append(") ");
            sb.append(e.args().get(2).accept(this));
            sb.append("))");
          }
        }
        if (e.args().size() > 2 && nonchainables.contains(newName)) {
          Iterator<IExpr> iter2 = e.args().iterator();
          sb.append("(AND ");

          IExpr left = iter2.next();
          while (iter2.hasNext()) {
            IExpr right = iter2.next();
            sb.append("(" + newName + " ");
            sb.append(left.accept(this));
            sb.append(" ");
            sb.append(right.accept(this));
            sb.append(")");
            left = right;
          }
          sb.append(")");
        }
        if (e.args().size() > 2 && (newName.equals("-") || newName.equals("/"))) {
          Iterator<IExpr> iter2 = e.args().iterator();
          sb.append(leftassoc(newName, e.args().size(), iter2));
        }

        if (sb.length() == 0) {
          sb.append("( ");
          sb.append(newName);
          while (iter.hasNext()) {
            sb.append(" ");
            sb.append(iter.next().accept(this));
          }
          sb.append(" )");
        }
      } finally {
        this.isFormula = resultIsFormula;
      }
      return sb.toString();
    }