350 likes | 423 Vues
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.
E N D
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