Python 统一表达式仅在树的顶部节点上匹配

Python 统一表达式仅在树的顶部节点上匹配,python,python-3.x,sympy,Python,Python 3.x,Sympy,我决定改变三角恒等式 通过重写unify将其转换为函数。所以 >>> trig_rule_tan = rewriterule(1 + tan(x)**2, sec(x)**2, [x]) >>> trig_rule_tan(1 + tan(x)**2).next() 我得到 但是,由于unification的精确模式匹配,我只能在表达式树的最顶层节点中找到这个函数模式。例如: >>> list(trig_rule_tan(2 + (1

我决定改变三角恒等式

通过重写
unify
将其转换为函数。所以

>>> trig_rule_tan = rewriterule(1 + tan(x)**2, sec(x)**2, [x])
>>> trig_rule_tan(1 + tan(x)**2).next()
我得到

但是,由于unification的精确模式匹配,我只能在表达式树的最顶层节点中找到这个函数模式。例如:

>>> list(trig_rule_tan(2 + (1 + tan(x)**2)))
没有匹配项


如何在较大的表达式树中将模式映射与具有重写规则的函数相匹配?

堆栈是匹配括号的好方法。这里我提供了一些用于堆栈和括号匹配的代码

class stacked(): # Nodes in the stack
    def __init__(self,obj,next):
        self.obj = obj
        self.next = next
    def getObj(self):
        return(self.obj)
    def getNext(self):
        return(self.next)

class stack(): # The stack itself
    def __init__(self):
        self.top=None
    def push(self,obj):
        self.top = stacked(obj,self.top)
    def pop(self):
        if(self.top == None):
            return(None)
        r = self.top.getObj()
        self.top = self.top.getNext()
        return(r)

def Framed(StringIn,l,r):
    s = stack()
    pairs=[]
    for n,k in enumerate(StringIn):
        if(k==l):
            s.push([n])
        if(k==r):
            q = s.pop()
            q.append(n+1)
            pairs.append(q)
    StringsOut = []
    for k in pairs:
        StringsOut.append(StringIn[k[0]:k[1]])
    return(StringsOut,pairs)

s = "(2 + (1 + tan(x)**2))"
pieces = Framed(s,"(",")")
print(pieces)
印刷品

(['(x)', '(1 + tan(x)**2)', '(2 + (1 + tan(x)**2))'], [[13, 16], [5, 20], [0, 21]])
鉴于此,遍历表达式树非常简单

for k in pieces[0]:
    if(rewriterule(eval(k),[x]).next() != None):
        ...
请注意,除非有框架括号,否则框架方法不会获取整个函数


希望这有帮助:)

您可能想看看SymPy的FU的
TR22
函数,它使用
bottum\u up
函数:

>>> eq
x/(tan(x)**2 + 1)
>>> FU['TR22'](eq)
x/sec(x)**2

谢谢,我想我应该澄清一下,最理想的情况是我希望能够在一个更大的表达式中隐式地使用身份。我不知道为什么这被否决了,但添加了我的upvote以帮助解决这个问题。我的一个问题也被无缘无故地否决了,所以这才公平:P