Commit eb087f2e authored by Taddeus Kroes's avatar Taddeus Kroes

Added rule to multiply fractions.

parent 6029187f
......@@ -10,7 +10,7 @@ from .numerics import match_add_numerics, match_divide_numerics, \
match_multiply_numerics, match_multiply_zero, match_multiply_one, \
match_raise_numerics
from .fractions import match_constant_division, match_add_constant_fractions, \
match_expand_and_add_fractions
match_expand_and_add_fractions, match_multiply_fractions
from .negation import match_negated_factor, match_negate_polynome, \
match_negated_division
from .sort import match_sort_multiplicants
......@@ -23,7 +23,7 @@ RULES = {
OP_MUL: [match_multiply_numerics, match_expand, match_add_exponents,
match_expand_and_add_fractions, match_multiply_zero,
match_negated_factor, match_multiply_one,
match_sort_multiplicants],
match_sort_multiplicants, match_multiply_fractions],
OP_DIV: [match_subtract_exponents, match_divide_numerics,
match_constant_division, match_negated_division],
OP_POW: [match_multiply_exponents, match_duplicate_exponent,
......
......@@ -173,3 +173,37 @@ def match_expand_and_add_fractions(node):
p = []
return p
def match_multiply_fractions(node):
"""
a / b * (c / d) -> ac / (bd)
"""
# TODO: is 'add' Appropriate when rewriting to "(a + (-d)) / * (b / c)"?
assert node.is_op(OP_MUL)
p = []
scope = Scope(node)
fractions = filter(lambda n: n.is_op(OP_DIV), scope)
for ab, cd in combinations(fractions, 2):
p.append(P(node, multiply_fractions, (scope, ab, cd)))
return p
def multiply_fractions(root, args):
"""
a / b * (c / d) -> ac / (bd)
"""
scope, ab, cd = args
a, b = ab
c, d = cd
scope.replace(ab, a * c / (b * d))
scope.remove(cd)
return scope.as_nary_node()
MESSAGES[multiply_fractions] = _('Multiply fractions {2} and {3}.')
from src.rules.fractions import match_constant_division, division_by_one, \
division_of_zero, division_by_self, match_add_constant_fractions, \
equalize_denominators, add_nominators
equalize_denominators, add_nominators, match_multiply_fractions, \
multiply_fractions
from src.node import Scope
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......@@ -123,3 +124,18 @@ class TestRulesFractions(RulesTestCase):
n0, n1 = root = a / -b + -c / -b
self.assertEqualNodes(add_nominators(root, (n0, n1)), (a + -c) / -b)
def test_match_multiply_fractions(self):
(a, b), (c, d) = ab, cd = root = tree('a / b * (c / d)')
self.assertEqualPos(match_multiply_fractions(root),
[P(root, multiply_fractions, (Scope(root), ab, cd))])
def test_multiply_fractions(self):
(a, b), (c, d) = ab, cd = root = tree('a / b * (c / d)')
self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)),
a * c / (b * d))
(ab, e), cd = root = tree('a / b * e * (c / d)')
self.assertEqual(multiply_fractions(root, (Scope(root), ab, cd)),
a * c / (b * d) * e)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment