Можно ли моделировать случайные сбои в Alloy?
Например, в настоящее время у меня есть связанный граф, который передает данные на разных временных шагах своим соседям. Что я пытаюсь сделать, так это выяснить какой-то метод, позволяющий модели случайным образом уничтожать ссылки, и при этом все еще удается достичь своей цели (гарантировать, что все узлы имеют состояние данных, установленное на «Вкл.»).
open util/ordering[Time]
enum Datum{Off, On} // A simple representation of the state of each node
sig Time{state:Node->one Datum} // at each time we have a network state
abstract sig Node{
neighbours:set Node
}
fact {
neighbours = ~neighbours -- symmetric
no iden & neighbours -- no loops
all n : Node | Node in n.*neighbours -- connected
-- all n : Node | (Node - n) in n.neighbours -- comp. connected
}
fact start{// At the start exactly one node has the datum
one n:Node|first.state[n]=On
}
fact simple_change{ // in one time step all neighbours of On nodes become on
all t:Time-last |
let t_on = t.state.On |
next[t].state.On = t_on+t_on.neighbours
}
run {} for 5 Time, 10 Node
Программное обеспечение, которое я пытаюсь смоделировать, имеет дело с неопределенностью. По сути, связь между узлами может выйти из строя, и программное обеспечение перенаправит маршрут по другому пути. Что я хотел бы попробовать сделать в Alloy, так это иметь возможность для ссылок «умирать» в определенные моменты времени (желательно случайным образом). В самом верхнем факте у меня есть возможность сделать граф полностью связанным, поэтому возможно, что, если связь прервется, другая может восполнить слабину (поскольку simple_change переключает состояние Datum на On для все подключенные соседи).
Изменить:
Итак, я сделал, как было предложено, и столкнулся со следующей ошибкой:
Я запутался, так как Я думал, что соседи и Node все еще были наборами?
Вот мой обновленный код:
open util/ordering[Time]
open util/relation
enum Datum{Off, On} // A simple representation of the state of each node
sig Time{
neighbours : Node->Node,
state:Node->one Datum // at each time we have a network state
}{
symmetric[neighbours, Node]
}
abstract sig Node{
neighbours:set Node
}
fact {
neighbours = ~neighbours -- symmetric
no iden & neighbours -- no loops
-- all n : Node | (Node - n) in n.neighbours -- comp. connected
all n : Node | Node in n.*neighbours -- connected
}
// At the start exactly one node has the datum
fact start{
one n:Node|first.state[n]=On
}
// in one time step all neighbours of On nodes become on
fact simple_change{
all t:Time-last |
let t_on = t.state.On |
next[t].state.On = t_on+t_on.neighbours
all t:Time-last | next[t].neighbours in t.neighbours
all t:Time-last | lone t.neighbours - next[t].neighbours
}
run {} for 10 Time, 3 Node