The Concurrent Alternating Bit Protocol
Description
Specification
data module CABP-data
begin
exports
begin
sorts
BIT,
DATA,
FRAME,
ACK
functions
0 : -> BIT
1 : -> BIT
inv : BIT -> BIT
'a : -> DATA
'b : -> DATA
'c : -> DATA
'd : -> DATA
'e : -> DATA
frame : DATA # BIT -> FRAME
ack : BIT -> FRAME
ce : -> FRAME
ae : -> FRAME
ac : -> FRAME
end
equations
[B1] inv(0) = 1
[B2] inv(1) = 0
end CABP-data
process module CABP
begin
imports
CABP-data
atoms
input : DATA
output : DATA
send-SK : FRAME
rec-SK : FRAME
comm-SK : FRAME
send-KR : FRAME
rec-KR : FRAME
comm-KR : FRAME
send-RAS : FRAME
rec-RAS : FRAME
comm-RAS : FRAME
send-ASL : FRAME
rec-ASL : FRAME
comm-ASL : FRAME
send-LAR : FRAME
rec-LAR : FRAME
comm-LAR : FRAME
send-ARS : FRAME
rec-ARS : FRAME
comm-ARS : FRAME
processes
S
Receive-Message : BIT
Send-Frame : FRAME
K
K : FRAME
R
Receive-Frame : BIT
AS
Ack-Sender : BIT
L
L : BIT
AR
Ack-Receiver : BIT
CABP
sets
of DATA
DATA-set = { 'a, 'b, 'c, 'd, 'e }
of BIT
BIT-set = { 0, 1 }
of atoms
H = { send-SK(fr), rec-SK(fr),
send-KR(fr), rec-KR(fr),
send-RAS(fr), rec-RAS(fr),
send-ASL(fr), rec-ASL(fr),
send-LAR(fr), rec-LAR(fr),
send-ARS(fr), rec-ARS(fr) | fr in FRAME }
communications
send-SK(fr) | rec-SK(fr) = comm-SK(fr) for fr in FRAME
send-KR(fr) | rec-KR(fr) = comm-KR(fr) for fr in FRAME
send-RAS(fr) | rec-RAS(fr) = comm-RAS(fr) for fr in FRAME
send-ASL(fr) | rec-ASL(fr) = comm-ASL(fr) for fr in FRAME
send-LAR(fr) | rec-LAR(fr) = comm-LAR(fr) for fr in FRAME
send-ARS(fr) | rec-ARS(fr) = comm-ARS(fr) for fr in FRAME
variables
b : -> BIT
d : -> DATA
fr : -> FRAME
definitions
S = Receive-Message(0)
Receive-Message(b) = sum(d in DATA-set, input(d) . Send-Frame(frame(d, b)))
Send-Frame(frame(d, b)) =
send-SK(frame(d, b)) .
Send-Frame(frame(d, b))
+ rec-ARS(ac) .
Receive-Message(inv(b))
K = sum(fr in FRAME, rec-SK(fr) . K(fr))
K(fr) = (
skip .
send-KR(fr)
+ skip .
send-KR(ce)
+ skip
) . K
R = Receive-Frame(0)
Receive-Frame(b) =
sum(d in DATA-set,
rec-KR(frame(d, b)) .
output(d) .
send-RAS(ac) .
Receive-Frame(inv(b))
)
+ sum(d in DATA-set,
rec-KR(frame(d, inv(b))) .
Receive-Frame(b)
)
+ rec-KR(ce) .
Receive-Frame(b)
AS = Ack-Sender(1)
Ack-Sender(b) =
rec-RAS(ac) .
Ack-Sender(inv(b))
+ send-ASL(ack(b)) .
Ack-Sender(b)
L = sum(b in BIT-set, rec-ASL(ack(b)) . L(b))
L(b) = (
skip .
send-LAR(ack(b))
+ skip .
send-LAR(ae)
+ skip
) . L
AR = Ack-Receiver(0)
Ack-Receiver(b) =
(
rec-LAR(ae)
+ rec-LAR(ack(inv(b)))
) . Ack-Receiver(b)
+ rec-LAR(ack(b)) .
send-ARS(ac) .
Ack-Receiver(inv(b))
CABP = encaps(H, S || K || R || AS || L || AR)
end CABP
Compilation
Assuming the specification resides in file
CABP, it should be
compiled with the command:
% psf -s CABP
Simulation
Compilation gives the file
CABP.til, which can be simulated with
the command:
% sim CABP.til
Choose
CABP as start process.
Animation
With the tool
simanim we can combine the simulation with animation.
For the animation we use:
Anim::Windows 440 200 -text 61 10
Anim::CreateItem recti rect 30 150 20 20 "I"
Anim::CreateItem ovals oval 120 150 20 20 "S"
Anim::CreateItem rectk rect 240 150 40 10 "K"
Anim::CreateItem ovalr oval 360 150 20 20 "R"
Anim::CreateItem rectl rect 240 50 40 10 "L"
Anim::CreateItem ovalas oval 360 50 20 20 "AS"
Anim::CreateItem ovalar oval 120 50 20 20 "AR"
Anim::CreateLine toS item recti e item ovals chop -arrow last
Anim::TextposLine toS toS s
Anim::CreateLine StoK item ovals chop item rectk w -arrow last
Anim::TextposLine StoK StoK n
Anim::TextposItem atK rectk s n
Anim::CreateLine KtoR item rectk e item ovalr chop -arrow last
Anim::TextposLine KtoR KtoR n
Anim::CreateLine fromR item ovalr chop pos 430 150 -arrow last
Anim::TextposLine fromR fromR s
Anim::CreateLine RtoAS item ovalr chop item ovalas chop -arrow last
Anim::TextposLine RtoAS RtoAS w
Anim::CreateLine AStoL item ovalas chop item rectl e -arrow last
Anim::TextposLine AStoL AStoL s
Anim::TextposItem atL rectl n s
Anim::CreateLine LtoAR item rectl w item ovalar chop -arrow last
Anim::TextposLine LtoAR LtoAR s
Anim::CreateLine ARtoS item ovalar chop item ovals chop -arrow last
Anim::TextposLine ARtoS ARtoS e
proc ANIM_action {line} {
if {[regexp {^input\('(.*)\)$} $line match arg1]} {
Anim::Clear recti
Anim::Clear ovals
Anim::CreateText toS "$arg1"
Anim::ActivateLine toS
Anim::AddClear ovals {line toS} {text toS}
} elseif {[regexp {^comm-SK\(frame\('(.*), (.*)\)\)$} $line match arg1 arg2]} {
Anim::Clear ovals
Anim::CreateText StoK "$arg1 ($arg2)"
Anim::ActivateLine StoK
Anim::AddClear rectk {line StoK} {text StoK}
} elseif {[regexp {^skip<(0|1|2)>$} $line match]} {
Anim::Clear rectk
Anim::CreateText atK "$match"
Anim::AddClear rectk {text atK}
} elseif {[regexp {^comm-KR\(frame\('(.*), (.*)\)\)$} $line match arg1 arg2]} {
Anim::Clear rectk
Anim::Clear ovalr
Anim::CreateText KtoR "$arg1 ($arg2)"
Anim::ActivateLine KtoR
Anim::AddClear ovalr {line KtoR} {text KtoR}
} elseif {[regexp {^comm-KR\((.*)\)$} $line match arg1]} {
Anim::Clear rectk
Anim::Clear ovalr
Anim::CreateText KtoR "$arg1"
Anim::ActivateLine KtoR
Anim::AddClear ovalr {line KtoR} {text KtoR}
} elseif {[regexp {^output\('(.*)\)$} $line match arg1]} {
Anim::Clear ovalr
Anim::CreateText fromR "$arg1"
Anim::ActivateLine fromR
Anim::AddClear ovalr {line fromR} {text fromR}
} elseif {[regexp {^comm-RAS\((.*)\)$} $line match arg1]} {
Anim::Clear ovalr
Anim::CreateText RtoAS "$arg1"
Anim::ActivateLine RtoAS
Anim::AddClear ovalas {line RtoAS} {text RtoAS}
} elseif {[regexp {^comm-ASL\((.*)\)$} $line match arg1]} {
Anim::Clear ovalas
Anim::CreateText AStoL "$arg1"
Anim::ActivateLine AStoL
Anim::AddClear ovalas {line AStoL} {text AStoL}
} elseif {[regexp {^skip<(3|4|5)>$} $line match]} {
Anim::Clear ovalas
Anim::CreateText atL "$match"
Anim::AddClear rectl {text atL}
} elseif {[regexp {^comm-LAR\((.*)\)$} $line match arg1]} {
Anim::Clear rectl
Anim::Clear ovalar
Anim::CreateText LtoAR "$arg1"
Anim::ActivateLine LtoAR
Anim::AddClear ovalar {line LtoAR} {text LtoAR}
} elseif {[regexp {^comm-ARS\((.*)\)$} $line match arg1]} {
Anim::Clear ovalar
Anim::CreateText ARtoS "$arg1"
Anim::ActivateLine ARtoS
Anim::AddClear ovals {line ARtoS} {text ARtoS}
}
}
proc ANIM_choose {line} {
if {[regexp {^input\('(.*)\)$} $line match arg1]} {
Anim::AddList recti $match
} elseif {[regexp {^comm-SK\(frame\('(.*), (.*)\)\)$} $line match arg1 arg2]} {
Anim::AddList ovals $match
} elseif {[regexp {^skip<(0|1|2)>$} $line match]} {
Anim::AddList rectk $match
} elseif {[regexp {^comm-KR\(frame\('(.*), (.*)\)\)$} $line match arg1 arg2]} {
Anim::AddList rectk $match
} elseif {[regexp {^comm-KR\((.*)\)$} $line match arg1]} {
Anim::AddList rectk $match
} elseif {[regexp {^output\('(.*)\)$} $line match arg1]} {
Anim::AddList ovalr $match
} elseif {[regexp {^comm-RAS\((.*)\)$} $line match arg1]} {
Anim::AddList ovalr $match
} elseif {[regexp {^comm-ASL\((.*)\)$} $line match arg1]} {
Anim::AddList ovalas $match
} elseif {[regexp {^skip<(3|4|5)>$} $line match]} {
Anim::AddList rectl $match
} elseif {[regexp {^comm-LAR\((.*)\)$} $line match arg1]} {
Anim::AddList rectl $match
} elseif {[regexp {^comm-ARS\((.*)\)$} $line match arg1]} {
Anim::AddList ovalar $match
}
}
Assuming the animation resides in file
cabp.tcl we can start
the animation with the command:
% simanim CABP.til cabp.tcl