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, \ ...@@ -11,7 +11,7 @@ from .numerics import match_add_numerics, match_divide_numerics, \
match_multiply_numerics, match_multiply_zero, match_raise_numerics match_multiply_numerics, match_multiply_zero, match_raise_numerics
from .fractions import match_constant_division, match_add_fractions, \ from .fractions import match_constant_division, match_add_fractions, \
match_multiply_fractions, match_divide_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, \ from .negation import match_negated_factor, match_negate_polynome, \
match_negated_division match_negated_division
from .sort import match_sort_multiplicants from .sort import match_sort_multiplicants
...@@ -43,7 +43,8 @@ RULES = { ...@@ -43,7 +43,8 @@ RULES = {
match_factor_in_multiplicant], match_factor_in_multiplicant],
OP_DIV: [match_subtract_exponents, match_divide_numerics, OP_DIV: [match_subtract_exponents, match_divide_numerics,
match_constant_division, match_divide_fractions, 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, OP_POW: [match_multiply_exponents, match_duplicate_exponent,
match_raised_fraction, match_remove_negative_exponent, match_raised_fraction, match_remove_negative_exponent,
match_exponent_to_root, match_extend_exponent, match_exponent_to_root, match_extend_exponent,
......
...@@ -268,7 +268,7 @@ def divide_fraction(root, args): ...@@ -268,7 +268,7 @@ def divide_fraction(root, args):
""" """
(a, b), c = root (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}.') MESSAGES[divide_fraction] = _('Move {3} to denominator of fraction {1} / {2}.')
...@@ -281,7 +281,7 @@ def divide_by_fraction(root, args): ...@@ -281,7 +281,7 @@ def divide_by_fraction(root, args):
a, bc = root a, bc = root
b, c = bc 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] = \ MESSAGES[divide_by_fraction] = \
...@@ -370,7 +370,7 @@ def extract_nominator_term(root, args): ...@@ -370,7 +370,7 @@ def extract_nominator_term(root, args):
""" """
a, c = args a, c = args
return a / root[1] * c return negate(a / root[1] * c, root.negated)
MESSAGES[extract_nominator_term] = \ MESSAGES[extract_nominator_term] = \
...@@ -385,9 +385,39 @@ def extract_fraction_terms(root, args): ...@@ -385,9 +385,39 @@ def extract_fraction_terms(root, args):
a ^ b * c / (a ^ d * e) -> a ^ b / a ^ d * (c / e) a ^ b * c / (a ^ d * e) -> a ^ b / a ^ d * (c / e)
""" """
n_scope, d_scope, n, d = args 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) \ return negate(div, root.negated)
/ remove_from_mult_scope(d_scope, d))
MESSAGES[extract_fraction_terms] = _('Extract {3} / {4} from fraction {0}.') 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, \ ...@@ -3,7 +3,8 @@ from src.rules.fractions import match_constant_division, division_by_one, \
equalize_denominators, add_nominators, match_multiply_fractions, \ equalize_denominators, add_nominators, match_multiply_fractions, \
multiply_fractions, multiply_with_fraction, match_divide_fractions, \ multiply_fractions, multiply_with_fraction, match_divide_fractions, \
divide_fraction, divide_by_fraction, match_extract_fraction_terms, \ 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.node import ExpressionNode as N, Scope, OP_MUL
from src.possibilities import Possibility as P from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree from tests.rulestestcase import RulesTestCase, tree
...@@ -284,3 +285,35 @@ class TestRulesFractions(RulesTestCase): ...@@ -284,3 +285,35 @@ class TestRulesFractions(RulesTestCase):
'a * 4 / 5', 'a * 4 / 5',
# FIXME: '4 / 5 * a', # 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