@@ -1672,80 +1672,136 @@ def composition(self, ex, operator):
1672
1672
else :
1673
1673
return res
1674
1674
1675
- class SubstituteFunction (Converter ):
1676
- def __init__ (self , ex , original , new ):
1675
+
1676
+ class ExpressionTreeWalker (Converter ):
1677
+ def __init__ (self , ex ):
1677
1678
"""
1678
- A class that walks the tree and replaces occurrences of a
1679
- function with another.
1679
+ A class that walks the tree. Mainly for subclassing.
1680
1680
1681
1681
EXAMPLES::
1682
1682
1683
- sage: from sage.symbolic.expression_conversions import SubstituteFunction
1684
- sage: foo = function('foo'); bar = function('bar')
1685
- sage: s = SubstituteFunction(foo(x), foo, bar)
1686
- sage: s(1/foo(foo(x)) + foo(2))
1687
- 1/bar(bar(x)) + bar(2)
1683
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1684
+ sage: from sage.symbolic.random_tests import random_expr
1685
+ sage: ex = sin(atan(0,hold=True)+hypergeometric((1,),(1,),x))
1686
+ sage: s = ExpressionTreeWalker(ex)
1687
+ sage: bool(s() == ex)
1688
+ True
1689
+ sage: foo = random_expr(20, nvars=2)
1690
+ sage: s = ExpressionTreeWalker(foo)
1691
+ sage: bool(s() == foo)
1692
+ True
1688
1693
"""
1689
- self .original = original
1690
- self .new = new
1691
1694
self .ex = ex
1692
1695
1693
1696
def symbol (self , ex ):
1694
1697
"""
1695
1698
EXAMPLES::
1696
1699
1697
- sage: from sage.symbolic.expression_conversions import SubstituteFunction
1698
- sage: foo = function('foo'); bar = function('bar')
1699
- sage: s = SubstituteFunction(foo(x), foo, bar)
1700
- sage: s.symbol(x)
1701
- x
1700
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1701
+ sage: s = ExpressionTreeWalker(x)
1702
+ sage: bool(s.symbol(x) == x)
1703
+ True
1702
1704
"""
1703
1705
return ex
1704
1706
1705
1707
def pyobject (self , ex , obj ):
1706
1708
"""
1707
1709
EXAMPLES::
1708
1710
1709
- sage: from sage.symbolic.expression_conversions import SubstituteFunction
1710
- sage: foo = function('foo'); bar = function('bar')
1711
- sage: s = SubstituteFunction(foo(x), foo, bar)
1711
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1712
1712
sage: f = SR(2)
1713
- sage: s.pyobject(f, f.pyobject())
1714
- 2
1715
- sage: _.parent()
1716
- Symbolic Ring
1713
+ sage: s = ExpressionTreeWalker(f)
1714
+ sage: bool(s.pyobject(f, f.pyobject()) == f.pyobject())
1715
+ True
1717
1716
"""
1718
1717
return ex
1719
1718
1720
1719
def relation (self , ex , operator ):
1721
1720
"""
1722
1721
EXAMPLES::
1723
1722
1724
- sage: from sage.symbolic.expression_conversions import SubstituteFunction
1725
- sage: foo = function('foo'); bar = function('bar')
1726
- sage: s = SubstituteFunction(foo(x), foo, bar)
1723
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1724
+ sage: foo = function('foo')
1727
1725
sage: eq = foo(x) == x
1728
- sage: s.relation(eq, eq.operator())
1729
- bar(x) == x
1726
+ sage: s = ExpressionTreeWalker(eq)
1727
+ sage: s.relation(eq, eq.operator()) == eq
1728
+ True
1730
1729
"""
1731
1730
return operator (self (ex .lhs ()), self (ex .rhs ()))
1732
1731
1733
1732
def arithmetic (self , ex , operator ):
1734
1733
"""
1734
+ EXAMPLES::
1735
+
1736
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1737
+ sage: foo = function('foo')
1738
+ sage: f = x*foo(x) + pi/foo(x)
1739
+ sage: s = ExpressionTreeWalker(f)
1740
+ sage: bool(s.arithmetic(f, f.operator()) == f)
1741
+ True
1742
+ """
1743
+ return reduce (operator , map (self , ex .operands ()))
1744
+
1745
+ def composition (self , ex , operator ):
1746
+ """
1747
+ EXAMPLES::
1748
+
1749
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1750
+ sage: foo = function('foo')
1751
+ sage: f = foo(atan2(0, 0, hold=True))
1752
+ sage: s = ExpressionTreeWalker(f)
1753
+ sage: bool(s.composition(f, f.operator()) == f)
1754
+ True
1755
+ """
1756
+ from sage .symbolic .function import Function
1757
+ if isinstance (operator , Function ):
1758
+ return operator (* map (self , ex .operands ()), hold = True )
1759
+ else :
1760
+ return operator (* map (self , ex .operands ()))
1761
+
1762
+ def derivative (self , ex , operator ):
1763
+ """
1764
+ EXAMPLES::
1765
+
1766
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1767
+ sage: foo = function('foo')
1768
+ sage: f = foo(x).diff(x)
1769
+ sage: s = ExpressionTreeWalker(f)
1770
+ sage: bool(s.derivative(f, f.operator()) == f)
1771
+ True
1772
+ """
1773
+ return operator (* map (self , ex .operands ()))
1774
+
1775
+ def tuple (self , ex ):
1776
+ """
1777
+ EXAMPLES::
1778
+
1779
+ sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
1780
+ sage: foo = function('foo')
1781
+ sage: f = hypergeometric((1,2,3,),(x,),x)
1782
+ sage: s = ExpressionTreeWalker(f)
1783
+ sage: bool(s() == f)
1784
+ True
1785
+ """
1786
+ return ex .operands ()
1787
+
1788
+ class SubstituteFunction (ExpressionTreeWalker ):
1789
+ def __init__ (self , ex , original , new ):
1790
+ """
1791
+ A class that walks the tree and replaces occurrences of a
1792
+ function with another.
1793
+
1735
1794
EXAMPLES::
1736
1795
1737
1796
sage: from sage.symbolic.expression_conversions import SubstituteFunction
1738
1797
sage: foo = function('foo'); bar = function('bar')
1739
1798
sage: s = SubstituteFunction(foo(x), foo, bar)
1740
- sage: f = x*foo(x) + pi/foo(x)
1741
- sage: s.arithmetic(f, f.operator())
1742
- x*bar(x) + pi/bar(x)
1799
+ sage: s(1/foo(foo(x)) + foo(2))
1800
+ 1/bar(bar(x)) + bar(2)
1743
1801
"""
1744
- if operator == add_vararg :
1745
- operator = _operator .add
1746
- elif operator == mul_vararg :
1747
- operator = _operator .mul
1748
- return reduce (operator , map (self , ex .operands ()))
1802
+ self .original = original
1803
+ self .new = new
1804
+ self .ex = ex
1749
1805
1750
1806
def composition (self , ex , operator ):
1751
1807
"""
@@ -1798,3 +1854,4 @@ def derivative(self, ex, operator):
1798
1854
return operator .change_function (self .new )(* map (self ,ex .operands ()))
1799
1855
else :
1800
1856
return operator (* map (self , ex .operands ()))
1857
+
0 commit comments