lotos introduced through a worked example (drayton, chetwynd, blair circa 1990)
DESCRIPTION
LOTOS introduced through a worked example (Drayton, Chetwynd, Blair circa 1990). Communication systems form a large portion of safety critical systems These systems are usually large and constantly evolving. - PowerPoint PPT PresentationTRANSCRIPT
LOTOS introduced through a worked example (Drayton, Chetwynd, Blair circa
1990)• Communication systems form a large portion of safety critical
systems
• These systems are usually large and constantly evolving.
• A number of formalisms and development languages of communication systems have been developed.
• LOTOS (Language of Temporal Ordering Specification) is an international standard that lies heavily on the underlying Process Algebraic theory
• LOTOS was accepted as an ISO standard in 1988
Brief examples - 1
• As an example, we could define the following two processes
P_A[off_A, dial, connect] := off_A; dial; connect; …
P_B[off_B, ring, connect] := ring; off_B; connect; …
• This simple example corresponds to a normal telephone call setup.
• If we want the previous processes to execute in parallel and to synchronize through their common action connect, we may write
process P_A […] |[ connect ]| process P_B[…]
Brief Examples - 2
• Some execution sequences of the previous parallel composition of processes are
off_A; dial; ring; off_B; connect; …
off_A; ring; off_B; dial; connect; …
ring; off_A; dial; off_B; connect; …
LOTOS language fundamentals
• LOTOS language can be divided into two parts
Behaviour – concepts such as parameter passing, choice
non-determinism, sequential composition, etc.
Data- concepts of sorts, operations, renaming, actualization
• These will be further explained in the following slides
Parameter Passing
• For example, off ! id1 binds the id of the phone that was picked up to the variable id1
• Similarly, the expression off ? any_id: id_sort accepts all id’s as parameters. This form is typically used in representing non-deterministic behaviour
• It is possible to add arbitrarily many ! and ? operators to a single event. For example, dial ! id1 ? any_id:id_sort represents a situation where the phone id1 is picked up and it chooses non-deterministically a phone where to call.
Choice Operator
• Any reasonable language should be able to represent a choice between possible futures. In LOTOS this is done through the choice operator [].
dial ! ringtone; …
[]
dial ! engagedtone; …
Represents a choice between behaviours. Each behaviour must end with a special exit or stop keyword.
Non-Determinism
• For example dial ? any_id:id_sort represents non-deterministic behaviour where we bind an arbitrary identifier to the dial event
Example Process Definition
• The following is an example of a process definition in LOTOS
Process MakeCall [off, dial, connect, on] (phone_id:id_sort): exit :=
off ! dialtone ! phone_id;
((dial ! ringtone ! phone_id ? callee:id_sort;
connect ! phone_id ! callee;
on ! phone_id;
exit)
[]
(dial ! engagedtone ! phone_id ? callee:id_sort;
on ! phone_id;
exit))
endproc
Data Types in LOTOS
• The description of data is as important as the description of behaviour. The type definition is constructed as follows:
type Identifier is …
sorts ….
opns …..
eqns ….
• LOTOS has many predefined data types, such as NaturalNumber and Boolean
Data Types example
• Operations and Defining Equations are defined as follows
id_sort
opns id1, id2, id3 : -> id_sort /* constants */
NatRep: id_sort -> nat /* going from id1 to 1 */
_eq_, _ne_ : id_sort, id_sort -> Boolean /* equality */
eqns of sort nat
NatRep(id1) = succ(0);
NatRep(id2) = succ(NatRep(id1));
NatRep(id3) = succ(NatRep(id2));
Data Types Example Continued
• It is also possible to include variables in the defining equations
forall x, y: id_sort ofsort bool
x eq y = NatRep(x) eq NatRep(y);
x ne y = not(x eq y);
Renaming a Data Type
• LOTOS contains a predefined data type Set. If we want to utilize this to define a set (actually a list) of identifiers we have to declare a new data type and then give its actual definition
• The declaration is done by
type ListIds0 is Set renamedby
sortnames ListIds for Set
endtype
• Then we must define the data type ListIds0 as follows
type ListIds is ListIds0 actualizedby
Identifier using sortnames
id_sort for element
bool for fbool
nat for fnat
endtype
Parallel Composition of Dependent Processes
• If we want two processes to synchronize on ALL actions we may write
Phones[…]
||
Exchange[…]
• If we want to model interleaved behaviour (I.e. totally independent processes) we write
process Phones[…] : noexit :=
Phone[….] (id1)
|||
Phone[….] (id2)
|||
Phone[….] (id3)
Sequential Composition of Processes
• Some processes are related in such a way that the execution of one can start only after the other has finished (by the special action exit). In this case we talk of sequential composition
• For example, we may write
process Phone [….] (phone_id: id_sort): noexit :=
( MakeCall[….] (phone_id)
[]
ReceiveCall[….] (phone_id)
)
>> Phone[….] (phone_id)
endproc
Complete LOTOS example – Multiphone System
specification phone_system
[off, on, dial, cancel, ring, stop_ring, connect] : noexit
(* STANDARD LIBRARY TYPES INCLUDED *)
library Boolean, NaturalNumber, Set, DecNatRepr endlib
type Identifier is NaturalNumber
sorts id_sort
opns id1 (*! constructor),
id2 (*! constructor),
id3 (*! constructor),
anything (*! constructor) : -> id_sort
NatRep : id_sort -> Nat
SystemPhone : id_sort -> Bool
_eq_, _ne_, _lt_ : id_sort, id_sort -> Bool
Data Definitions - 2
eqns forall x, y : id_sort
ofsort Nat
NatRep(anything) = 0;
NatRep(id1) = succ(0);
NatRep(id2) = succ(NatRep(id1));
NatRep(id3) = succ(NatRep(id2));
Ofsort Bool
SystemPhone(anything) = false;
SystemPhone(x) = true; (* phones id1-3 are in system *)
x eq anything = true;
anything eq x = true;
x eq y = NatRep(x) eq NatRep(y);
x ne y = not(x eq y);
x lt y = NatRep(x) lt NatRep(y);
endtype
Data Definitions - 3
(* ------------------------------- *)
type PhonePair is Identifier, DecNatRepr
sorts PhonePair
opns _to_ (*! constructor) : id_sort, id_sort -> PhonePair
NatRep : PhonePair -> Nat
first, second : PhonePair -> id_sort
_eq_, _ne, _lt_ : PhonePair, PhonePair -> Bool
Data Definitions - 4
eqns forall a,b,c,d : id_sort, pair : PhonePair
ofsort Nat
NatRep(a to b) = (NatRep(a) * NatNum(1+Dec(0))) + NatRep(b);
ofsort id_sort
first(a to b) = a;
second(a to b) = b;
ofsort Bool
(a to b) eq (c to d) = (a eq c) and (b eq d);
(a to b) ne (c to d) = not((a eq c) and (b eq d));
(a to b) lt (c to d) = NatRep(a to b) lt NatRep (c to d);
endtype
Data Definitions - 5
(* ----------------------------------------- *)
type ListPairs0 is Set renamedby
sortnames ListPairs for Set
endtype
type ListPairs1 is ListPairs0 actualizedby PhonePair using
sortnames
PhonePair for Element
Bool for FBool
Nat for FNat
endtype
Data Definitions - 6
type ListPairs is ListPairs1
opns head : ListPairs -> PhonePair
tail : ListPairs -> ListPairs
fully_connect: id_sort, id_sort, ListPairs -> ListPairs
fully_remove : id_sort, ListPairs -> ListPairs
eqns forall x, y : id_sort, pair : PhonePair, list : ListPairs
ofsort PhonePair
(* note, head is never called with parameter {}. If it were
would need something like "head({}) = Null" where null
was a phone pair *)
head(Cons(pair, list)) = pair;
ofsort ListPairs
tail({}) = {};
tail(Cons(pair, list)) = list;
Data Definitions - 6
fully_remove(x, list) = Remove (x to anything
Remove(anything to x, list));
fully_connect(x,y, {}) = Insert(x to y, {});
x eq first(head(list)) =>
fully_connect(x,y,list) = Insert(second(head(list)) to y,
Insert(head(list),
fully_connect(x,y, tail(list))));
y eq first(head(list)) =>
fully_connect(x,y,list) = Insert(second(head(list)) to x,
Insert(head(list),
fully_connect(x,y,tail(list))));
(*... otherwise ...*)
fully_connect(x, y, list) = Insert(head(list),
fully_connect(x, y, tail(list)));
endtype
Data Definitions - 7
(* ------------------------------------- *)
type ListIds0 is Set renamedby
sortnames ListIds for Set
endtype
type ListIds is ListIds0 actualizedby Identifier using
sortnames
id_sort for Element
Bool for FBool
Nat for FNat
endtype
Data Definitions - 8
(* ------------------------------------------- *)
type Signal is
sorts Signal
opns dialtone (*! constructor)
ringtone (*! constructor)
engagedtone (*! constructor)
connect (*! constructor)
after_ringtone (*! constructor)
after_engaged_tone (*! constructor)
endtype
Behaviour - 1
Behaviour
Phones[off, on, dial, cancel, ring, stop_ring, connect]
||
Exchange[off, on, dial, cancel, ring, stop_ring, connect]
({} of ListIds, {} of ListPairs)
where
process Phones[off, on, dial, cancel, ring, stop_ring, connect]
: noexit :=
Phone[off, on, dial, cancel, ring, stop_ring, connect](id1)
|||
Phone[off, on, dial, cancel, ring, stop_ring, connect](id2)
|||
Phone[off, on, dial, cancel, ring, stop_ring, connect](id3)
endproc
Behaviour - 2
(* PHONE specifies the behaviour of a single phone *)
process Phone[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id:id_sort) : noexit :=
( MakeCall[off, on, dial, cancel, ring, stop_ring, connect] (phone_id)
[]
ReceiveCall[off, on, dial, cancel, ring, stop_ring, connect](phone_id))
>>
Phone[off, on, dial, cancel, ring, stop_ring, connect](phone_id)
endproc
Behaviour - 3
(* MAKECALL specifies the behaviour when someone makes a call *)
process MakeCall[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id:id_sort) : exit :=
off !dialtone !phone_id;
DialSomeone[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id)
endproc
Behaviour - 4
(* RECEIVECALL specifies the behaviour when someone receives a call *)
process ReceiveCall[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id:id_sort) : exit :=
ring ? caller : id_sort !phone_id;
((stop_ring !phone_id;
exit )
[]
(off ! connect ! caller ! phone_id;
DialSomeone[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id) ) )
endproc
Behaviour - 5
(* DIALSOMEONE specifies the behaviour when one phone dials another *)
process DialSomeone[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id:id_sort) : exit :=
( dial !ringtone !phone_id ?callee:id_sort;
NotEngaged[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id, callee))
[]
( dial !engagedtone !phone_id ?callee:id_sort;
Engaged[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id, callee))
[]
( on !phone_id;
exit )
endproc
Behaviour - 6
(* NOTENGAGED specifies the behaviour when the phone being dialled is not
engaged *)
process NotEngaged[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id, callee: id_sort) : exit :=
( on !after_ringtone !phone_id !callee;
exit )
[]
( connect ! phone_id ! callee;
on !phone_id;
exit; )
[]
( cancel !after_ringtone !phone_id !callee;
DialSomeone[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id) )
endproc
Behaviour - 7
(* ENGAGED specifies the behaviour when the phone being dialled is engaged *)
process Engaged[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id, callee : id_sort) : exit :=
( cancel !after_engagedtone !phone_id;
DialSomeone[off, on, dial, cancel, ring, stop_ring, connect]
(phone_id) )
[]
( on !phone_id;
exit )
endproc
Behaviour - 8
(* EXCHANGE specifies the behaviour to link the processes MakeCall and
ReceiveCall in the correct way *)
process Exchange[off, on, dial, cancel, ring, stop_ring, connect]
(engaged: ListIds, connections: ListPairs) : noexit :=
SubExchange
[off, on, dial, cancel, ring, stop_ring, connect]
(engaged, connections)
>>
accept engaged:ListIds, connections:ListPairs in
Exchange
[off, on, dial, cancel, ring, stop_ring, connect]
(engaged, connections)
endproc
Behaviour - 9
(* SUBEXCHANGE specifies how the lists are to be updated with each
possible action *)
process SubExchange[off, on, dial, cancel, ring, stop_ring, connect]
(engaged: ListIds, connections: ListPairs) : exit(ListIds, ListPairs)
:=
(* ( off !dialtone ?phone_id:id_sort; *)
( off !dialtone !id1;
exit(Insert(id1, engaged), connections))
[]
( on ?phone_id:id_sort;
exit(Remove(phone_id, engaged), fully_remove(phone_id, connections)))
[]
( on !after_ringtone ?from_id:id_sort ?to_id:id_sort;
stop_ring !to_id;
exit(Remove(from_id, engaged), fully_remove(from_id, connections)))
Behaviour - 10
[]
(* (dial !ringtone ?from_id:id_sort ?to_id: id_sort) *)
( dial !ringtone !id1 ?to_id:id_sort
[SystemPhone(to_id) and (to_id NotIn engaged)];
ring ! id1 ! to_id;
exit(engaged, connections))
[]
(*( dial !engagedtone ?from_id:id_sort ?to_id:id_sort)*)
( dial !engagedtone !id1 ?to_id:id_sort
[SystemPhone(to_id) and (to_id IsIn engaged)];
exit(engaged, connections))
[]
( cancel !after_ringtone ?from_id:id_sort ?to_id:id_sort;
stop_ring !to_id;
exit(engaged,connections) )
Behaviour - 11
[]
(off ! connect ? from_id:id_sort ? to_id:id_sort
connect ! from_id ! to_id;
exit(Insert(to_id, engaged), fully_connect(from_id, to_id, connections)))
[]
( cancel !after_engagedtone ?phone_id:id_sort;
exit(engaged, connections))
endproc
endspec
Afterthoughts
• LOTOS is an intuitive, programmer-friendly way of describing concurrent systems
• For some, the axiomatic style of data definition might seem like overkill
• One of the strengths of LOTOS is the fact that specifications do not require any special characters, but everything is found in ASCII.
• One publicly available LOTOS tool is LOLA =>
http://wwwtios.cs.utwente.nl/lotos/lotos-news/lnews_03/node70.html