Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
trs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
trs
Commits
712dbdbc
Commit
712dbdbc
authored
May 17, 2012
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added rules (and tests) for sorting polynomes and monomials.
parent
464b95ee
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
36 deletions
+173
-36
src/rules/__init__.py
src/rules/__init__.py
+3
-3
src/rules/precedences.py
src/rules/precedences.py
+1
-0
src/rules/sort.py
src/rules/sort.py
+105
-22
tests/test_rules_sort.py
tests/test_rules_sort.py
+64
-11
No files found.
src/rules/__init__.py
View file @
712dbdbc
...
@@ -14,7 +14,7 @@ from .fractions import match_constant_division, match_add_fractions, \
...
@@ -14,7 +14,7 @@ from .fractions import match_constant_division, match_add_fractions, \
match_extract_fraction_terms
,
match_division_in_denominator
match_extract_fraction_terms
,
match_division_in_denominator
from
.negation
import
match_negated_factor
,
match_negate_polynome
,
\
from
.negation
import
match_negated_factor
,
match_negate_polynome
,
\
match_negated_division
match_negated_division
from
.sort
import
match_sort_polynome
,
match_sort_mo
linome
from
.sort
import
match_sort_polynome
,
match_sort_mo
nomial
from
.goniometry
import
match_add_quadrants
,
match_negated_parameter
,
\
from
.goniometry
import
match_add_quadrants
,
match_negated_parameter
,
\
match_half_pi_subtraction
,
match_standard_radian
match_half_pi_subtraction
,
match_standard_radian
from
.derivatives
import
match_zero_derivative
,
\
from
.derivatives
import
match_zero_derivative
,
\
...
@@ -36,11 +36,11 @@ from .sqrt import match_reduce_sqrt
...
@@ -36,11 +36,11 @@ from .sqrt import match_reduce_sqrt
RULES
=
{
RULES
=
{
OP_ADD
:
[
match_add_numerics
,
match_add_fractions
,
OP_ADD
:
[
match_add_numerics
,
match_add_fractions
,
match_combine_groups
,
match_add_quadrants
,
match_combine_groups
,
match_add_quadrants
,
match_add_logarithms
],
match_add_logarithms
,
match_sort_polynome
],
OP_MUL
:
[
match_multiply_numerics
,
match_expand
,
match_add_exponents
,
OP_MUL
:
[
match_multiply_numerics
,
match_expand
,
match_add_exponents
,
match_multiply_zero
,
match_negated_factor
,
match_multiply_zero
,
match_negated_factor
,
match_multiply_fractions
,
match_factor_in_multiplicant
,
match_multiply_fractions
,
match_factor_in_multiplicant
,
match_sort_mo
linome
],
match_sort_mo
nomial
],
OP_DIV
:
[
match_subtract_exponents
,
match_divide_numerics
,
OP_DIV
:
[
match_subtract_exponents
,
match_divide_numerics
,
match_constant_division
,
match_divide_fractions
,
match_constant_division
,
match_divide_fractions
,
match_negated_division
,
match_extract_fraction_terms
,
match_negated_division
,
match_extract_fraction_terms
,
...
...
src/rules/precedences.py
View file @
712dbdbc
...
@@ -98,4 +98,5 @@ IMPLICIT_RULES = [
...
@@ -98,4 +98,5 @@ IMPLICIT_RULES = [
remove_power_of_one
,
remove_power_of_one
,
negated_factor
,
negated_factor
,
add_numerics
,
add_numerics
,
swap_factors
,
]
]
src/rules/sort.py
View file @
712dbdbc
from
.utils
import
iter_pairs
from
.utils
import
iter_pairs
,
evals_to_numeric
from
..node
import
ExpressionNode
as
N
,
Scope
,
OP_ADD
,
OP_MUL
from
..node
import
ExpressionNode
as
N
,
Scope
,
OP_ADD
,
OP_MUL
from
..possibilities
import
Possibility
as
P
,
MESSAGES
from
..possibilities
import
Possibility
as
P
,
MESSAGES
from
..translate
import
_
from
..translate
import
_
def
swap_moni
((
left
,
right
)):
def
get_power_prop
(
node
):
left_num
,
right_num
=
left
.
is_numeric
(),
right
.
is_numeric
()
"""
Get the power properties of a node needed for sorting, being the variable
name and exponent value.
"""
if
node
.
is_variable
():
return
node
.
value
,
1
if
left_num
and
right_num
:
if
node
.
is_power
():
return
False
root
,
exponent
=
node
if
root
.
is_variable
():
if
exponent
.
is_numeric
():
# Numeric exponent: value can be compared to other exponents
exp
=
exponent
.
actual_value
()
else
:
# No numeric exponent: same precedence as the variable itself
exp
=
1
return
root
.
value
,
exp
def
swap_mono
((
left
,
right
)):
"""
Check if a pair of left and right multiplication factors in a monomial
should be swapped to be correctly sorted.
"""
# Numerics should always be on the left of a monomial
if
evals_to_numeric
(
right
):
return
not
evals_to_numeric
(
left
)
left_prop
=
get_power_prop
(
left
)
right_prop
=
get_power_prop
(
right
)
if
left_prop
and
right_prop
:
left_var
,
left_exp
=
left_prop
right_var
,
right_exp
=
right_prop
if
left_var
==
right_var
:
# Same variable, compare exponents
return
left_exp
>
right_exp
# Compare variable names alphabetically
return
left_var
>
right_var
return
False
def
get_poly_prop
(
node
):
"""
Get the polynome properties of an monomial in a polynome, being the leading
variable name and the exponent it is raised to.
"""
if
node
.
is_op
(
OP_MUL
):
scope
=
Scope
(
node
)
power
=
None
left_var
,
right_var
=
left
.
is_variable
(),
right
.
is_variable
()
for
n
in
scope
:
new_power
=
get_power_prop
(
n
)
if
left_var
and
right_var
:
if
new_power
:
return
cmp
(
left
.
value
,
right
.
value
)
if
not
power
:
var
,
exp
=
power
=
new_power
continue
if
left_var
and
right_num
:
new_var
,
new_exp
=
new_power
return
True
if
(
new_exp
>
exp
if
new_var
==
var
else
new_var
<
var
):
var
,
exp
=
power
=
new_power
return
power
return
get_power_prop
(
node
)
def
swap_poly
((
left
,
right
)):
def
swap_poly
((
left
,
right
)):
pass
"""
Check if a pair of left and right addition factors in a polynomial should
be swapped to be correctly sorted.
"""
left_poly
=
get_poly_prop
(
left
)
right_poly
=
get_poly_prop
(
right
)
if
not
left_poly
:
return
bool
(
right_poly
)
elif
not
right_poly
:
return
False
def
match_sort_polynome
(
node
):
left_var
,
left_exp
=
left_poly
right_var
,
right_exp
=
right_poly
if
left_var
==
right_var
:
# Same variable, compare exponents
return
left_exp
<
right_exp
# Compare variable names alphabetically
return
left_var
>
right_var
def
match_sort_monomial
(
node
):
"""
"""
Sort a monomial, pursuing the following form:
x^0 * x^1 * ... * x^n
For example: 2xx^2
"""
"""
assert
node
.
is_op
(
OP_
ADD
)
assert
node
.
is_op
(
OP_
MUL
)
scope
=
Scope
(
node
)
scope
=
Scope
(
node
)
return
[
P
(
node
,
swap_factors
,
(
scope
,
l
,
r
))
return
[
P
(
node
,
swap_factors
,
(
scope
,
l
,
r
))
for
l
,
r
in
filter
(
swap_
poly
,
iter_pairs
(
scope
))]
for
l
,
r
in
filter
(
swap_
mono
,
iter_pairs
(
scope
))]
def
match_sort_
moli
nome
(
node
):
def
match_sort_
poly
nome
(
node
):
"""
"""
x * 2 -> 2x # variable > number
Sort a polynome, pursuing the following form:
x ^ 2 * x ^ 3 -> x ^ 3 * x ^ 2 # exponents
c_n * x^n * ... * c_1 * x^1 * c_0 * x^0
yx -> xy # alphabetically
For example: 2x^2 + x - 3
"""
"""
assert
node
.
is_op
(
OP_
MUL
)
assert
node
.
is_op
(
OP_
ADD
)
scope
=
Scope
(
node
)
scope
=
Scope
(
node
)
return
[
P
(
node
,
swap_factors
,
(
scope
,
l
,
r
))
return
[
P
(
node
,
swap_factors
,
(
scope
,
l
,
r
))
for
l
,
r
in
filter
(
swap_
moni
,
iter_pairs
(
scope
))]
for
l
,
r
in
filter
(
swap_
poly
,
iter_pairs
(
scope
))]
def
swap_factors
(
root
,
args
):
def
swap_factors
(
root
,
args
):
"""
"""
left * right
f * g -> g * f
"""
"""
scope
,
left
,
right
=
args
scope
,
left
,
right
=
args
...
@@ -60,4 +143,4 @@ def swap_factors(root, args):
...
@@ -60,4 +143,4 @@ def swap_factors(root, args):
return
scope
.
as_nary_node
()
return
scope
.
as_nary_node
()
MESSAGES
[
swap_factors
]
=
_
(
'Move {
2} to the left of {1
}.'
)
MESSAGES
[
swap_factors
]
=
_
(
'Move {
3} to the left of {2
}.'
)
tests/test_rules_sort.py
View file @
712dbdbc
from
src.rules.sort
import
match_sort_polynome
,
swap_factors
,
\
from
src.rules.sort
import
match_sort_polynome
,
swap_factors
,
get_poly_prop
,
\
match_sort_mo
linome
,
iter_pairs
match_sort_mo
nomial
,
iter_pairs
,
swap_mono
,
swap_poly
,
get_power_prop
from
src.node
import
Scope
from
src.node
import
Scope
from
src.possibilities
import
Possibility
as
P
from
src.possibilities
import
Possibility
as
P
from
tests.rulestestcase
import
RulesTestCase
,
tree
from
tests.rulestestcase
import
RulesTestCase
,
tree
...
@@ -7,21 +7,74 @@ from tests.rulestestcase import RulesTestCase, tree
...
@@ -7,21 +7,74 @@ from tests.rulestestcase import RulesTestCase, tree
class
TestRulesSort
(
RulesTestCase
):
class
TestRulesSort
(
RulesTestCase
):
def
test_match_sort_molinome_constant
(
self
):
def
test_swap_mono
(
self
):
self
.
assertTrue
(
swap_mono
(
tree
(
'x, 1 / 2'
)))
self
.
assertFalse
(
swap_mono
(
tree
(
'2, 1 / 2'
)))
self
.
assertTrue
(
swap_mono
(
tree
(
'x, 2'
)))
self
.
assertFalse
(
swap_mono
(
tree
(
'2, x'
)))
self
.
assertTrue
(
swap_mono
(
tree
(
'x ^ 2, 2'
)))
self
.
assertTrue
(
swap_mono
(
tree
(
'y, x'
)))
self
.
assertFalse
(
swap_mono
(
tree
(
'x, y'
)))
self
.
assertFalse
(
swap_mono
(
tree
(
'x, x'
)))
self
.
assertTrue
(
swap_mono
(
tree
(
'x ^ 3, x ^ 2'
)))
self
.
assertFalse
(
swap_mono
(
tree
(
'x ^ 2, x ^ 3'
)))
def
test_swap_poly
(
self
):
self
.
assertTrue
(
swap_poly
(
tree
(
'2, x'
)))
self
.
assertFalse
(
swap_poly
(
tree
(
'x, 2'
)))
self
.
assertTrue
(
swap_poly
(
tree
(
'a, a^2'
)))
self
.
assertFalse
(
swap_poly
(
tree
(
'a^2, a'
)))
self
.
assertTrue
(
swap_poly
(
tree
(
'y, x'
)))
self
.
assertFalse
(
swap_poly
(
tree
(
'x, y'
)))
self
.
assertFalse
(
swap_poly
(
tree
(
'x, x'
)))
self
.
assertFalse
(
swap_poly
(
tree
(
'x ^ 3, x ^ 2'
)))
self
.
assertTrue
(
swap_poly
(
tree
(
'x ^ 2, x ^ 3'
)))
def
test_get_power_prop
(
self
):
self
.
assertEqual
(
get_power_prop
(
tree
(
'a'
)),
(
'a'
,
1
))
self
.
assertEqual
(
get_power_prop
(
tree
(
'a ^ b'
)),
(
'a'
,
1
))
self
.
assertEqual
(
get_power_prop
(
tree
(
'a ^ 2'
)),
(
'a'
,
2
))
self
.
assertEqual
(
get_power_prop
(
tree
(
'a ^ -2'
)),
(
'a'
,
-
2
))
self
.
assertIsNone
(
get_power_prop
(
tree
(
'1'
)))
def
test_get_poly_prop
(
self
):
self
.
assertEqual
(
get_poly_prop
(
tree
(
'a ^ 2'
)),
(
'a'
,
2
))
self
.
assertEqual
(
get_poly_prop
(
tree
(
'2a ^ 2'
)),
(
'a'
,
2
))
self
.
assertEqual
(
get_poly_prop
(
tree
(
'ca ^ 2 * 2'
)),
(
'a'
,
2
))
self
.
assertEqual
(
get_poly_prop
(
tree
(
'ab ^ 2'
)),
(
'a'
,
1
))
self
.
assertEqual
(
get_poly_prop
(
tree
(
'a^3 * a^2'
)),
(
'a'
,
3
))
self
.
assertEqual
(
get_poly_prop
(
tree
(
'a^2 * a^3'
)),
(
'a'
,
3
))
self
.
assertIsNone
(
get_poly_prop
(
tree
(
'1'
)))
def
test_match_sort_monomial_constant
(
self
):
x
,
l2
=
root
=
tree
(
'x * 2'
)
x
,
l2
=
root
=
tree
(
'x * 2'
)
self
.
assertEqualPos
(
match_sort_mo
linome
(
root
),
self
.
assertEqualPos
(
match_sort_mo
nomial
(
root
),
[
P
(
root
,
swap_factors
,
(
Scope
(
root
),
x
,
l2
))])
[
P
(
root
,
swap_factors
,
(
Scope
(
root
),
x
,
l2
))])
root
=
tree
(
'2x'
)
root
=
tree
(
'2x'
)
self
.
assertEqualPos
(
match_sort_molinome
(
root
),
[])
self
.
assertEqualPos
(
match_sort_monomial
(
root
),
[])
def
test_match_sort_monomial_variables
(
self
):
y
,
x
=
root
=
tree
(
'yx'
)
self
.
assertEqualPos
(
match_sort_monomial
(
root
),
[
P
(
root
,
swap_factors
,
(
Scope
(
root
),
y
,
x
))])
root
=
tree
(
'xy'
)
self
.
assertEqualPos
(
match_sort_monomial
(
root
),
[])
#def test_match_sort_molinome_variables
(self):
def
test_match_sort_polynome
(
self
):
# y, x = root = tree('yx
')
x
,
x2
=
root
=
tree
(
'x + x ^ 2
'
)
# self.assertEqualPos(match_sort_moli
nome(root),
self
.
assertEqualPos
(
match_sort_poly
nome
(
root
),
# [P(root, swap_factors, (Scope(root), y, x
))])
[
P
(
root
,
swap_factors
,
(
Scope
(
root
),
x
,
x2
))])
# root = tree('xy
')
root
=
tree
(
'x + 2
'
)
# self.assertEqualPos(match_sort_moli
nome(root), [])
self
.
assertEqualPos
(
match_sort_poly
nome
(
root
),
[])
def
test_swap_factors
(
self
):
def
test_swap_factors
(
self
):
x
,
l2
=
root
=
tree
(
'x * 2'
)
x
,
l2
=
root
=
tree
(
'x * 2'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment