Beispiel #1
0
  // Normalizes a MIN/MAX expression
  private SimpleExpression normalizeMINMAX() {
    // Literal/non-literal separation
    TreeSet<Double> literals = new TreeSet<Double>();
    TreeSet<SimpleExpression> exprs = new TreeSet<SimpleExpression>();
    SimpleExpression ret = new SimpleExpression(sop);
    for (SimpleExpression child : children) {
      if (child.sop == LIT) literals.add(child.getValue());
      else exprs.add(child);
    }
    if (sop == MIN) ret.add(getInt(literals.first().intValue()));
    else ret.add(getInt(literals.last().intValue()));
    ret.addAll(exprs);

    // Quick return for single-entry min/max.
    if (ret.children.size() == 1) return ret.getChild(0);

    // Match min(a,max(a,b))=a or max(a,min(a,b))=a
    if (ret.sop == MIN
            && ret.children.size() == 2
            && ret.getChild(1).sop == MAX
            && ret.getChild(1).children.size() == 2
            && ret.getChild(1).children.contains(ret.getChild(0))
        || ret.sop == MAX
            && ret.children.size() == 2
            && ret.getChild(1).sop == MIN
            && ret.getChild(1).children.size() == 2
            && ret.getChild(1).children.contains(ret.getChild(0))) return ret.getChild(0);

    return ret;
  }
Beispiel #2
0
  // Normalizes a comparison operation
  private SimpleExpression normalizeCompare() {
    SimpleExpression lhs = getChild(0), rhs = getChild(1);

    // Before normalization ( lhs <op> rhs )
    if (lhs.sop == LIT && rhs.sop == LIT) {
      double diff = lhs.getValue().doubleValue() - rhs.getValue().doubleValue();
      switch (sop) {
        case EQ:
          return (diff == 0) ? sone : szero;
        case NE:
          return (diff != 0) ? sone : szero;
        case LE:
          return (diff <= 0) ? sone : szero;
        case LT:
          return (diff < 0) ? sone : szero;
        case GE:
          return (diff >= 0) ? sone : szero;
        case GT:
          return (diff > 0) ? sone : szero;
        default:
          Tools.exit("[SimpleExpression] unknown comparison expression");
      }
    } else if (lhs.equals(rhs)) return (sop == EQ || sop == LE || sop == GE) ? sone : szero;

    // Normalization ( lhs-rhs <op> 0 )
    SimpleExpression ret = new SimpleExpression(sop);
    if (compare(lhs, rhs) < 0) {
      ret.add(subtract(rhs, lhs));
      ret.sop = exchangeOp(sop);
    } else ret.add(subtract(lhs, rhs));
    ret.add(szero);

    return ret;
  }
Beispiel #3
0
  // Negates this simple expression
  private SimpleExpression negate() {
    SimpleExpression ret = null;

    if (sop == NEG) ret = getChild(0);
    else if (sop == LIT) ret = (equals(szero)) ? sone : szero;
    else if (sop >= EQ && sop <= GT) {
      ret = (SimpleExpression) clone();
      ret.sop = negateOp(sop);
    } else if (sop == AND || sop == OR) {
      ret = new SimpleExpression((sop == AND) ? OR : AND);
      for (SimpleExpression child : children) ret.add(child.negate());
    } else {
      ret = new SimpleExpression(NEG);
      ret.add(this);
    }

    return ret;
  }
Beispiel #4
0
 // Distributes terms; a*(b+c) --> a*b+a*c
 private SimpleExpression distribute() {
   if (!allow(DISTRIBUTE) || sop != MUL || !containsChildOfType(ADD)) return this;
   SimpleExpression ret = sone;
   for (SimpleExpression child : children) {
     SimpleExpression lhs = new SimpleExpression(szero, ADD, ret);
     SimpleExpression rhs = new SimpleExpression(szero, ADD, child);
     ret = new SimpleExpression(ADD);
     for (SimpleExpression lhs_child : lhs.children)
       for (SimpleExpression rhs_child : rhs.children) ret.add(multiply(lhs_child, rhs_child));
   }
   ret = ret.normalizeADD();
   // Tools.printlnStatus("[DIST] "+this+" --> "+ret, 1);
   return ret;
 }
Beispiel #5
0
  // Returns the non-literal term in the simple expression.
  protected SimpleExpression getTerm() {
    SimpleExpression ret = null;
    if (sop == LIT) ret = sone;
    else if (sop != MUL) ret = this;
    else {
      ret = new SimpleExpression(MUL);
      for (SimpleExpression child : children) if (child.sop != LIT) ret.add(child);

      if (ret.children.size() == 0) ret = sone;
      else if (ret.children.size() == 1) ret = ret.getChild(0);
    }
    // Tools.printlnStatus("[TERM] "+this+" --> "+ret, 1);
    return ret;
  }
Beispiel #6
0
  // Parses a binary expression
  private void parse(BinaryExpression be) {
    BinaryOperator bop = be.getOperator();
    SimpleExpression lhs = new SimpleExpression(be.getLHS());
    SimpleExpression rhs = new SimpleExpression(be.getRHS());
    contains_side_effect |= (lhs.contains_side_effect || rhs.contains_side_effect);

    if (bop == BinaryOperator.SUBTRACT) {
      sop = ADD;
      SimpleExpression new_rhs = new SimpleExpression(MUL);
      new_rhs.add(getInt(-1));
      new_rhs.add(rhs);
      add(lhs);
      add(new_rhs);
    } else {
      sop = cop.indexOf(bop);
      if (sop == -1) {
        sop = TREE;
        expr = be;
      }
      add(lhs);
      add(rhs);
    }
  }
Beispiel #7
0
 // Removes division by replacing with modulus operations.
 // The returned list contains the modified simple expression (get(0)) and
 // the additionally multiplied value (get(1)).
 // e.g., a*(b/c)*(d/e) returns {a*(b-b%c)*(d-d%e), c*e}.
 // It is important to notice that the legality check of this transformation
 // is up to the callers.
 // It is assumed that the original simple expressions has been normalized.
 protected List<SimpleExpression> multiplyByLCM() {
   List<SimpleExpression> ret = new ArrayList<SimpleExpression>(2);
   if (sop == DIV) {
     ret.add(subtract(getChild(0), mod(getChild(0), getChild(1))));
     ret.add(getChild(1));
   } else if (sop == ADD) {
     List<SimpleExpression> terms = new LinkedList<SimpleExpression>();
     List<SimpleExpression> factors = new LinkedList<SimpleExpression>();
     SimpleExpression lcm = sone;
     for (SimpleExpression child : children) {
       List<SimpleExpression> ret0 = child.multiplyByLCM();
       terms.add(ret0.get(0));
       factors.add(ret0.get(1));
       lcm = computeLCM(lcm, ret0.get(1));
     }
     SimpleExpression ret1 = new SimpleExpression(ADD);
     for (int i = 0; i < terms.size(); i++)
       ret1.add(multiply(divide(lcm, factors.get(i)), terms.get(i)));
     ret.add(ret1.normalize());
     ret.add(lcm);
   } else if (sop == MUL) {
     SimpleExpression terms = new SimpleExpression(MUL);
     SimpleExpression factors = sone;
     for (SimpleExpression child : children) {
       List<SimpleExpression> ret0 = child.multiplyByLCM();
       terms.add(ret0.get(0));
       factors = multiply(factors, ret0.get(1));
     }
     ret.add(terms.normalize());
     ret.add(factors);
   } else {
     ret.add(this);
     ret.add(sone);
   }
   return ret;
 }
Beispiel #8
0
 // Normalizes an AND|OR operation
 private SimpleExpression normalizeLogic() {
   if (!allow(LOGIC)) return this;
   TreeSet<SimpleExpression> set = new TreeSet<SimpleExpression>(children);
   TreeSet<SimpleExpression> neg = new TreeSet<SimpleExpression>();
   SimpleExpression ret = new SimpleExpression(sop);
   for (SimpleExpression child : set) {
     if (sop == AND) {
       if (child.equals(szero) || neg.contains(child)) return szero;
       else if (child.sop != LIT) // ==LIT means non-zero literal.
       ret.add(child);
     } else // sop == OR
     {
       if ((child.sop == LIT && !child.equals(szero)) || neg.contains(child)) return sone;
       else if (child.sop != LIT) // ==LIT means zero literal.
       ret.add(child);
     }
     neg.add(child.negate());
   }
   if (ret.children.size() == 0) // skipped literals.
   ret = (ret.sop == AND) ? sone : szero;
   else if (ret.children.size() == 1) ret = ret.getChild(0);
   // Tools.printlnStatus("[LOGIC] "+this+" --> "+ret, 1);
   return ret;
 }
Beispiel #9
0
 // Normalizes a MUL expression
 private SimpleExpression normalizeMUL() {
   SimpleExpression ret = this;
   if (allow(FOLD)) {
     SimpleExpression coef = sone;
     LinkedList<SimpleExpression> terms = new LinkedList<SimpleExpression>();
     for (SimpleExpression child : children) {
       if (child.sop == LIT) coef = multiply(coef, child);
       else terms.add(child);
     }
     ret = new SimpleExpression(MUL);
     if (coef.equals(szero)) ret = szero;
     else {
       if (!coef.equals(sone) || terms.size() == 0) ret.add(coef);
       ret.addAll(terms);
       if (ret.children.size() == 1) ret = ret.getChild(0);
     }
   }
   ret = ret.distribute();
   // Tools.printlnStatus("[MUL] "+this+" --> "+ret, 1);
   return ret;
 }
Beispiel #10
0
  // Normalizes an ADD expression
  private SimpleExpression normalizeADD() {
    if (!allow(FOLD)) return this;
    TreeMap<SimpleExpression, SimpleExpression> terms =
        new TreeMap<SimpleExpression, SimpleExpression>();
    for (SimpleExpression child : children) {
      SimpleExpression term = child.getTerm(), coef = child.getCoef();
      if (terms.containsKey(term)) terms.put(term, add(terms.get(term), coef));
      else terms.put(term, coef);
    }

    SimpleExpression ret = new SimpleExpression(ADD);
    for (SimpleExpression term : terms.keySet()) {
      SimpleExpression coef = terms.get(term);
      if (!coef.equals(szero)) ret.add((coef.equals(sone)) ? term : multiply(coef, term));
    }

    if (ret.children.size() == 0) ret = szero;
    else if (ret.children.size() == 1) ret = ret.getChild(0);
    // Tools.printlnStatus("[ADD] "+this+" --> "+ret, 1);

    return ret;
  }
Beispiel #11
0
  // Normalizes this simple expression recursively.
  protected SimpleExpression normalize() {
    SimpleExpression ret = new SimpleExpression(this);

    for (SimpleExpression child : children) ret.add(child.normalize());

    if (contains_side_effect) return ret;

    switch (ret.sop) {
      case ID:
      case LIT:
      case LEAF:
        ret = this;
        break;
      case ADD:
        ret = ret.normalizeADD();
        break;
      case MUL:
        ret = ret.normalizeMUL();
        break;
      case DIV:
        ret = ret.normalizeDIV();
        break;
      case MOD:
        ret = ret.normalizeMOD();
        break;
      case SFTL:
      case SFTR:
      case BAND:
      case BOR:
      case BXOR:
        ret = ret.normalizeBitOperation();
        break;
      case BCMP:
        ret = ret.normalizeBCMP();
        break;
      case AND:
      case OR:
        ret = ret.normalizeLogic();
        break;
      case EQ:
      case NE:
      case LE:
      case LT:
      case GE:
      case GT:
        ret = ret.normalizeCompare();
        break;
      case NEG:
        ret = ret.normalizeNEG();
        break;
      case MIN:
      case MAX:
        ret = ret.normalizeMINMAX();
        break;
      default:
    }

    if (ret.isCommAssoc()) ret.sort();

    // Tools.printlnStatus("[NORM] "+this+" --> "+ret, 1);
    return ret;
  }