You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
5.5 KiB
213 lines
5.5 KiB
// Modest PTA model of the bounded retransmission protocol (BRP)
|
|
// [HH09], http://www.modestchecker.net/CaseStudies/BRP/
|
|
action put, get, put_k, get_k, put_l, get_l;
|
|
action new_file;
|
|
action s_ok, s_dk, s_nok, s_restart;
|
|
action r_ok, r_inc, r_fst, r_nok, r_timeout;
|
|
exception error;
|
|
|
|
const int N = 16; // number of frames per file
|
|
const int MAX = 2; // maximum number of retransmissions per frame
|
|
const int TD = 1; // transmission delay
|
|
const int TS = 2 * TD + 1; // sender timeout
|
|
const int TR = 2 * MAX * TS + 3 * TD; // receiver timeout
|
|
const int SYNC = TR;
|
|
|
|
bool ff, lf, ab; // channel data: first/last frame, alternating bit
|
|
int(0..N) i; // sender chunk counter
|
|
bool inTransitK = false;
|
|
bool inTransitL = false;
|
|
|
|
bool first_file_done = false;
|
|
bool get_k_seen, s_ok_seen, s_nok_seen, s_dk_seen, s_restart_seen, r_ok_seen, r_timeout_seen;
|
|
|
|
// Invariant (timed) properties (from [BrpOnTime], the TA model)
|
|
bool premature_timeout, channel_k_overflow, channel_l_overflow;
|
|
// "there is at most one message in transit for each channel"
|
|
property T_1 = A[] (!(channel_k_overflow || channel_l_overflow));
|
|
// "there is at most one message in transit in total"
|
|
property T_2 = A[] (!(inTransitK && inTransitL));
|
|
// Assumption (A1): "no premature timeouts"
|
|
property T_A1 = A[] (!premature_timeout);
|
|
// Assumption (A2): "sender starts new file only after receiver reacted to failure"
|
|
// Note that receiver can only notice failure if it received at least one chunk, i.e. get_k_seen
|
|
property T_A2 = A[] (!s_restart_seen || !get_k_seen || r_timeout_seen);
|
|
|
|
// Probabilistic reachability properties (from [D'AJJL01], the RAPTURE/PRISM model)
|
|
// property A of [D'AJJL01]: "the maximum probability that eventually the sender reports
|
|
// a certain unsuccessful transmission but the receiver got the complete file"
|
|
property P_A = Pmax(<>(s_nok_seen && r_ok_seen));
|
|
// property B of [D'AJJL01]: "the maximum probability that eventually the sender reports
|
|
// a certain successful transmission but the receiver did not get the complete file"
|
|
property P_B = Pmax(<>(s_ok_seen && !r_ok_seen));
|
|
// property 1 of [D'AJJL01]: "the maximum probability that eventually the sender
|
|
// does not report a successful transmission"
|
|
property P_1 = Pmax(<>(s_nok_seen || s_dk_seen));
|
|
// property 2 of [D'AJJL01]: "the maximum probability that eventually the sender
|
|
// reports an uncertainty on the success of the transmission"
|
|
property P_2 = Pmax(<>(s_dk_seen));
|
|
// property 3 of [D'AJJL01]: "the maximum probability that eventually the sender
|
|
// reports an unsuccessful transmission after more than 8 chunks have been sent successfully"
|
|
property P_3 = Pmax(<>(s_nok_seen && i > 8));
|
|
// property 4 of [D'AJJL01]: "the maximum probability that eventually the receiver
|
|
// does not receive any chunk and the sender tried to send a chunk"
|
|
property P_4 = Pmax(<>((s_ok_seen || s_nok_seen || s_dk_seen) && !get_k_seen));
|
|
|
|
|
|
process Sender()
|
|
{
|
|
bool bit;
|
|
int(0..MAX) rc;
|
|
clock c;
|
|
|
|
try
|
|
{
|
|
do {
|
|
:: when urgent(i < N) {= i++ =};
|
|
do
|
|
{
|
|
// send frame
|
|
invariant(c <= 0) put_k {= ff = (i == 1), lf = (i == N), ab = bit, c = 0 =};
|
|
invariant(c <= TS) alt {
|
|
:: // receive ack
|
|
get_l {= bit = !bit, rc = 0, c = 0 =};
|
|
urgent break
|
|
:: // timeout
|
|
when(c >= TS)
|
|
if(rc < MAX)
|
|
{
|
|
// retry
|
|
{= rc++, c = 0 =}
|
|
}
|
|
else if(i < N)
|
|
{
|
|
// no retries left
|
|
s_nok {= rc = 0, c = 0 =};
|
|
urgent throw(error)
|
|
}
|
|
else
|
|
{
|
|
// no retries left
|
|
s_dk {= rc = 0, c = 0 =};
|
|
urgent throw(error)
|
|
}
|
|
}
|
|
}
|
|
:: when(i == N)
|
|
// file transmission successfully completed
|
|
invariant(c <= 0) s_ok {= first_file_done = true =};
|
|
urgent break
|
|
}
|
|
}
|
|
catch error
|
|
{
|
|
// File transfer did not succeed: wait, then restart with next file
|
|
invariant(c <= SYNC) when(c >= SYNC)
|
|
s_restart {= bit = false, first_file_done = true =}
|
|
}
|
|
}
|
|
|
|
process Receiver()
|
|
{
|
|
bool r_ff, r_lf, r_ab;
|
|
bool bit;
|
|
clock c;
|
|
|
|
// receive first frame
|
|
if(ff) { get_k {= c = 0, bit = ab, r_ff = ff, r_lf = lf, r_ab = ab =} }
|
|
else { get_k {= c = 0, premature_timeout = true =}; stop };
|
|
do
|
|
{
|
|
invariant(c <= 0)
|
|
{
|
|
if(r_ab != bit)
|
|
{
|
|
// repetition, re-ack
|
|
put_l
|
|
}
|
|
else
|
|
{
|
|
// report frame
|
|
if(r_lf) { r_ok }
|
|
else if(r_ff) { r_fst }
|
|
else { r_inc };
|
|
put_l {= bit = !bit =}
|
|
}
|
|
};
|
|
invariant(c <= TR)
|
|
{
|
|
alt {
|
|
:: // receive next frame
|
|
get_k {= c = 0, r_ff = ff, r_lf = lf, r_ab = ab =}
|
|
:: // timeout
|
|
when(c == TR)
|
|
if(r_lf)
|
|
{
|
|
// we just got the last frame, though
|
|
r_timeout; break
|
|
}
|
|
else
|
|
{
|
|
r_nok;
|
|
// abort transfer
|
|
r_timeout; break
|
|
}
|
|
}
|
|
}
|
|
};
|
|
Receiver()
|
|
}
|
|
|
|
process ChannelK()
|
|
{
|
|
clock c;
|
|
|
|
put_k palt
|
|
{
|
|
:98: {= c = 0, inTransitK = true =};
|
|
invariant(c <= TD) alt {
|
|
:: get_k {= inTransitK = false =}
|
|
:: put_k {= channel_k_overflow = true =}; stop
|
|
}
|
|
: 2: {==}
|
|
};
|
|
ChannelK()
|
|
}
|
|
|
|
process ChannelL()
|
|
{
|
|
clock c;
|
|
|
|
put_l palt
|
|
{
|
|
:99: {= c = 0, inTransitL = true =};
|
|
invariant(c <= TD) alt {
|
|
:: get_l {= inTransitL = false =}
|
|
:: put_l {= channel_l_overflow = true =}; stop
|
|
}
|
|
: 1: {==}
|
|
};
|
|
ChannelL()
|
|
}
|
|
|
|
process Observer()
|
|
{
|
|
alt {
|
|
:: get_k {= get_k_seen = true =}
|
|
:: s_ok {= s_ok_seen = true =}
|
|
:: s_nok {= s_nok_seen = true =}
|
|
:: s_dk {= s_dk_seen = true =}
|
|
:: s_restart {= s_restart_seen = true =}
|
|
:: r_ok {= r_ok_seen = true =}
|
|
:: r_timeout {= r_timeout_seen = true =}
|
|
};
|
|
Observer()
|
|
}
|
|
|
|
par {
|
|
:: Sender()
|
|
:: Receiver()
|
|
:: ChannelK()
|
|
:: ChannelL()
|
|
:: Observer()
|
|
}
|