I have defined the following Alloy model that
uses a single State object to point to the roots of two trees State.a and 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
Among the solutions I get:
+-----+
+--+State|+-+
a| +-----+ |b
| |
v v
+--+ +--+
|N2| |N3|
++-+ +-++
| |
+v-+ +-v+
|N0| |N1|
+--+ +--+
So I get two trees N2 -> N0 and N3 -> N1 that are
structurally equal.
How can I further constraint this model so that State.a and State.b
are not equal in this sense?
I am afraid that this can only be done with a recursive predicate and recursion is only possible to a limit of depth 3 (I think).
Therefore, I would favour a non-recursive solution if this is possible.
You said everything right about the recursion the recursion depth. I just tried the following recursive predicate, which did work fine for small trees
Another way to achieve this, which doesn't require recursion, is to model the
nonisorelationship as an Alloy relation, and then assert for all nodes that this relation contains all non-isomorphic pairs. You could do that like thisTo put this to test, I created
show_nonisoandshow_isopredicates that create trees with 4 levels of nesting.and then ran various combinations
The results of these analyses were as expected