统一表达式只匹配树的顶部节点

Unification expression only matches on top node of tree

我决定转三角恒等式

通过重写unify变成一个函数。所以,

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

然后我得到

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

>>> list(trig_rule_tan(2 + (1 + tan(x)**2)))

没有找到匹配项

如何在更大的表达式树中将模式映射匹配到具有 rewriterule 的函数?

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

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):
        ...

请注意,除非有框架括号,否则 framed 方法不会获取整个函数。

希望这对您有所帮助:)

您可能想看看 SymPy 的 FU 的 TR22 函数,它使用 bottum_up 函数:

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