У меня есть модель (см. Ниже) с двумя подписями: Data
и Node
. Я определил некоторые предикаты, которые характеризуют жителей Узла, а именно: Orphan
, Terminal
и Isolated
.
Что я хочу сделать - но еще не достиг - это определить предикат Link
, который моделирует связывание двух узлов так, что один узел становится преемником (succ
) другого. Кроме того, я хотел бы ограничить операцию так, чтобы ссылки могли быть сделаны только для Isolated
узлов. Кроме того, я хотел бы, чтобы ограничение - если это возможно - каким-то образом было внутренним по отношению к предикату Link
.
Вот моя последняя попытка:
sig Data {}
sig Node {
data: Data,
succ: lone Node
}
// Node characterisation
pred Isolated (n: Node) { Orphan[n] and Terminal[n] }
pred Orphan (n: Node) { no m: Node | m.succ = n }
pred Terminal (n: Node) { no n.succ }
/*
* Link
*
* May only Link n to an m, when:
* - n differs from m
* - m is an Isolated Node (DOES NOT WORK)
*
* After the operation:
* - m is the succcessor of n
*/
pred Link (n,m: Node) {
n != m
Isolated[m] /* Not satisfiable */
m = succ[n]
}
pred LinkFeasible { some n,m: Node | Link[n,m] }
run LinkFeasible
Включение конъюнкта Isolated[m]
делает модель неудовлетворительной. Я думаю, что понимаю почему: не может быть Node
, который одновременно является Isolated
и наследником другого. Я включаю его только в надежде, что это может раскрыть мои намерения.
Мой вопрос: как мне определить предикат Link
, чтобы связать два узла так, чтобы с ним могли быть связаны только Isolated
узлы?