Tree 如何表达合金中树之间的结构相等?

Tree 如何表达合金中树之间的结构相等?,tree,equality,alloy,structural-equality,Tree,Equality,Alloy,Structural Equality,我定义了以下合金模型: 使用单个状态对象指向两棵树的根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.par

我定义了以下合金模型: 使用单个状态对象指向两棵树的根
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的极限(我认为)


因此,如果可能的话,我倾向于使用非递归的解决方案。

关于递归,你说的一切都是对的,递归深度。我只是尝试了下面的递归谓词,它对小树很有效

pred noniso[n1, n2: N] {
  #n1.children != #n2.children or 
  some nn1: n1.children, nn2: n2.children | noniso[nn1, nn2]
}
另一种不需要递归的方法是将
noniso
关系建模为合金关系,然后为所有节点断言该关系包含所有非同构对。你可以这样做

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.