假设我们有 N 符号表达式,例如:
f(g(a1, a2), b1)
f(a3, b2)
f(g(a4, a2), b1)
f(a3, b4)
f(a3, b1)
为简单起见,假设所有具有相同名称的函数具有相同的arity(如同,没有重载)。
我的目标是使用最少数量的 join , union 和 list 来代表这组 N 项目em>内存中的表达式:
list 表达式只是一个有限集。我们在问题中设置的输入是一个列表表达式。例如:
[a1, a2, a3]
union 表达式是多个集合的并集:
U{[a1, a2, a3], U{[b1], [c2, c3]}} == [a1, a2, a3, b1, c2, c3]
函数f
的 join 表达式表示一个集合,它是参数集的笛卡尔积,其函数f
应用于每个参数组合。例如:
f{[a1, a2, a3], [b1, b2]} ==
[ f(a1, b1), f(a2, b1), f(a3, b1),
f(a1, b2), f(a2, b2), f(a3, b2) ]
给定输入集,有许多可能的方法用这些运算符表示它。简单地将所有 N 表达式统一在一个列表中是一种方法。下面显示了两个可能的其他:
U{ f{ [g(a1, a2), g(a4, a2)],
[b1] },
f{ [a3],
[b1, b2, b4] }}
U{ f{ U{ [a3],
g{ [a1, a4],
[a2] } },
[b1] },
f{ [a3], [b2, b4] }}
直观地说,这些表示中的每一个都将给定表达式的一些公共部分统一到共享组件中。显然,对于足够大的 N ,存在的表示占用的内存少于仅仅 N 表达式的明确列表。我定义了#34;占用内存"这里是集合中所有术语的总数(包括中间术语,如函数应用程序)加上集合表达式(连接和联合)的总数。直观地说,它只是表示中的运算符和操作数的总数。例如:
f
s,2 g
s,...)。f
- 加入,以及所有列表元素的总共11个术语。< / LI>
f
- 加入,1个g
- 加入< / em>,以及所有列表元素的总共8个术语。在这些选项中,最后一个是最优选的。可能还有更好的,我不知道。最终,选择最佳表示是关于确定应该共享哪些部分,以及应该明确列出哪些部分。有没有办法在算法上解决这个问题?对于我来说,它看起来像是一种自上而下的动态编程,但我还没有找到确切的解决方案。
谢谢!