我定义了以下Alloy模型
使用单个State对象指向两个树State.a
和State.b
的根。
sig N {
children: set N
}
fact {
let p = ~children |
~p.p in iden
and no iden & ^p
}
one sig State {
a: one N,
b: one N
}
fun parent[n:N] : N {
n.~children
}
fact {
no State.a.parent
no State.b.parent
State.a != State.b
State.a.^children != State.b.^children
}
pred show {}
run show for 4
我得到的解决方案之一:
+-----+
+--+State|+-+
a| +-----+ |b
| |
v v
+--+ +--+
|N2| |N3|
++-+ +-++
| |
+v-+ +-v+
|N0| |N1|
+--+ +--+
所以我得到两棵树N2 -> N0
和N3 -> N1
结构上相等。
如何进一步限制此模型,以便State.a
和State.b
在这个意义上是不平等的?
我担心这只能用递归谓词来完成 递归只能达到深度3的限制(我认为)。
因此,如果可能,我倾向于使用非递归解决方案。
答案 0 :(得分:1)
你对递归深度的递归说了一切。我刚尝试了以下递归谓词,它对小树很好用
pred noniso[n1, n2: N] {
#n1.children != #n2.children or
some nn1: n1.children, nn2: n2.children | noniso[nn1, nn2]
}
另一种不需要递归的方法是将noniso
关系建模为Alloy关系,然后为所有节点断言此关系包含所有非同构对。你可以这样做
one sig G {
noniso: N -> N
} {
all n1, n2: N {
(n1 -> n2 in noniso) iff
(#n1.children != #n2.children or
some nn1: n1.children, nn2: n2.children | nn1 -> nn2 in noniso)
}
}
为了测试这个,我创建了show_noniso
和show_iso
谓词,创建了4层嵌套的树。
// differ at level 4 only
pred show_noniso[n1, n2, n3, n4, n5, n6, n7: N] {
children = n1 -> n2 + n2 -> n3 + n3 -> n4 + n5 -> n6 + n6 -> n7
State.a = n1
State.b = n5
}
pred show_iso[n1, n2, n3, n4, n5, n6, n7, n8: N] {
children = n1 -> n2 + n2 -> n3 + n3 -> n4 + n5 -> n6 + n6 -> n7 + n7 -> n8
State.a = n1
State.b = n5
}
然后运行各种组合
// USING RECURSION_DEPTH SET TO 2
run noniso_recursion_fails {
some disj n1, n2, n3, n4, n5, n6, n7: N | show_noniso[n1, n2, n3, n4, n5, n6, n7]
noniso[State.a, State.b]
} for 8 expect 0
run noniso_relation_works {
some disj n1, n2, n3, n4, n5, n6, n7: N | show_noniso[n1, n2, n3, n4, n5, n6, n7]
State.a -> State.b in G.noniso
} for 8 expect 1
run iso_relation_works {
some disj n1, n2, n3, n4, n5, n6, n7, n8: N | show_iso[n1, n2, n3, n4, n5, n6, n7, n8]
State.a -> State.b in G.noniso
} for 8 expect 0
这些分析的结果与预期一致
#1: no instance found. noniso_recursion_fails may be inconsistent, as expected.
#2: instance found. noniso_relation_works is consistent, as expected.
#3: no instance found. iso_relation_works may be inconsistent, as expected.