Skip to content
Snippets Groups Projects
Commit f45d2751 authored by Taddeus Kroes's avatar Taddeus Kroes
Browse files

Added rule that removed fractions from denominators.

parent e12f71ea
No related branches found
No related tags found
No related merge requests found
......@@ -11,7 +11,7 @@ from .numerics import match_add_numerics, match_divide_numerics, \
match_multiply_numerics, match_multiply_zero, match_raise_numerics
from .fractions import match_constant_division, match_add_fractions, \
match_multiply_fractions, match_divide_fractions, \
match_extract_fraction_terms
match_extract_fraction_terms, match_division_in_denominator
from .negation import match_negated_factor, match_negate_polynome, \
match_negated_division
from .sort import match_sort_multiplicants
......@@ -43,7 +43,8 @@ RULES = {
match_factor_in_multiplicant],
OP_DIV: [match_subtract_exponents, match_divide_numerics,
match_constant_division, match_divide_fractions,
match_negated_division, match_extract_fraction_terms],
match_negated_division, match_extract_fraction_terms,
match_division_in_denominator],
OP_POW: [match_multiply_exponents, match_duplicate_exponent,
match_raised_fraction, match_remove_negative_exponent,
match_exponent_to_root, match_extend_exponent,
......
......@@ -268,7 +268,7 @@ def divide_fraction(root, args):
"""
(a, b), c = root
return (a / (b * c)).negate(root.negated)
return negate(a / (b * c), root.negated)
MESSAGES[divide_fraction] = _('Move {3} to denominator of fraction {1} / {2}.')
......@@ -281,7 +281,7 @@ def divide_by_fraction(root, args):
a, bc = root
b, c = bc
return (a * c / b).negate(root.negated + bc.negated)
return negate(a * c / b, root.negated + bc.negated)
MESSAGES[divide_by_fraction] = \
......@@ -370,7 +370,7 @@ def extract_nominator_term(root, args):
"""
a, c = args
return a / root[1] * c
return negate(a / root[1] * c, root.negated)
MESSAGES[extract_nominator_term] = \
......@@ -385,9 +385,39 @@ def extract_fraction_terms(root, args):
a ^ b * c / (a ^ d * e) -> a ^ b / a ^ d * (c / e)
"""
n_scope, d_scope, n, d = args
div = n / d * (remove_from_mult_scope(n_scope, n) \
/ remove_from_mult_scope(d_scope, d))
return n / d * (remove_from_mult_scope(n_scope, n) \
/ remove_from_mult_scope(d_scope, d))
return negate(div, root.negated)
MESSAGES[extract_fraction_terms] = _('Extract {3} / {4} from fraction {0}.')
def match_division_in_denominator(node):
"""
a / (b / c + d) -> (ca) / (c(b / c + d))
"""
assert node.is_op(OP_DIV)
denom = node[1]
if not denom.is_op(OP_ADD):
return []
return [P(node, multiply_with_term, (n[1],))
for n in Scope(denom) if n.is_op(OP_DIV)]
def multiply_with_term(root, args):
"""
a / (b / c + d) -> (ca) / (c(b / c + d))
"""
c = args[0]
nom, denom = root
return negate(c * nom / (c * denom), root.negated)
MESSAGES[multiply_with_term] = \
_('Multiply nominator and denominator of {0} with {1}.')
......@@ -3,7 +3,8 @@ from src.rules.fractions import match_constant_division, division_by_one, \
equalize_denominators, add_nominators, match_multiply_fractions, \
multiply_fractions, multiply_with_fraction, match_divide_fractions, \
divide_fraction, divide_by_fraction, match_extract_fraction_terms, \
constant_to_fraction, extract_nominator_term, extract_fraction_terms
constant_to_fraction, extract_nominator_term, extract_fraction_terms, \
match_division_in_denominator, multiply_with_term
from src.node import ExpressionNode as N, Scope, OP_MUL
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......@@ -284,3 +285,35 @@ class TestRulesFractions(RulesTestCase):
'a * 4 / 5',
# FIXME: '4 / 5 * a',
])
def test_match_division_in_denominator(self):
a, ((b, c), d) = root = tree('a / (b / c + d)')
self.assertEqualPos(match_division_in_denominator(root),
[P(root, multiply_with_term, (c,))])
a, ((d, (b, c)), e) = root = tree('a / (d + b / c + e)')
self.assertEqualPos(match_division_in_denominator(root),
[P(root, multiply_with_term, (c,))])
def test_multiply_with_term_chain(self):
self.assertRewrite([
'1 / (1 / b - 1 / a)',
'(b * 1) / (b(1 / b - 1 / a))',
'b / (b(1 / b - 1 / a))',
'b / (b * 1 / b + b(-1 / a))',
'b / ((b * 1) / b + b(-1 / a))',
'b / (b / b + b(-1 / a))',
'b / (1 + b(-1 / a))',
'b / (1 - b * 1 / a)',
'b / (1 - (b * 1) / a)',
'b / (1 - b / a)',
'(ab) / (a(1 - b / a))',
'(ab) / (a * 1 + a(-b / a))',
'(ab) / (a + a(-b / a))',
'(ab) / (a - ab / a)',
'(ab) / (a - (ab) / a)',
'(ab) / (a - a / a * b / 1)',
'(ab) / (a - 1b / 1)',
'(ab) / (a - 1b)',
'(ab) / (a - b)',
])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment