예제 #1
0
 @Override
 public String visit(ISymbol e) throws IVisitor.VisitorException {
   // Symbols do not necessarily have sorts - e.g. if they are function names
   ISort sort = typemap.get(e);
   if (!isFormula && sort != null && sort.isBool()) {
     throw new VisitorException(
         "Use of boolean in a term position is not yet implemented in the Simplify adapter",
         e.pos()); // FIXME - booleans as terms
   }
   // Simplify does not allow tab, newline, cr in identifiers;
   // these are allowed by SMTLIB.
   // Note that neither simplify nor SMTLIB allows \ or |
   // All other printable characters are allowed in both.
   String oldName = e.value();
   String newName = fcnNames.get(oldName);
   if (newName != null) {
     // There is a direct translation of a pre-defined SMT-LIB name
     // into a simplify equivalent - use it.
   } else {
     // Use the ? character as an escape
     newName =
         oldName.replace("?", "??").replace("\n", "?n").replace("\r", "?r").replace("\t", "?t");
     if (reservedWords.contains(newName)) {
       newName = newName + "?!";
     }
     newName = "|" + newName + "|";
   }
   return newName;
 }
예제 #2
0
  /** Parses the arguments of the command, producing a new command instance */
  public static /*@Nullable*/ C_declare_const parse(Parser p) throws ParserException {
    /*@Nullable*/ ISymbol symbol = p.parseSymbol();
    if (symbol == null) return null;

    /*@Nullable*/ ISort result = p.parseSort(null);
    if (result == null) return null;
    String v = symbol.value();
    if (v.length() > 0 && (v.charAt(0) == '@' || v.charAt(0) == '.')) {
      error(p.smt(), "User-defined symbols may not begin with . or @", symbol.pos());
      return null;
    }
    return new C_declare_const(symbol, result);
  }
예제 #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();
    }