Commit 6843d12e authored by Taddeus Kroes's avatar Taddeus Kroes

Added numeric rules in separate file.

- Moved combine_numerics to new rules file and renamed it to add_numerics.
- Added (match_)divide_numerics that checks if numbers can be divided without
  losing precision.
parent ad790a21
from itertools import combinations from itertools import combinations
from ..node import ExpressionNode as Node, ExpressionLeaf as Leaf, \ from ..node import ExpressionNode as Node, ExpressionLeaf as Leaf, \
TYPE_OPERATOR, OP_ADD, OP_MUL OP_ADD, OP_MUL
from ..possibilities import Possibility as P from ..possibilities import Possibility as P
from .utils import nary_node from .utils import nary_node
from .numerics import add_numerics
def match_expand(node): def match_expand(node):
""" """
a * (b + c) -> ab + ac a * (b + c) -> ab + ac
""" """
assert node.type == TYPE_OPERATOR assert node.is_op(OP_MUL)
assert node.op == OP_MUL
# TODO: fix! # TODO: fix!
return [] return []
...@@ -60,8 +60,7 @@ def match_combine_polynomes(node, verbose=False): ...@@ -60,8 +60,7 @@ def match_combine_polynomes(node, verbose=False):
n + exp + m -> exp + (n + m) n + exp + m -> exp + (n + m)
k0 * v ^ n + exp + k1 * v ^ n -> exp + (k0 + k1) * v ^ n k0 * v ^ n + exp + k1 * v ^ n -> exp + (k0 + k1) * v ^ n
""" """
assert node.type == TYPE_OPERATOR assert node.is_op(OP_ADD)
assert node.op == OP_ADD
p = [] p = []
...@@ -101,7 +100,7 @@ def match_combine_polynomes(node, verbose=False): ...@@ -101,7 +100,7 @@ def match_combine_polynomes(node, verbose=False):
if c0 == 1 and c1 == 1 and e0 == 1 and e1 == 1 \ if c0 == 1 and c1 == 1 and e0 == 1 and e1 == 1 \
and r0.is_numeric() and r1.is_numeric(): and r0.is_numeric() and r1.is_numeric():
# 2 + 3 -> 5 # 2 + 3 -> 5
p.append(P(node, combine_numerics, (n0, n1, r0.value, r1.value))) p.append(P(node, add_numerics, (n0, n1, r0.value, r1.value)))
elif c0.is_numeric() and c1.is_numeric() and r0 == r1 and e0 == e1: elif c0.is_numeric() and c1.is_numeric() and r0 == r1 and e0 == e1:
# 2a + 2a -> 4a # 2a + 2a -> 4a
# a + 2a -> 3a # a + 2a -> 3a
...@@ -112,26 +111,6 @@ def match_combine_polynomes(node, verbose=False): ...@@ -112,26 +111,6 @@ def match_combine_polynomes(node, verbose=False):
return p return p
def combine_numerics(root, args):
"""
Combine two constants to a single constant in an n-ary plus.
Synopsis:
c0 + c1 -> eval(c1 + c2)
"""
n0, n1, c0, c1 = args
scope = root.get_scope()
# Replace the left node with the new expression
scope[scope.index(n0)] = Leaf(c0 + c1)
# Remove the right node
scope.remove(n1)
return nary_node('+', scope)
def combine_polynomes(root, args): def combine_polynomes(root, args):
""" """
Combine two multiplications of any polynome in an n-ary plus. Combine two multiplications of any polynome in an n-ary plus.
......
from src.rules.poly import match_combine_polynomes, combine_polynomes, \ from src.rules.poly import match_combine_polynomes, combine_polynomes
combine_numerics from src.rules.numerics import add_numerics
from src.possibilities import Possibility as P from src.possibilities import Possibility as P
from src.node import ExpressionLeaf as L from src.node import ExpressionLeaf as L
from src.parser import Parser from src.parser import Parser
...@@ -76,34 +76,25 @@ class TestRulesPoly(RulesTestCase): ...@@ -76,34 +76,25 @@ class TestRulesPoly(RulesTestCase):
#self.assertEqualPos(possibilities, #self.assertEqualPos(possibilities,
# [P(root, combine_polynomes, (left, right, c, c, a_b, d))]) # [P(root, combine_polynomes, (left, right, c, c, a_b, d))])
def test_match_combine_numerics(self): def test_match_add_numerics(self):
l0, l1, l2 = tree('0,1,2') l0, l1, l2 = tree('0,1,2')
root = l0 + l1 + l2 root = l0 + l1 + l2
possibilities = match_combine_polynomes(root) possibilities = match_combine_polynomes(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, combine_numerics, (l0, l1, l0, l1)), [P(root, add_numerics, (l0, l1, l0, l1)),
P(root, combine_numerics, (l0, l2, l0, l2)), P(root, add_numerics, (l0, l2, l0, l2)),
P(root, combine_numerics, (l1, l2, l1, l2))]) P(root, add_numerics, (l1, l2, l1, l2))])
def test_match_combine_numerics_explicit_powers(self): def test_match_add_numerics_explicit_powers(self):
l0, l1, l2 = tree('0^1,1*1,1*2^1') l0, l1, l2 = tree('0^1,1*1,1*2^1')
root = l0 + l1 + l2 root = l0 + l1 + l2
possibilities = match_combine_polynomes(root) possibilities = match_combine_polynomes(root)
self.assertEqualPos(possibilities, self.assertEqualPos(possibilities,
[P(root, combine_numerics, (l0, l1, l0[0], l1[1])), [P(root, add_numerics, (l0, l1, l0[0], l1[1])),
P(root, combine_numerics, (l0, l2, l0[0], l2[1][0])), P(root, add_numerics, (l0, l2, l0[0], l2[1][0])),
P(root, combine_numerics, (l1, l2, l1[1], l2[1][0]))]) P(root, add_numerics, (l1, l2, l1[1], l2[1][0]))])
def test_combine_numerics(self):
l0, l1 = tree('1,2')
self.assertEqual(combine_numerics(l0 + l1, (l0, l1, 1, 2)), 3)
def test_combine_numerics_nary(self):
l0, a, l1 = tree('1,a,2')
self.assertEqual(combine_numerics(l0 + a + l1, (l0, l1, 1, 2)),
L(3) + a)
def test_combine_polynomes(self): def test_combine_polynomes(self):
# 2a + 3a -> (2 + 3) * a # 2a + 3a -> (2 + 3) * a
......
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