Leader election ring
¤
A module for axiomatizing a total order
¤
module total_order(r) = {
axiom r(X,X) # Reflexivity
axiom r(X, Y) & r(Y, Z) -> r(X, Z) # Transitivity
axiom r(X, Y) & r(Y, X) -> X = Y # Anti-symmetry
axiom r(X, Y) | r(Y, X) # Totality
}
¤
Module describing a ring topology.
The module includes a ring_head and ring_tail elements, and a ring total order relation.
The module also includes get_next and get_prev actions.
In this module, the ring topology is arbitrary and fixed.
¤
module ring_topology(carrier) = {
individual head:carrier # ring head
individual tail:carrier # ring tail
relation le(X:carrier,Y:carrier) # total order describing ring topology
instantiate total_order(le) # total order
axiom le(head, X) # head is minimal
axiom le(X, tail) # tail is maximal
action get_next(x:carrier) returns (y:carrier) = {
assume (x = tail & y = head) | (le(x,y) & x ~= y & ((le(x, Z) & x ~= Z) -> le(y, Z)))
}
action get_prev(y:carrier) returns (x:carrier) = {
assume (x = tail & y = head) | (le(x,y) & x ~= y & ((le(x, Z) & x ~= Z) -> le(y, Z)))
}
}
¤
Types, relations and functions describing state of the network
¤
type node
type id
instantiate ring : ring_topology(node)
relation le(X:id, Y:id)
instantiate total_order(le)
individual idn(X:node) : id
axiom idn(X)=idn(Y) -> X=Y # the idn function is injective
relation leader(N:node)
init ~leader(N)
relation pending(V:id, N:node) # The identity V is pending at node N
init ~pending(V, N)
¤
Protocol description
Two action: send and receive
¤
action send = {
local n1:node, n2:node {
n2 := ring.get_next(n1);
pending(idn(n1), n2) := true
}
}
action receive = {
local n1:node, n2:node, m:id {
assume pending(m, n1);
pending(m, n1) := *; # abstract the number of pending messages
if m = idn(n1) { # Found a leader
leader(n1) := true
} else {
if le(idn(n1), m) { # pass message to next node
n2 := ring.get_next(n1);
pending(m, n2) := true
} # otherwise drop the message...
}
}
}
export send
export receive
conjecture leader(X) & leader(Y) -> X = Y # at most one leader
conjecture leader(X) -> le(idn(Y), idn(X)) # leader has highest id