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