链表,没有两个元素相同

时间:2015-02-02 02:17:24

标签: alloy

sig List {
    header: set Node
}
sig Node {
    link: set Node,
    elem: set Int
}

我希望没有两个节点指向同一个元素。如何实现这一目标?

我真的不了解*运算符,但我尝试了

all n: Node | n.elem != n.*link.elem

假设n。* link.elem指向集合中的所有元素,例如

n.link.elem
n.link.link.elem
n.link.link.link.elem

但这不起作用。

3 个答案:

答案 0 :(得分:3)

您可以在声明elem字段时简单地使用disj关键字

sig List {
    header: set Node
}
sig Node {
    link: set Node,
    disj elem: set Int
}

这是表示没有两个节点n1和n2使得n1!= n2和n1.elem& n2.elem!=无

关于你的尝试,

all n: Node | n.elem != n.*link.elem

表示对于所有节点n,与n关联的元素与链接到n的节点关联的元素不同。 这有两个流程。

首先,您不会考虑未链接到n的节点。

其次,你应该考虑到elem是一组整数。 假设n1.elem = {1,2,3,4}和n2.elem = {1,2,3}。写入n1.elem是不够的{1,2,3,4}!= {1,2,3}。在这种情况下,n1和n2都指向1,2和3。因此,你需要脱节。

答案 1 :(得分:1)

为了更好地逼近整数结构链表,我建议使用以下模型。

sig List {
    header: lone Node // empty list or one header node
}

sig Node {
    link: lone Node,  // 0 or 1 next node 
    elem: one Int     // prohibit empty nodes
}

fact {
    no n: Node | n in n.^link                   // prohibit cycles
    all disj n, n': Node | n.elem != n'.elem    // different nodes have different elements
    all n: Node | one l: List | n = l.header or n in l.header.^link 
                                                // every node belongs to a list
}

答案 2 :(得分:1)

你需要节点吗?

这样抽象的东西怎么样?

abstract sig List {}
sig EmptyList extends List {}
sig NonEmptyList extends List {rest: List, contents: T}