Commit 150add57 authored by Sander Mathijs van Veen's avatar Sander Mathijs van Veen

Merge branch 'master' of kompiler.org:trs

parents fb84eb49 e1dd1838
...@@ -29,6 +29,17 @@ class Possibility(object): ...@@ -29,6 +29,17 @@ class Possibility(object):
def filter_duplicates(items): def filter_duplicates(items):
"""
Filter duplicated possibilities. Duplicated possibilities occur in n-ary
nodes, the root-level node and a lower-level node will both recognize a
reqrite possibility within their sscope, whereas only the root-level one
matters.
Example: 1 + 2 + 3
The addition of 1 and 2 is recognized bij n-ary additions "1 + 2" and
"1 + 2 + 3". The "1 + 2" addition should be removed by this function.
"""
# TODO: Finish according to docstrings
unique = [] unique = []
for item in items: for item in items:
......
from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW from ..node import OP_ADD, OP_MUL, OP_DIV, OP_POW
from .poly import match_combine_polynomes, match_expand from .poly import match_combine_polynomes
from .factors import match_expand
from .powers import match_add_exponents, match_subtract_exponents, \ from .powers import match_add_exponents, match_subtract_exponents, \
match_multiply_exponents, match_duplicate_exponent, \ match_multiply_exponents, match_duplicate_exponent, \
match_remove_negative_exponent, match_exponent_to_root match_remove_negative_exponent, match_exponent_to_root
......
from ..node import OP_ADD, OP_MUL
from ..possibilities import Possibility as P, MESSAGES
from .utils import nary_node
def match_expand(node):
"""
a * (b + c) -> ab + ac
"""
assert node.is_op(OP_MUL)
# TODO: fix!
return []
p = []
a = []
bc = []
for n in node.get_scope():
if n.is_leaf():
a.append(n)
elif n.op == OP_ADD:
bc.append(n)
if a and bc:
for a_node in a:
for bc_node in bc:
p.append(P(node, expand_single, a_node, bc_node))
return p
def expand_single(root, args):
"""
Combine a leaf (a) multiplied with an addition of two expressions
(b + c) to an addition of two multiplications.
>>> a * (b + c) -> a * b + a * c
"""
a, bc = args
b, c = bc
scope = root.get_scope()
# Replace 'a' with the new expression
scope[scope.index(a)] = a * b + a * c
# Remove the old addition
scope.remove(bc)
return nary_node('*', scope)
from itertools import combinations from itertools import combinations
from ..node import ExpressionNode as Node, OP_ADD, OP_MUL from ..node import OP_ADD
from ..possibilities import Possibility as P, MESSAGES from ..possibilities import Possibility as P, MESSAGES
from .utils import nary_node from .utils import nary_node
from .numerics import add_numerics from .numerics import add_numerics
def match_expand(node):
"""
a * (b + c) -> ab + ac
"""
assert node.is_op(OP_MUL)
# TODO: fix!
return []
p = []
a = []
bc = []
for n in node.get_scope():
if n.is_leaf():
a.append(n)
elif n.op == OP_ADD:
bc.append(n)
if a and bc:
for a_node in a:
for bc_node in bc:
p.append(P(node, expand_single, a_node, bc_node))
return p
def expand_single(root, args):
"""
Combine a leaf (a) multiplied with an addition of two expressions
(b + c) to an addition of two multiplications.
>>> a * (b + c) -> a * b + a * c
"""
a, bc = args
b, c = bc
scope = root.get_scope()
# Replace 'a' with the new expression
scope[scope.index(a)] = Node('+', Node('*', a, b), \
Node('*', a, c))
# Remove the old addition
scope.remove(bc)
return nary_node('*', scope)
def match_combine_polynomes(node, verbose=False): def match_combine_polynomes(node, verbose=False):
""" """
n + exp + m -> exp + (n + m) n + exp + m -> exp + (n + m)
......
from src.rules.factors import match_expand, expand_single
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase
from tests.test_rules_poly import tree
class TestRulesFactors(RulesTestCase):
def test_match_expand(self):
pass
def test_expand_single(self):
pass
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