Jin Sa and Brian C. Warboys. Specifying concurrent object-based systems using combined specification notations. Technical Report UMCS-91-7-2, Department of Computer Science, University of Manchester, Manchester, UK, July 91.
See Incremental requirements specification and the constraint-oriented style in LOTOS for the background to this specification.
specification FileAccessSystem : noexit
library
Boolean, NaturalNumber, String, OctetString
endlib
type Op is Boolean, NaturalNumber
sorts Op
opns
open, read, write, close, save : -> Op
op0, op1, op2, op3 : -> Op
Ord : Op -> Nat
_ eq _, _ ne _ : Op, Op -> Bool
eqns
forall op1, op2 : Op
ofsort Nat
Ord (open) = 0;
Ord (read) = Succ (Ord (open));
Ord (write) = Succ (Ord (read));
Ord (close) = Succ (Ord (write));
Ord (save) = Succ (Ord (close));
Ord (op0) = Succ (Ord (save));
Ord (op1) = Succ (Ord (op0));
Ord (op2) = Succ (Ord (op1));
Ord (op3) = Succ (Ord (op2))
ofsort Bool
op1 eq op2 = Ord (op1) eq Ord (op2);
op1 ne op2 = not (op1 eq op2)
endtype (* Op *)
type Dir is NaturalNumber
sorts Dir
opns
inv, ret : -> Dir
Ord : Dir -> Nat
_ eq _, _ ne _ : Dir, Dir -> Bool
eqns
forall dir1, dir2 : Dir
ofsort Nat
Ord (inv) = 0;
Ord (ret) = Succ (Ord (inv))
ofsort Bool
dir1 eq dir2 = Ord (dir1) eq Ord (dir2);
dir1 ne dir2 = not (dir1 eq dir2)
endtype (* Dir *)
type Orig is NaturalNumber
sorts Orig
opns
t1, t2, app : -> Orig
Ord : Orig -> Nat
_ eq _, _ ne _ : Orig, Orig -> Bool
eqns
forall orig1, orig2 : Orig
ofsort Nat
Ord (t1) = 0;
Ord (t2) = Succ (Ord (t1));
Ord (app) = Succ (Ord (t2))
ofsort Bool
orig1 eq orig2 = Ord (orig1) eq Ord (orig2);
orig1 ne orig2 = not (orig1 eq orig2)
endtype (* Orig *)
type Octs is OctetString
opns
_--_ : OctetString, OctetString -> OctetString
eqns
forall o1, o2 : Octet, os1, os2 : OctetString
ofsort OctetString
<> -- os2 = <>;
os1 -- <> = os1;
o1 eq o2 =<
(o1 + os1) -- (o2 + os2) = os1 -- os2;
o1 ne o2 =<
(o1 + os1) -- (o2 + os2) = <>;
endtype (* Octs *)
behaviour
hide fh, t1, t2 in
Sys [fh, t1, t2]
where
process Sys [fh, t1, t2] : noexit :=
SysGen [fh]
||
FH [fh]
||
(
Appl [fh, t1, t2]
|[t1, t2]|
(T1 [fh, t1] ||| T2 [fh, t2])
)
where
process SysGen [fh] : noexit :=
SysOpen [fh]
|[fh]|
SysClose [fh]
|[fh]|
SysWrite [fh]
where
process SysOpen [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[(op eq open) implies (orig eq t1)];
SysOpen [fh]
endproc (* SysOpen *)
process SysClose [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[(op eq close) implies (orig eq t1)];
SysClose [fh]
endproc (* SysClose *)
process SysWrite [fh] : noexit :=
fh ! read ! inv ? octs : OctetString ! t1;
fh ? op : Op ? dir : Dir ? octs : OctetString ! t1;
SysWrite1 [fh]
[]
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[(op ne read) or (dir ne inv) or (orig ne t1)];
SysWrite [fh]
where
process SysWrite1 [fh] : noexit :=
fh ! read ! ret ? octs : OctetString ! t1;
SysWrite [fh]
[]
fh ? op : Op ? dir : Dir ? octs : OctetString ! t1
[(op ne read) or (dir ne ret)];
SysWrite1 [fh]
endproc (* SysWrite1 *)
endproc (* SysWrite *)
endproc (* SysGen *)
process FH [fh] : noexit :=
FHComm [fh] || FHOper [fh] || FHCall [fh] || FHData [fh]
where
process FHComm [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig;
FHComm [fh]
endproc (* FHComm *)
process FHOper [fh] : noexit :=
FHOpname [fh] || FHOpen [fh] || FHClose [fh] || FHSave [fh]
where
process FHOpname [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig;
FHOpname [fh]
endproc (* FHOpname *)
process FHOpen [fh] : noexit :=
fh ! open ! inv ? octs : OctetString ? orig : Orig;
FHOpen1 [fh]
where
process FHOpen1 [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[(op ne open) or (dir ne inv)];
FHOpen1 [fh]
endproc (* FHOpen1 *)
endproc (* FHOpen *)
process FHClose [fh] : noexit :=
FHClose1 [fh]
[>
fh ! close ! ret ? octs : OctetString ? orig : Orig;
stop
where
process FHClose1 [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[(op ne close) or (dir ne ret)];
FHClose1 [fh]
endproc (* FHClose1 *)
endproc (* FHClose *)
process FHSave [fh] : noexit :=
fh ! write ? dir : Dir ? octs : OctetString ? orig : Orig;
FHSave1 [fh]
[]
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[op ne write];
FHSave [fh]
where
process FHSave1 [fh] : noexit :=
fh ! save ? dir : Dir ? octs : OctetString ? orig : Orig;
FHSave [fh]
[]
fh ? op : Op ? dir : Dir ? octs : OctetString ? orig : Orig
[op ne save];
FHSave1 [fh]
endproc (* FHSave1 *)
endproc (* FHSave *)
endproc (* FHOper *)
process FHCall [fh] : noexit :=
fh ? op : Op ! inv ? octs : OctetString ? orig : Orig;
fh ! op ! ret ? octs : OctetString ! orig;
FHCall [fh]
endproc (* FHCall *)
process FHData [fh] : noexit :=
FHNotIO [fh] ||| ((FHRead [fh] ||| FHWrite [fh]) || FHFile [fh] (<>))
where
process FHNotIO [fh] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString
[(op ne read) and (op ne write)];
FHNotIO [fh]
endproc (* FHRead *)
process FHRead [fh] : noexit :=
fh ! read ! ret ? octs : OctetString ? orig : Orig;
FHRead [fh]
endproc (* FHRead *)
process FHWrite [fh] : noexit :=
fh ! write ! inv ? octs : OctetString ? orig : Orig [octs ne <>];
FHWrite [fh]
endproc (* FHWrite *)
process FHFile [fh] (octs : OctetString) : noexit :=
fh ! write ! inv ? octs1 : OctetString ? orig : Orig;
FHFile [fh] (octs ++ octs1)
[]
fh ! read ! ret ! octs ? orig : Orig;
FHFile [fh] (octs)
endproc (* FHFile *)
endproc (* FHData *)
endproc (* FH *)
process T1 [fh, t1] : noexit :=
T1Op1 [fh, t1] ||| T1Op2 [fh, t1] ||| T1Op3 [fh, t1]
where
process T1Op1 [fh, t1] : noexit :=
t1 ! op1 ! inv ! <> ! app;
fh ! open ! inv ? octs : OctetString ! t1;
fh ! open ! ret ? octs : OctetString ! t1;
t1 ! op1 ! ret ! <> ! app;
T1Op1 [fh, t1]
endproc (* T1Op1 *)
process T1Op2 [fh, t1] : noexit :=
t1 ! op2 ! inv ? octs1 : OctetString ! app;
fh ! read ! inv ? octs : OctetString ! t1;
fh ! read ! ret ? octs2 : OctetString ! t1;
fh ! write ! inv ! octs1 ! t1;
fh ! write ! ret ? octs : OctetString ! t1;
fh ! read ! inv ? octs : OctetString ! t1;
fh ! read ! ret ? octs3 : OctetString ! t1;
t1 ! op2 ! ret ! octs3 -- octs2 ! app;
T1Op2 [fh, t1]
endproc (* T1Op2 *)
process T1Op3 [fh, t1] : noexit :=
t1 ! op3 ! inv ! <> ! app;
fh ! close ! inv ? octs : OctetString ! t1;
fh ! close ! ret ? octs : OctetString ! t1;
t1 ! op3 ! ret ! <> ! app;
T1Op3 [fh, t1]
endproc (* T1Op3 *)
endproc (* T1 *)
process T2 [fh, t2] : noexit :=
t2 ! op0 ! inv ? octs : OctetString ! app;
fh ! write ! inv ! octs ! t2;
fh ! write ! ret ? octs : OctetString ! t2;
t2 ! op0 ! ret ! <> ! app;
T2 [fh, t2]
endproc (* T2 *)
process Appl [fh, t1, t2] : noexit :=
fh ? op : Op ? dir : Dir ? octs : OctetString ! app;
Appl [fh, t1, t2]
[]
t1 ? op : Op ? dir : Dir ? octs : OctetString ! app;
Appl [fh, t1, t2]
[]
t2 ? op : Op ? dir : Dir ? octs : OctetString ! app;
Appl [fh, t1, t2]
endproc (* Appl *)
endproc (* Sys *)
endspec (* FileAccessSystem *)
Up one level to University of Stirling - LOTOS Activities