【问题标题】:Algorithms for Unification of list-based trees基于列表的树的统一算法
【发布时间】:2012-10-26 18:06:00
【问题描述】:

我需要一个统一算法来处理以下情况。

我的表达式树中的每个节点都有一个列表(关联)或一组(关联和交换)子级。我想获得与特定模式的所有可能匹配项。

这是一个例子。假设我们正在处理矩阵,因此 + 是可交换的, * 是不可交换的

表达式:A + B*C*D + E

或者:Add(A, Mul(B, C, D), E)

模式:X + Y*Z

我看到了两场比赛

X: A + E
Y: B
Z: C * D

X: A + E
Y: B * C
Z: D

问题:是否有任何标准算法可以处理这个问题?

【问题讨论】:

  • 也有涉及0或I的情况,单位矩阵。

标签: programming-languages pattern-matching logic-programming unification


【解决方案1】:

当我看到这个时,我想到的只是用于匹配交换项的分区和子集。如果要将 n 项与 m > n 项匹配,则必须将 m 划分为 n 个部分,p。

然后您需要长度为 p_i 的子集,然后可以针对您的原始模式进行测试。找到最严格的术语并首先匹配它可能是有意义的。例如,如果 mul 将匹配,您可以查看是否存在 muls...如果是,那么您的初始问题已分为两部分:mul 部分和其余部分。最严格的术语是具有最高操作数的术语。所以 X + X*Y*Z + X*(Y+Z) 这两个 mul 项并列;领带可能会被打破,以支持添加更复杂的那个。所以也许 op_count 和操作类型的数量可能是复杂性的衡量标准。

在 SymPy 中:

>>> pat = X + X*Y*Z + X*(Y+Z)
>>> [(p.count_ops(), p.count_ops(visual=True).free_symbols) for p in Add.make_args(pat)]
[(0, set([])), (2, set([MUL])), (2, set([ADD, MUL]))]

就制定映射而言,让二进制数字为您选择项目是可行的。再次在 SymPy 中,from sympy.utilities.iterables import reshape, runs, permutations 生效:

>>> N=list('ABC')
>>> M=list('abcde')
>>> n=[1]*len(N)
>>> m=[1]*len(M)
>>> n.extend([0]*(len(m) - len(n)))
>>> grouper = lambda x, xx: x==xx==0 or x==0 and xx==1
>>> demo = [1, 0, 0, 1, 1]
>>> runs(demo, grouper)
[[1, 0, 0], [1], [1]]
>>> nn=n[1:] # the first one will stay put; shuffle the rest
>>> for p in permutations(nn):
...   P = [1]+list(p)
...   shape = [[len(r)] for r in runs(P, grouper)]
...   print dict(zip(N, reshape(M, shape)[0])) 
{'A': ['a'], 'C': ['c', 'd', 'e'], 'B': ['b']}
{'A': ['a'], 'C': ['c', 'd', 'e'], 'B': ['b']}
{'A': ['a'], 'C': ['d', 'e'], 'B': ['b', 'c']}
{'A': ['a'], 'C': ['e'], 'B': ['b', 'c', 'd']}
{'A': ['a'], 'C': ['d', 'e'], 'B': ['b', 'c']}
{'A': ['a'], 'C': ['e'], 'B': ['b', 'c', 'd']}
{'A': ['a'], 'C': ['c', 'd', 'e'], 'B': ['b']}
{'A': ['a'], 'C': ['c', 'd', 'e'], 'B': ['b']}
{'A': ['a'], 'C': ['d', 'e'], 'B': ['b', 'c']}
{'A': ['a'], 'C': ['e'], 'B': ['b', 'c', 'd']}
{'A': ['a'], 'C': ['d', 'e'], 'B': ['b', 'c']}
{'A': ['a'], 'C': ['e'], 'B': ['b', 'c', 'd']}
{'A': ['a', 'b'], 'C': ['d', 'e'], 'B': ['c']}
{'A': ['a', 'b'], 'C': ['e'], 'B': ['c', 'd']}
{'A': ['a', 'b'], 'C': ['d', 'e'], 'B': ['c']}
{'A': ['a', 'b'], 'C': ['e'], 'B': ['c', 'd']}
{'A': ['a', 'b', 'c'], 'C': ['e'], 'B': ['d']}
{'A': ['a', 'b', 'c'], 'C': ['e'], 'B': ['d']}
{'A': ['a', 'b'], 'C': ['d', 'e'], 'B': ['c']}
{'A': ['a', 'b'], 'C': ['e'], 'B': ['c', 'd']}
{'A': ['a', 'b'], 'C': ['d', 'e'], 'B': ['c']}
{'A': ['a', 'b'], 'C': ['e'], 'B': ['c', 'd']}
{'A': ['a', 'b', 'c'], 'C': ['e'], 'B': ['d']}
{'A': ['a', 'b', 'c'], 'C': ['e'], 'B': ['d']}

克里斯

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 2020-11-07
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多