想知道如何以下列形式描述树关系:
module tree
pred isTree (r: univ −> univ) {...} run isTree for 4
如果我有:
refines module Graph
pred isConnected {
some n: Node |
(Graph.nodes = n) || (Graph.nodes = n.^(edges.(src + dest)))
}
pred noCycles {
all n: Node | n not in (n.^(outEdges.dest) + n.^(inEdges.src))
}
pred loneParent {
all n: Node | lone n.inEdges
}
fact isTree {
noDoubleEdges && isConnected && noCycles && loneParent
}
我想知道如何使用r建模树上的上述约束:univ - >大学。
提前非常感谢你!
答案 0 :(得分:2)
我看到你有兴趣检查关系是否以通用方式满足树的约束,即独立于关系的类型。
这在合金中是可能的,诀窍是对于任何关系r: univ->univ
,r.univ
将为您提供关系的域,univ.r
将为您提供关系的范围(从中你可以获得关系所涉及的所有节点。
您正在寻找的谓词是:
pred isTree (r: univ -> univ) {
let nodes=univ.r + r.univ{
one root : nodes | nodes = root.*r
no n :nodes | n in n.^r
all n:nodes | lone n.~r
}
}
第一个约束是可达性,第二个约束是非循环,第三个约束是为了防止节点有多个父节点。
答案 1 :(得分:1)
由于您已经省略了代码的一些细节,因此假设所有谓词都是正确的,给定代码确实应该在Node
的实例上描述树结构。请注意,这是在Universe中Node
的所有实例上完成的,仅由事实isTree
完成,因此不需要其他谓词。
请注意,虽然您的代码假设节点(以及整个树)位于全局范围内,但根据给定的参数定义定义有效树的谓词可能更方便,例如:为了无助:
pred acyclicity [root: Node, tree: Node -> Node] {
no ^tree & iden
}
在这种情况下,树定义有根音符和定义父子关系的关系。 然后,为了定义(约束模型)一个有效的树,可以按照
的方式写一些东西pred isTree [root: Node, tree: Node -> Node] {
reachability[root, tree]
acyclicity[root, tree]
loneParent[root, tree]
}
请注意,在这种情况下,您可能不需要对约束noDoubleEdges
建模,因为表示不允许通过构造。