【发布时间】:2020-10-15 23:17:30
【问题描述】:
有没有办法使用更命令的方法从Graph type 计算支配树?语言是否支持直接创建这样的数据结构?
我正在尝试使用以下算法 (here is the link for the original article) 从图表中提取支配树:
但我在调整 for 和 while 语句时遇到了麻烦。
【问题讨论】:
标签: graph functional-programming rascal
有没有办法使用更命令的方法从Graph type 计算支配树?语言是否支持直接创建这样的数据结构?
我正在尝试使用以下算法 (here is the link for the original article) 从图表中提取支配树:
但我在调整 for 和 while 语句时遇到了麻烦。
【问题讨论】:
标签: graph functional-programming rascal
有一些选择,例如如何表示输出支配树。一种典型的方法是再次选择 Graph。稍后,如果您愿意,可以通过其他函数将 Graph 转换为构造函数树。
鉴于对 Graph[&T] 的选择,以下模板可以将给定算法直接翻译成 Rascal:
Graph[&T] dominators(Graph[&T] graph, &T root) {
result = {};
V = carrier(graph);
Pred = graph<to,from>;
solve(result) {
for (v <- V, u <- Pred[v]) {
if (...)
}
}
return result;
}{
但是没有必要通过先反转它然后不断查找前辈来进入“pred”形式的图,我们也可以直接遍历边,这要快得多:
Graph[&T] dominators(Graph[&T] graph, &T root) {
result = {};
solve(result) {
for (<u, v> <- graph) { // u is the predecessor of v
if (...) {
result += { };
}
}
}
return result;
}
直接来自 Dragon 书中定义的基本不动点求解器(以及您引用的论文中的方程 3.2)。 (注意我只是输入了这个,还没有测试,所以它可能是错误的):
rel[&T, set[&T]] dominators(graph[&T] graph) {
nodes = carrier(graph);
result = {};
preds = graph<to,from>;
solve(result) {
for (n <- nodes) {
result[n] = {n} + intersect({result[p] | p <- preds[n]?{}});
}
}
return result;
}
(与 Set 模块中的库函数相交)
这是一个“关系演算”解决方案,它使用reachX 库函数解决问题,并返回从每个节点到它支配的节点集的关系(取自 Rascal 文档文件):
rel[&T, set[&T]] dominators(rel[&T,&T] PRED, &T ROOT) {
set[&T] VERTICES = carrier(PRED);
return { <V, (VERTICES - {V, ROOT}) - reachX({ROOT}, {V}, PRED)> | &T V : VERTICES};
}
【讨论】:
demo::Dominators
{result[p] | p <- preds[n]?{}} 时,我得到“set[void] 类型的表达式不能被下标”。我不知道如何解决这个问题,有什么想法吗?
union 代替intersection,引发了未定义的函数错误