%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% XSB/LMC Code for Leader Election Protocol: %% Dolev, Klawe, Rodeh, %% Adapted from SPIN test suite by Y.S.R., 19 Dec 96. %% Parameterized wrt size of ring and buffer size by C.R., Aug 98. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%============================================================================= %% the node process involved in electing a leader %% one node. N is the number of nodes in the network node(N, Id) ::= out(right, first(Id)) o nodeActive(N, Id, _Nbr). nodeActive(N, Maxi, Nbr) ::= in(left, first(NId)) o if(NId \== Maxi , out(right, second(NId)) o nodeActive(N, Maxi, NId) , if( Maxi is N-1 , action(leader) o nodeActive(N, Maxi, NId) , action(fail) o end ) ) # in(left, second(NId)) o if((Nbr > NId, Nbr > Maxi) , out(right, first(Nbr)) o nodeActive(N, Nbr, Nbr) , nodeInactive ). nodeInactive ::= in(left, Msg) o out(right, Msg) o nodeInactive. %%============================================================================= %% A size-N buffer :- import length/2 from basics. chan(N, Buf) ::= length(Buf, Len) o ( Len < N o in(chan_in, Msg) o chan(N, [Msg|Buf]) # Len > 0 o strip_from_end(Buf, Msg, NewBuf) o out(chan_out, Msg) o chan(N, NewBuf) ). strip_from_end([X], X, []). strip_from_end([X,Y|Ys], Z, [X|Zs]) :- strip_from_end([Y|Ys], Z, Zs). %%----------------------------------------------------------------------------- %% instantiated system specifications leader3 ::= ( node(3,2) @ [left/left(0), right/right(0)] | node(3,1) @ [left/left(1), right/right(1)] | node(3,0) @ [left/left(2), right/right(2)] | chan(6,[]) @ [chan_in/right(0), chan_out/left(1)] | chan(6,[]) @ [chan_in/right(1), chan_out/left(2)] | chan(6,[]) @ [chan_in/right(2), chan_out/left(0)] ) \ {snd(_), left(_), right(_)}. leader4 ::= ( node(4,3) @ [left/left(0), right/right(0)] | node(4,2) @ [left/left(1), right/right(1)] | node(4,1) @ [left/left(2), right/right(2)] | node(4,0) @ [left/left(3), right/right(3)] | chan(8,[]) @ [chan_in/right(0), chan_out/left(1)] | chan(8,[]) @ [chan_in/right(1), chan_out/left(2)] | chan(8,[]) @ [chan_in/right(2), chan_out/left(3)] | chan(8,[]) @ [chan_in/right(3), chan_out/left(0)] ) \ {snd(_), left(_), right(_)}. leader5 ::= ( node(5,4) @ [left/left(0), right/right(0)] | node(5,3) @ [left/left(1), right/right(1)] | node(5,2) @ [left/left(2), right/right(2)] | node(5,1) @ [left/left(3), right/right(3)] | node(5,0) @ [left/left(4), right/right(4)] | chan(10,[]) @ [chan_in/right(0), chan_out/left(1)] | chan(10,[]) @ [chan_in/right(1), chan_out/left(2)] | chan(10,[]) @ [chan_in/right(2), chan_out/left(3)] | chan(10,[]) @ [chan_in/right(3), chan_out/left(4)] | chan(10,[]) @ [chan_in/right(4), chan_out/left(0)] ) \ {snd(_), left(_), right(_)}. leader6 ::= ( node(6,5) @ [left/left(0), right/right(0)] | node(6,4) @ [left/left(1), right/right(1)] | node(6,3) @ [left/left(2), right/right(2)] | node(6,2) @ [left/left(3), right/right(3)] | node(6,1) @ [left/left(4), right/right(4)] | node(6,0) @ [left/left(5), right/right(5)] | chan(12,[]) @ [chan_in/right(0), chan_out/left(1)] | chan(12,[]) @ [chan_in/right(1), chan_out/left(2)] | chan(12,[]) @ [chan_in/right(2), chan_out/left(3)] | chan(12,[]) @ [chan_in/right(3), chan_out/left(4)] | chan(12,[]) @ [chan_in/right(4), chan_out/left(5)] | chan(12,[]) @ [chan_in/right(5), chan_out/left(0)] ) \ {snd(_), left(_), right(_)}. leader7 ::= ( node(7,6) @ [left/left(0), right/right(0)] | node(7,5) @ [left/left(1), right/right(1)] | node(7,4) @ [left/left(2), right/right(2)] | node(7,3) @ [left/left(3), right/right(3)] | node(7,2) @ [left/left(4), right/right(4)] | node(7,1) @ [left/left(5), right/right(5)] | node(7,0) @ [left/left(6), right/right(6)] | chan(14,[]) @ [chan_in/right(0), chan_out/left(1)] | chan(14,[]) @ [chan_in/right(1), chan_out/left(2)] | chan(14,[]) @ [chan_in/right(2), chan_out/left(3)] | chan(14,[]) @ [chan_in/right(3), chan_out/left(4)] | chan(14,[]) @ [chan_in/right(4), chan_out/left(5)] | chan(14,[]) @ [chan_in/right(5), chan_out/left(6)] | chan(14,[]) @ [chan_in/right(6), chan_out/left(0)] ) \ {snd(_), left(_), right(_)}. %%============================================================================= %% Properties ae_leader += diam(-nil, tt) /\ box(-leader, ae_leader). ee_fail += diam(fail, tt) \/ diam(-nil, ee_fail). one_leader += box(-leader, one_leader) /\ box(leader, no_leader). no_leader -= box(leader, ff) /\ box(-nil, no_leader). aa_true -= box(fail, ff) /\ box(-nil, aa_true). aa_leader -= diam(-nil, tt) /\ box(-leader, aa_leader).