// Returns the number of descendants with the specified type. private int countsOperations(int op) { int ret = 0; if (children == null) return ret; for (SimpleExpression child : children) ret += child.countsOperations(op); if (sop == op) ret += children.size() - 1; return ret; }
// 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; }