def pow_atom_common_terms(pair): # print "pow_atom_common_terms: finding common terms of " + str(pair) if Rule.is_a(pair[1], Const): return [] if pair[0].base() != pair[1]: return [] return [pair[1]]
def pow_common_terms(pair): # print "pow_common_terms: finding common terms of " + str(pair) if not Rule.all_equal([term.base() for term in pair]): return [] if Rule.all_are([term.exponent() for term in pair], Var): return [] if Rule.all_are([term.exponent() for term in pair], Const): if Rule.all_are([term.exponent().value() for term in pair], int): v1 = pair[0].exponent().value() v2 = pair[1].exponent().value() return [Power(pair[0].base(), Const(min(v1, v2)))] common_in_exp = common_terms((pair[0].exponent(), pair[1].exponent())) if len(common_in_exp) > 0: if len(common_in_exp) > 1: mults = Multiply(*common_in_exp) else: mults = common_in_exp[0] return [Power(pair[0].base(), mults)] return []
def distribute_op(matched): new_args = copy(matched.args) def distribute_modifying_args(term, addition): new_args.remove(addition) new_args.remove(term) new_args.append(Add(*[Multiply(term, add_arg) for add_arg in addition.args])) if len(matched.args) > 1 and Rule.is_a(matched.args[0], Add): distribute_modifying_args(matched.args[1], matched.args[0]) else: for idx in range(1, len(matched.args)): current_arg = matched.args[idx] if Rule.is_a(current_arg, Add): distribute_modifying_args(matched.args[0], current_arg) break print "distributing: " + str(matched) print "new args: " + str(new_args) if len(new_args) == 1: return new_args[0] else: return Multiply(*new_args)
def pull_pow_from_mult(power, mult): new_args = [] for fact in mult.args: if Rule.is_a(fact, Power) and fact.base() == power.base(): new_args.append(pull(power, fact)) else: new_args.append(fact) if len(new_args) == 0: return Const(1) elif len(new_args) == 1: return new_args[0] else: return Multiply(*new_args)
def pull(factor, value): if Rule.is_a(factor, Const): #it's only possible to pull a constant out of a const or a multiplication if Rule.is_a(value, Const) and float(value.value()) % float(factor.value()) == 0: return Const(value.value() / factor.value()) elif Rule.is_a(value, Multiply): return pull_factor_from_mult(factor, value) elif Rule.is_a(factor, Var): #a var can be pulled out of a var, a multiplication, or a power if Rule.is_a(value, Var) and value == factor: return Const(1) elif Rule.is_a(value, Multiply): return pull_factor_from_mult(factor, value) elif Rule.is_a(value, Power): return Power(value.base(), Add(value.exponent(), Const(-1))) elif Rule.is_a(factor, Add): #an addition can be pulled out of a multiplication or a power if Rule.is_a(value, Multiply): return pull_factor_from_mult(factor, value) elif Rule.is_a(value, Power): return Power(value.base(), Add(value.exponent(), Const(-1))) elif Rule.is_a(factor, Power): #a power can be pulled out of a multiply or a power if Rule.is_a(value, Multiply): return pull_pow_from_mult(factor, value) elif Rule.is_a(value, Power): return Power(value.base(), Add(value.exponent(), Multiply(Const(-1), factor.exponent()))) return value
def common_terms(pair): # print "common_terms: finding common terms of " + str(pair) if Rule.all_are(pair, Const): return const_common_terms(pair) if Rule.all_are(pair, Var): if pair[0] == pair[1]: return [pair[0]] else: return [] if Rule.all_are(pair, Atom): return [] if Rule.all_are(pair, Multiply): return mult_common_terms(pair) if Rule.is_a(pair[0], Multiply) and Rule.is_a(pair[1], Atom): return mult_atom_common_terms(pair) if Rule.is_a(pair[0], Atom) and Rule.is_a(pair[1], Multiply): return mult_atom_common_terms((pair[1], pair[0])) if Rule.all_are(pair, Power): return pow_common_terms(pair) if Rule.is_a(pair[0], Power) and Rule.is_a(pair[1], Atom): return pow_atom_common_terms(pair) if Rule.is_a(pair[0], Atom) and Rule.is_a(pair[1], Power): return pow_atom_common_terms((pair[1], pair[0])) if Rule.is_a(pair[0], Multiply) and Rule.is_a(pair[1], Power): return mult_pow_common_terms(pair) if Rule.is_a(pair[0], Power) and Rule.is_a(pair[1], Multiply): return mult_pow_common_terms((pair[1], pair[0])) return []