module routing sig State {} sig IP {} sig Link {from, to: State ->! Router} sig Router {ip: IP, table: State -> IP ->? Link, nexts: State -> Router} { all s: State { (table[s][IP].from)[s] in this nexts[s] = (table[s][IP].to)[s] no table[s][ip]} } fact {inj (Router$ip)} fun inj [t,t'] (r:t->t') {all x: t' | sole r.x} fun Consistent (s: State) { let rnexts = {r,r': Router | r->s->r' in Router$nexts} | all r: Router, i: IP | (r.table[s][i].to)[s] in i.~ip.*~rnexts } fun Propagate (s, s': State) { let rnexts = {r,r': Router | r->s->r' in Router$nexts} | all r: Router | r.table[s'] in r.table[s] + r.~rnexts.table[s] } assert PropagationOK { all s, s': State | Consistent (s) && Propagate (s,s') => Consistent (s') } check PropagationOK for 2 fun NoTopologyChange (s,s': State) { all x: Link { x.from[s] = x.from[s'] x.to[s] = x.to[s'] } }