|
@@ -192,73 +192,58 @@ def match_multiply_zero(node):
|
|
|
return []
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
-def multiply_zero(root, args):
|
|
|
|
|
|
|
+def match_multiply_numerics(node):
|
|
|
"""
|
|
"""
|
|
|
- a * 0 -> 0
|
|
|
|
|
- 0 * a -> 0
|
|
|
|
|
- -0 * a -> -0
|
|
|
|
|
- 0 * -a -> -0
|
|
|
|
|
- -0 * -a -> 0
|
|
|
|
|
|
|
+ 3 * 2 -> 6
|
|
|
|
|
+ 3.0 * 2 -> 6.0
|
|
|
|
|
+ 3 * 2.0 -> 6.0
|
|
|
|
|
+ 3.0 * 2.0 -> 6.0
|
|
|
"""
|
|
"""
|
|
|
- return negate(Leaf(0), args[0])
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-MESSAGES[multiply_zero] = _('Multiplication with zero yields zero.')
|
|
|
|
|
|
|
+ assert node.is_op(OP_MUL)
|
|
|
|
|
|
|
|
|
|
+ p = []
|
|
|
|
|
+ scope = Scope(node)
|
|
|
|
|
+ numerics = filter(lambda n: n.is_numeric(), scope)
|
|
|
|
|
|
|
|
-def match_multiply_one(node):
|
|
|
|
|
- """
|
|
|
|
|
- a * 1 -> a
|
|
|
|
|
- 1 * a -> a
|
|
|
|
|
- -1 * a -> -a
|
|
|
|
|
- 1 * -a -> -a
|
|
|
|
|
- -1 * -a -> a
|
|
|
|
|
- """
|
|
|
|
|
- assert node.is_op(OP_MUL)
|
|
|
|
|
|
|
+ for n in numerics:
|
|
|
|
|
+ if n.negated:
|
|
|
|
|
+ continue
|
|
|
|
|
|
|
|
- left, right = node
|
|
|
|
|
|
|
+ if n.value == 0:
|
|
|
|
|
+ p.append(P(node, multiply_zero, (n,)))
|
|
|
|
|
|
|
|
- if left.value == 1:
|
|
|
|
|
- return [P(node, multiply_one, (right, left))]
|
|
|
|
|
|
|
+ if n.value == 1:
|
|
|
|
|
+ p.append(P(node, multiply_one, (scope, n)))
|
|
|
|
|
|
|
|
- if right.value == 1:
|
|
|
|
|
- return [P(node, multiply_one, (left, right))]
|
|
|
|
|
|
|
+ for c0, c1 in combinations(numerics, 2):
|
|
|
|
|
+ p.append(P(node, multiply_numerics, (scope, c0, c1)))
|
|
|
|
|
|
|
|
- return []
|
|
|
|
|
|
|
+ return p
|
|
|
|
|
|
|
|
|
|
|
|
|
-def multiply_one(root, args):
|
|
|
|
|
|
|
+def multiply_zero(root, args):
|
|
|
"""
|
|
"""
|
|
|
- a * 1 -> a
|
|
|
|
|
- 1 * a -> a
|
|
|
|
|
- -1 * a -> -a
|
|
|
|
|
- 1 * -a -> -a
|
|
|
|
|
- -1 * -a -> a
|
|
|
|
|
|
|
+ 0 * a -> 0
|
|
|
|
|
+ -0 * a -> -0
|
|
|
"""
|
|
"""
|
|
|
- a, one = args
|
|
|
|
|
- return a.negate(one.negated + root.negated)
|
|
|
|
|
|
|
+ return args[0].negate(root.negated)
|
|
|
|
|
|
|
|
|
|
|
|
|
-MESSAGES[multiply_one] = _('Multiplication with one yields the multiplicant.')
|
|
|
|
|
|
|
+MESSAGES[multiply_zero] = _('Multiplication with zero yields zero.')
|
|
|
|
|
|
|
|
|
|
|
|
|
-def match_multiply_numerics(node):
|
|
|
|
|
|
|
+def multiply_one(root, args):
|
|
|
"""
|
|
"""
|
|
|
- 3 * 2 -> 6
|
|
|
|
|
- 3.0 * 2 -> 6.0
|
|
|
|
|
- 3 * 2.0 -> 6.0
|
|
|
|
|
- 3.0 * 2.0 -> 6.0
|
|
|
|
|
|
|
+ 1 * a -> a
|
|
|
|
|
+ -1 * a -> -a
|
|
|
"""
|
|
"""
|
|
|
- assert node.is_op(OP_MUL)
|
|
|
|
|
|
|
+ scope, one = args
|
|
|
|
|
+ scope.remove(one)
|
|
|
|
|
|
|
|
- p = []
|
|
|
|
|
- scope = Scope(node)
|
|
|
|
|
- numerics = filter(lambda n: n.is_numeric(), scope)
|
|
|
|
|
|
|
+ return scope.as_nary_node().negate(one.negated)
|
|
|
|
|
|
|
|
- for c0, c1 in combinations(numerics, 2):
|
|
|
|
|
- p.append(P(node, multiply_numerics, (scope, c0, c1)))
|
|
|
|
|
|
|
|
|
|
- return p
|
|
|
|
|
|
|
+MESSAGES[multiply_one] = _('Multiplication with one yields the multiplicant.')
|
|
|
|
|
|
|
|
|
|
|
|
|
def multiply_numerics(root, args):
|
|
def multiply_numerics(root, args):
|