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

Generalized structure of sort rules.

parent 77ae42a0
No related branches found
No related tags found
No related merge requests found
......@@ -181,6 +181,9 @@ class ExpressionBase(object):
return s_root < o_root or s_exp < o_exp or s_coeff < o_coeff
def __gt__(self, other):
return other < self
def __ne__(self, other):
"""
Check strict inequivalence, using the strict equivalence operator.
......
......@@ -14,7 +14,7 @@ from .fractions import match_constant_division, match_add_fractions, \
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
from .sort import match_sort_polynome, match_sort_molinome
from .goniometry import match_add_quadrants, match_negated_parameter, \
match_half_pi_subtraction, match_standard_radian
from .derivatives import match_zero_derivative, \
......@@ -39,8 +39,8 @@ RULES = {
match_add_logarithms],
OP_MUL: [match_multiply_numerics, match_expand, match_add_exponents,
match_multiply_zero, match_negated_factor,
match_sort_multiplicants, match_multiply_fractions,
match_factor_in_multiplicant],
match_multiply_fractions, match_factor_in_multiplicant,
match_sort_molinome],
OP_DIV: [match_subtract_exponents, match_divide_numerics,
match_constant_division, match_divide_fractions,
match_negated_division, match_extract_fraction_terms,
......
from .factors import expand_double, expand_single
from .sort import move_constant
from .sort import swap_factors
from .numerics import multiply_one, multiply_zero, reduce_fraction_constants, \
raise_numerics, remove_zero, multiply_numerics, add_numerics
from .logarithmic import factor_in_exponent_multiplicant, \
......@@ -36,7 +36,7 @@ LOW = [
# Sorting expression terms has a low priority because it is assumed to
# be handled by the user
move_constant,
swap_factors,
]
......
from ..node import Scope, OP_MUL
from .utils import iter_pairs
from ..node import ExpressionNode as N, Scope, OP_ADD, OP_MUL
from ..possibilities import Possibility as P, MESSAGES
from ..translate import _
def match_sort_multiplicants(node):
def swap_moni((left, right)):
left_num, right_num = left.is_numeric(), right.is_numeric()
if left_num and right_num:
return False
left_var, right_var = left.is_variable(), right.is_variable()
if left_var and right_var:
return cmp(left.value, right.value)
if left_var and right_num:
return True
def swap_poly((left, right)):
pass
def match_sort_polynome(node):
"""
Sort multiplicant factors by swapping
x * 2 -> 2x
"""
assert node.is_op(OP_MUL)
assert node.is_op(OP_ADD)
p = []
scope = Scope(node)
for i, n in enumerate(scope[1:]):
left_nb = scope[i]
return [P(node, swap_factors, (scope, l, r))
for l, r in filter(swap_poly, iter_pairs(scope))]
if n.is_numeric() and not left_nb.is_numeric():
p.append(P(node, move_constant, (scope, n, left_nb)))
return p
def match_sort_molinome(node):
"""
x * 2 -> 2x # variable > number
x ^ 2 * x ^ 3 -> x ^ 3 * x ^ 2 # exponents
yx -> xy # alphabetically
"""
assert node.is_op(OP_MUL)
scope = Scope(node)
return [P(node, swap_factors, (scope, l, r))
for l, r in filter(swap_moni, iter_pairs(scope))]
def move_constant(root, args):
scope, constant, destination = args
def swap_factors(root, args):
"""
left * right
"""
scope, left, right = args
scope.replace(destination, constant * destination)
scope.remove(constant)
scope.replace(left, N(root.op, right, left))
scope.remove(right)
return scope.as_nary_node()
MESSAGES[move_constant] = \
_('Move constant {2} to the left of the multiplication {0}.')
MESSAGES[swap_factors] = _('Move {2} to the left of {1}.')
from src.rules.sort import match_sort_multiplicants, move_constant
from src.rules.sort import match_sort_polynome, swap_factors, \
match_sort_molinome, iter_pairs
from src.node import Scope
from src.possibilities import Possibility as P
from tests.rulestestcase import RulesTestCase, tree
......@@ -6,13 +7,23 @@ from tests.rulestestcase import RulesTestCase, tree
class TestRulesSort(RulesTestCase):
def test_match_sort_multiplicants(self):
def test_match_sort_molinome_constant(self):
x, l2 = root = tree('x * 2')
possibilities = match_sort_multiplicants(root)
self.assertEqualPos(possibilities,
[P(root, move_constant, (Scope(root), l2, x))])
self.assertEqualPos(match_sort_molinome(root),
[P(root, swap_factors, (Scope(root), x, l2))])
def test_move_constant(self):
root = tree('2x')
self.assertEqualPos(match_sort_molinome(root), [])
#def test_match_sort_molinome_variables(self):
# y, x = root = tree('yx')
# self.assertEqualPos(match_sort_molinome(root),
# [P(root, swap_factors, (Scope(root), y, x))])
# root = tree('xy')
# self.assertEqualPos(match_sort_molinome(root), [])
def test_swap_factors(self):
x, l2 = root = tree('x * 2')
self.assertEqualNodes(move_constant(root, (Scope(root), l2, x)),
self.assertEqualNodes(swap_factors(root, (Scope(root), x, l2)),
l2 * x)
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