Tree Alloy:使用谓词检查树关系

Tree Alloy:使用谓词检查树关系,tree,relational,alloy,calculus,Tree,Relational,Alloy,Calculus,我想知道如何以以下形式描述树关系: 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

我想知道如何以以下形式描述树关系:

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->univ对树上的上述约束进行建模


提前非常感谢

由于您省略了代码的一些细节,在假设所有谓词都正确的情况下,给定的代码确实应该描述Node实例上的树结构。请注意,这是在宇宙中所有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]
}

注意:在这种情况下,您可能不需要通过构造对约束nodoubledges建模,因为表示不允许它。

由于您省略了代码的一些细节,在假设所有谓词都正确的情况下,给定的代码确实应该描述节点实例上的树结构。请注意,这是在宇宙中所有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]
}

注意:在这种情况下,您可能不需要通过构造对约束nodoubledges进行建模,因为表示不允许它。

我发现您感兴趣的是检查一个关系是否以一种通用的方式满足树的约束,即独立于关系的类型

这在Alloy中是可能的,诀窍是,对于任何关系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
    }
}

第一个约束用于可达性,第二个约束用于非循环性,第三个约束用于防止节点具有多个父节点

我发现您对检查一个关系是否以通用方式满足树的约束感兴趣,也就是说,独立于关系的类型

这在Alloy中是可能的,诀窍是,对于任何关系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
    }
}
第一个约束用于可达性,第二个约束用于非循环性,第三个约束用于防止节点具有多个父节点