Пример #1
0
  // Converts ADD and MUL to division. e.g., a/2+1 --> (a+2)/2
  // This is called only when the expression is divisible.
  protected SimpleExpression toDivision() {
    SimpleExpression ret;
    if (sop == ADD) {
      List<SimpleExpression> converted = new LinkedList<SimpleExpression>();
      for (SimpleExpression child : children) converted.add(child.toDivision());
      SimpleExpression lcd = getLCD(converted);
      if (lcd.equals(sone)) ret = this;
      else {
        SimpleExpression dividend = szero;
        for (SimpleExpression child : converted) {
          if (child.sop == DIV)
            dividend = add(dividend, multiply(child.getChild(0), divide(lcd, child.getChild(1))));
          else dividend = add(dividend, multiply(child, lcd));
        }
        ret = divide(dividend, lcd);
      }
    } else if (sop == MUL) {
      SimpleExpression dividend = sone, divider = sone;
      for (SimpleExpression child : children) {
        if (child.sop == DIV) {
          dividend = multiply(dividend, child.getChild(0));
          divider = multiply(divider, child.getChild(1));
        } else dividend = multiply(dividend, child);
      }
      if (divider.equals(sone)) ret = this;
      else ret = divide(dividend, divider);
    } else ret = this;

    return ret;
  }
Пример #2
0
  // Aggressively normalize divisible expressions to minimize ADD operations.
  // This method is called only by induction variable substitution where
  // the divisibility of an expression is defined well.
  protected SimpleExpression normalizeDivisible() {
    SimpleExpression ret = this;
    if (sop == DIV) {
      if (getChild(0).sop == DIV)
        ret = divide(getChild(0).getChild(0), multiply(getChild(0).getChild(1), getChild(1)));
    } else if (sop == MUL) {
      ret = toDivision().normalize();
    } else if (sop == ADD) {
      ret = toDivision();
      if (ret.sop == DIV && ret.getChild(0).sop == ADD) {
        SimpleExpression non_div = szero, dividend = szero;
        SimpleExpression divider = ret.getChild(1);
        for (SimpleExpression child : ret.getChild(0).children) {
          SimpleExpression divided = divide(child, divider);
          if (divided.sop == DIV) dividend = add(dividend, child);
          else non_div = add(non_div, divided);
        }
        if (non_div.equals(szero) && ret.countsOperations(ADD) >= countsOperations(ADD))
          ret = this; // heuristics: no benefit from the simplification.
        else ret = add(non_div, divide(dividend, divider));
      }
    }

    return ret;
  }
Пример #3
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;
  }
Пример #4
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;
  }
Пример #5
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;
 }
Пример #6
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;
  }
Пример #7
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;
 }
Пример #8
0
 // Computes the least common denominator of the two simple expression.
 private static SimpleExpression computeLCD(SimpleExpression se1, SimpleExpression se2) {
   SimpleExpression divider1 = sone, divider2 = sone;
   if (se1.sop == DIV) divider1 = se1.getChild(1);
   if (se2.sop == DIV) divider2 = se2.getChild(1);
   return computeLCM(divider1, divider2);
 }