Commit 57dba53e authored by Taddeus Kroes's avatar Taddeus Kroes

Applied negation checks to some fraction rules.

parent 4f0defbd
...@@ -2,7 +2,7 @@ from itertools import combinations, product ...@@ -2,7 +2,7 @@ from itertools import combinations, product
from .utils import least_common_multiple, partition from .utils import least_common_multiple, partition
from ..node import ExpressionLeaf as L, Scope, negate, OP_DIV, OP_ADD, \ from ..node import ExpressionLeaf as L, Scope, negate, OP_DIV, OP_ADD, \
OP_MUL, nary_node OP_MUL, nary_node, negate
from ..possibilities import Possibility as P, MESSAGES from ..possibilities import Possibility as P, MESSAGES
from ..translate import _ from ..translate import _
...@@ -255,9 +255,9 @@ def match_equal_fraction_parts(node): ...@@ -255,9 +255,9 @@ def match_equal_fraction_parts(node):
# Look for in scope # Look for in scope
for i, n in enumerate(n_scope): for i, n in enumerate(n_scope):
for j, d in enumerate(d_scope): for j, d in enumerate(d_scope):
if n == d: if n.equals(d, ignore_negation=True):
p.append(P(node, divide_fraction_parts, p.append(P(node, divide_fraction_parts,
(n, n_scope, d_scope, i, j))) (negate(n, 0), n_scope, d_scope, i, j)))
return p return p
...@@ -270,9 +270,11 @@ def divide_fraction_parts(root, args): ...@@ -270,9 +270,11 @@ def divide_fraction_parts(root, args):
ab / (ac) -> b / c ab / (ac) -> b / c
ab / a -> b / 1 ab / a -> b / 1
a / (ab) -> 1 / b a / (ab) -> 1 / b
-ab / a -> -b / 1
""" """
a, n_scope, d_scope, i, j = args a, n_scope, d_scope, i, j = args
n, d = root n, d = root
a_n, a_d = n_scope[i], d_scope[j]
del n_scope[i] del n_scope[i]
del d_scope[j] del d_scope[j]
...@@ -294,7 +296,9 @@ def divide_fraction_parts(root, args): ...@@ -294,7 +296,9 @@ def divide_fraction_parts(root, args):
else: else:
denom = nary_node('*', d_scope) denom = nary_node('*', d_scope)
return nom.negate(n.negated) / denom.negate(d.negated) # Move negation of removed part to nominator and denominator
return nom.negate(n.negated + a_n.negated) \
/ denom.negate(d.negated + a_d.negated)
MESSAGES[divide_fraction_parts] = \ MESSAGES[divide_fraction_parts] = \
......
...@@ -108,7 +108,7 @@ def match_divide_numerics(node): ...@@ -108,7 +108,7 @@ def match_divide_numerics(node):
if not mod: if not mod:
# 6 / 2 -> 3 # 6 / 2 -> 3
# 3 / 2 -> 3 / 2 # 3 / 2 -> 3 / 2
return [P(node, divide_numerics, (nv, dv))] return [P(node, divide_numerics, (nv, dv, n.negated + d.negated))]
gcd = greatest_common_divisor(nv, dv) gcd = greatest_common_divisor(nv, dv)
...@@ -130,7 +130,7 @@ def match_divide_numerics(node): ...@@ -130,7 +130,7 @@ def match_divide_numerics(node):
# 3.0 / 2 -> 1.5 # 3.0 / 2 -> 1.5
# 3 / 2.0 -> 1.5 # 3 / 2.0 -> 1.5
# 3.0 / 2.0 -> 1.5 # 3.0 / 2.0 -> 1.5
return [P(node, divide_numerics, (nv, dv))] return [P(node, divide_numerics, (nv, dv, n.negated + d.negated))]
return [] return []
...@@ -146,9 +146,9 @@ def divide_numerics(root, args): ...@@ -146,9 +146,9 @@ def divide_numerics(root, args):
3.0 / 2.0 -> 1.5 3.0 / 2.0 -> 1.5
3 / 1.0 -> 3 3 / 1.0 -> 3
""" """
n, d = args n, d, negated = args
return Leaf(n / d) return Leaf(n / d).negate(negated)
MESSAGES[divide_numerics] = _('Divide constant {1} by constant {2}.') MESSAGES[divide_numerics] = _('Divide constant {1} by constant {2}.')
......
...@@ -167,6 +167,10 @@ class TestRulesFractions(RulesTestCase): ...@@ -167,6 +167,10 @@ class TestRulesFractions(RulesTestCase):
P(root, divide_fraction_parts, (b, s0, s1, 1, 1)), P(root, divide_fraction_parts, (b, s0, s1, 1, 1)),
P(root, divide_fraction_parts, (c, s0, s1, 2, 0))]) P(root, divide_fraction_parts, (c, s0, s1, 2, 0))])
root = tree('-a / a')
self.assertEqualPos(match_equal_fraction_parts(root),
[P(root, divide_fraction_parts, (a, [-a], [a], 0, 0))])
def test_divide_fraction_parts(self): def test_divide_fraction_parts(self):
(a, b), (c, a) = root = tree('ab / (ca)') (a, b), (c, a) = root = tree('ab / (ca)')
result = divide_fraction_parts(root, (a, [a, b], [c, a], 0, 1)) result = divide_fraction_parts(root, (a, [a, b], [c, a], 0, 1))
...@@ -189,3 +193,7 @@ class TestRulesFractions(RulesTestCase): ...@@ -189,3 +193,7 @@ class TestRulesFractions(RulesTestCase):
self.assertEqual(result, a * c / (c * a)) self.assertEqual(result, a * c / (c * a))
result = divide_fraction_parts(root, (c, [a, b, c], [c, b, a], 2, 0)) result = divide_fraction_parts(root, (c, [a, b, c], [c, b, a], 2, 0))
self.assertEqual(result, a * b / (b * a)) self.assertEqual(result, a * b / (b * a))
(a, b), a = root = tree('-ab / a')
result = divide_fraction_parts(root, (a, [-a, b], [a], 0, 0))
self.assertEqual(result, -b / 1)
...@@ -43,7 +43,12 @@ class TestRulesNumerics(RulesTestCase): ...@@ -43,7 +43,12 @@ class TestRulesNumerics(RulesTestCase):
root = i6 / i2 root = i6 / i2
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, divide_numerics, (6, 2))]) [P(root, divide_numerics, (6, 2, 0))])
root = -i6 / i2
possibilities = match_divide_numerics(root)
self.assertEqualPos(possibilities,
[P(root, divide_numerics, (6, 2, 1))])
root = i3 / i2 root = i3 / i2
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
...@@ -58,22 +63,22 @@ class TestRulesNumerics(RulesTestCase): ...@@ -58,22 +63,22 @@ class TestRulesNumerics(RulesTestCase):
root = f3 / i2 root = f3 / i2
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, divide_numerics, (3.0, 2))]) [P(root, divide_numerics, (3.0, 2, 0))])
root = i3 / f2 root = i3 / f2
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, divide_numerics, (3, 2.0))]) [P(root, divide_numerics, (3, 2.0, 0))])
root = f3 / f2 root = f3 / f2
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, divide_numerics, (3.0, 2.0))]) [P(root, divide_numerics, (3.0, 2.0, 0))])
root = i3 / f1 root = i3 / f1
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, divide_numerics, (3, 1))]) [P(root, divide_numerics, (3, 1, 0))])
root = a / b root = a / b
possibilities = match_divide_numerics(root) possibilities = match_divide_numerics(root)
...@@ -82,10 +87,13 @@ class TestRulesNumerics(RulesTestCase): ...@@ -82,10 +87,13 @@ class TestRulesNumerics(RulesTestCase):
def test_divide_numerics(self): def test_divide_numerics(self):
i2, i3, i6, f2, f3 = tree('2,3,6,2.0,3.0') i2, i3, i6, f2, f3 = tree('2,3,6,2.0,3.0')
self.assertEqual(divide_numerics(i6 / i2, (6, 2)), 3) self.assertEqual(divide_numerics(i6 / i2, (6, 2, 0)), 3)
self.assertEqual(divide_numerics(f3 / i2, (3.0, 2)), 1.5) self.assertEqual(divide_numerics(f3 / i2, (3.0, 2, 0)), 1.5)
self.assertEqual(divide_numerics(i3 / f2, (3, 2.0)), 1.5) self.assertEqual(divide_numerics(i3 / f2, (3, 2.0, 0)), 1.5)
self.assertEqual(divide_numerics(f3 / f2, (3.0, 2.0)), 1.5) self.assertEqual(divide_numerics(f3 / f2, (3.0, 2.0, 0)), 1.5)
self.assertEqual(divide_numerics(i6 / i2, (6, 2, 1)), -3)
self.assertEqual(divide_numerics(i6 / i2, (6, 2, 2)), --i3)
def test_reduce_fraction_constants(self): def test_reduce_fraction_constants(self):
l1, l2 = tree('1,2') l1, l2 = tree('1,2')
......
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