An introduction to LOTOS through a worked example. Lynne Drayton, Amanda Chetwynd, Gordon Blair.
Distributed Multimedia Research Group, School of Engineering, Computing and Mathematical Sciences, Lancaster University, Bailrigg, Lancaster LA1 4YR, telephone: +44 (0)524 65201 e-mail:
[email protected] 24th September, 1991
Abstract
The practical application of formal description techniques (FDT's) is becoming increasingly important in computing. However, there remains a gulf in the literature between the language of application developers and the more theoretical language often used to describe formal methods. The aim of this paper is to try to bridge this gap by introducing the formal description technique, LOTOS, in a non-theoretical manner. The main features of LOTOS are introduced through a worked example, a speci cation of a multi-way phone system. This example was chosen because the speci cation is compact and yet is suciently complex to introduce most LOTOS features. Furthermore, the protocols involved in a multi-way phone are intuitive. The paper also stresses the importance of supporting tools in the development of formal speci cations and presents two tools, namely SEDOS and CSAR/ALDE BARAN, and explains why they are important in the speci cation process.
1 Introduction The topic of formal speci cation is becoming increasingly important in the areas of communications and distributed systems. As these subjects mature, there is an increasing demand for techniques that can unambiguously capture the behaviour of system components. This is particularly important in the standards world. Over the past few years, a number of formal description techniques (or FDT's) have emerged to meet this demand, including SDL [CCI81] and Estelle [ISO86]. This paper concentrates on one such technique, LOTOS which was accepted as an international standard by ISO in 1988. Since then, LOTOS, (Language Of Temporal Ordering Speci cation) has been widely applied in areas such as the speci cation of communication protocols [Fre89] and more recently in work on Open Distributed Processing [ISO89]. The aim of this paper is to give a rst level introduction to LOTOS for practising computer scientists and engineers. The emphasis of the paper is therefore on the use of the language rather than on the theoretical models underpinning LOTOS. This 1
The Tempo Project
2
is achieved by introducing LOTOS through a worked example, namely a multi-way phone system. For a more comprehensive tutorial of LOTOS we refer the reader to [Br87] or [Bol88]. For examples of other LOTOS speci cations see [GR90],[Gib90], [McP85],[Tvr89] and for telephone examples see [Ben89]and [FLS90]. The paper also introduces two of the available LOTOS toolkits (SEDOS and CSAR/ALDE BARAN) and explains why they are important in the development of correct LOTOS speci cations. The paper is structured as follows. Section 2 explains the background to the work presented in this paper. Section 3 then informally describes the required behaviour of the multi-way phone system we intend to specify. Following this section 4 introduces the basic features of LOTOS, drawing examples from the phone system. Both the process algebra and the abstract data type components are introduced in this section. Section 5 considers more advanced features of LOTOS, in particular the use of the parallel operator, explaining in greater detail parts of the speci cation of the phone system. Section 6 then deals with two of the available LOTOS toolkits, discussing how they can be used in the development of a speci cation. Finally section 7 draws some conclusions from the paper. A listing of the LOTOS speci cation of the multi-way phone system is given in Appendix A and a graph illustrating the behaviour of the system is given in Appendix B.
2 Background The Distributed Multimedia Research Group was established at Lancaster to consider the impact of multimedia on all areas of distributed computing, with emphasis on networks and protocols [SBHL91], and distributed systems architectures [BCDW91]. As part of this work, the Tempo Project1 is considering the requirements of formal methods for specifying distributed multimedia components. The main focus of this work is on the LOTOS language and, in particular, extensions to LOTOS to capture the temporal properties of multimedia protocols and architectures. The emphasis is on practical techniques which can help in the development of complex distributed multimedia systems and applications. The work reported in this paper was carried out in the rst phase of the Tempo project. This phase covered the following topics:1. familiarisation with LOTOS, 2. establishment of a comprehensive LOTOS toolkit, 3. derivation of requirements for distributed multimedia computing, and 4. studies of timed process algebras. This paper is a result of the rst two areas of work. Other aspects of Tempo are reported in [BM91].
3 A Multi-way Phone System 3.1 Rationale
As mentioned above, the aim of this paper is to provide a general introduction to LOTOS for computer practitioners not familiar with formal methods. The approach adopted is to introduce LOTOS features using an example speci cation. In order to meet our objectives, it is important that the chosen example is well understood and 1 The Tempo Project (full title Formal Support for the Speci cation and Construction of Distributed Multimedia Systems) is a three year project funded by the SERC/ DTI IED Programme and starting in October 1990.
An Introduction to LOTOS intuitive, otherwise the complexity of the example could detract from the understanding of the speci cation. In addition, the example must be sophisticated enough to introduce the most important features of LOTOS and yet should be suciently compact to avoid overloading the reader. The multi-way phone system described in this paper satis es all these criteria. The complete speci cation is quite small and yet is suciently complex to introduce a large subset of LOTOS. Most importantly, the protocols involved in setting up multi-way phone calls are generally well understood. Note that the speci cation is based on an actual implementation of a digital multiway phone system in operation at Lancaster. This phone system was developed to test the facilities provided by our underlying distributed multimedia platform. This phone is currently being extended into a general conference system with integrated video facilities. Our multi-way phone system will allow any number of people to participate in a phone call (for practical reasons this is limited to three in the speci cation). The number of people involved in a call can be increased by any member of the group dialling a new number. The new person on answering their phone will automatically be connected to all members of the original call. Similarly, the number of people participating in a call may decrease when one person in the group puts their phone down. The rest of the group remain connected.
3.2 Informal Speci cation
We want to model a phone system which will handle multi-party calls. To start with, we shall suppose that just two parties are involved in a conversation. This can then be extended to allow multi-party calls.
3.2.1 Properties of a two-party system 1. 2. 3. 4.
The state of a phone can either be on (on-hook) or o (o-hook). If a phone, say phone A, is lifted o to make a call, a dial tone occurs. A may now dial a second phone, say phone B. If phone B is engaged, A gets an engaged tone. Phone A must be placed on or the dial request cancelled before continuing. 5. If phone B is not engaged, A gets a ring tone and phone B starts ringing. 6. If B does not answer, phone A must be placed on or the dial request cancelled before continuing, (either of these cause phone B to stop ringing). 7. If B answers by lifting the phone o, a connection is made between phones A and B. A conversation may now occur (this conversation may be interrupted by any phone involved in the conversation being placed on).
3.2.2 Extra properties of a multi-party system
The above points can now be extended to allow more than 2 phones to be connected. We want to allow either one of the phones already connected to dial a third person. This should result in a three-way connection. Any one of these phones should then be allowed to dial. 8. During a conversation, either connected party may dial a third party. Suppose B dials C. 9. If C is engaged, B gets an engaged tone. B must then cancel this dial request before dialling again. A and B remain connected throughout. 10. If C is not engaged, B gets a ring tone and phone C starts ringing.
3
The Tempo Project
4
A
A h
h
]J
J
B h
h
C
(i) A and B connected
B
J^
h
h
C
(ii) Connections when C joins in
11. If C does not answer, B must cancel the dial request before dialling again. Again, A and B remain connected. 12. If C answers, a connection is made. The connections should represent the fully connected graph between the relevant phones (in this case, connect A to C as well as B to C). 13. If A, B and C are connected and one of them puts their phone on the other two phones remain connected.
4 LOTOS fundamentals
LOTOS (Language of Temporal Ordering Speci cation) is a speci cation language based on Process Algebraic Methods such as CCS [Mil80] and CSP [Hoa85]. There is also a second component to LOTOS, the abstract data type component. This component is based on the data typing language ACT ONE [EM85]. We will consider each in turn.
4.1 The process algebra component
The process algebra component deals with the description of processes, their behaviour and how they interact with other processes. The system to be speci ed can be viewed as one process which, in non-trivial examples, will be re ned into subprocesses. The system can thus be viewed as a hierarchy of interacting processes.
4.1.1 Simple interacting processes
Interaction of processes must occur through event gates (or just gates). The simplest form of interaction is pure synchronisation. Here no values are exchanged between the interacting processes. For example, consider a very simpli ed phone system consisting of just two phones (A and B). Suppose that these two phones can communicate directly with each other (i.e. there is no need for communications to go through an exchange).
An Introduction to LOTOS To model this system we will need the two processes (representing the two phones) to interact. Let the processes P A and P B model the behaviour of phones A and B respectively. A wants to be able to phone B, get a connection, then have a conversation. We can write the behaviour of phone A as: off_A; dial; connect; ...
and the behaviour of phone B as: ring; off_B; connect; ...
These two lines should be interpreted as follows. The words 'o A', 'o B', 'dial', 'connect' and 'ring' denote user de ned names for events. The ';' symbol is used to denote sequentiality. Therefore, in the rst line, the 'o A' event precedes the 'dial' event, which itself precedes the 'connect' event. In this case, although we want two distinct 'o' events (one for each phone), we want the two 'connect' events to in fact refer to the same event, namely the connecting of phones A and B. This can be achieved by the use of the parallel operator, |[ ... ]|. process P_A[off_A,dial,connect] |[connect]| process P_B[ring,off_B,connect]
Here we are saying that process P A can communicate with its environment through the event gates 'o A', 'dial' and 'connect' and that process P B can communicate with its environment through the event gates 'ring', 'o B' and 'connect'. This list of gate names is always written in square brackets immediately following the process name. The parallel operator |[ ... ]| links processes P A and P B by the 'connect' event gate. This means that if process P A oers a 'connect' event, it must rst wait until process P B oers a 'connect' event, i.e. no 'connect' event can occur unless it is oered by both processes. One possible behaviour of the two processes when combined as above is the intended behaviour: off_A; dial; ring; off_B; connect; ...
However, note that and
off_A; ring; off_B; dial; connect; ... ring; off_A; dial; off_B; connect; ...
are two alternative valid behaviours. With just two phones in the system, it does not make sense to say that phone B starts ringing before A has dialled. In a system with at least three phones though, phone B could start ringing as a result of being phoned by C for example. Note also that with just two phones it is quite clear between which phones the connection should be made. This is not the case when a system consists of three or more phones. This leads us to the idea of structured interactions through the use of events with values.
5
The Tempo Project
6
4.1.2 Structured interactions using events with values
So far all our events have simply named the event gate. In the above example however, we may wish to attach a value to the o event to indicate which phone is being lifted o. This can be written as off !id1
where !id1 is a value declaration showing that the o is happening to the phone with identi er 1. It is also possible to give variable declarations as well as speci c values. For example, dial ?any_id:id_sort
This statement means that any value from the sort id sort can be accepted by the dial event. Suppose the sort id sort contained the set of values fid1, id2, id3g. The above line can now be considered shorthand for the choice between events dial !id1, dial !id2 and dial !id3. Note that it is possible to use both '!' and '?' (or any number of each) with a single event. The order in which the parameters are given is signi cant. Therefore, for the dial event, we could attach two values, the rst to identify which phone is doing the dialling and the second to identify the phone being dialled. This would be written as dial !id1 ?any_id:id_sort
Synchronisation may occur only if the event oers are identical. This means that when events include values (as above) synchronisation may occur only if both the event gate and all attached values are identical. Therefore, the following two event oers will not synchronise:connect !id1
connect !id2
However, since '?any id:id sort' is equivalent to a choice of events from the set id sort, both of these event oers would synchronise with the event oer connect ?any_id:id_sort
since id1 and id2 belong to the sort id sort. This type of synchronisation is known as value passing. Similarly the following two event oers would synchronise:connect ?any_id:id_sort
connect ?any_other_id:id_sort
This last case is an example of value generation, the value on which to synchronise being chosen non-deterministically from the set id sort.
4.1.3 The Choice operator
To represent the choice between alternative behaviours in LOTOS we can use the LOTOS construct []. For example dial !ringtone;... [] dial !engagedtone;...
It is important to note that we have used ... to mean the rest of the behaviour expression, since [] is a choice of behaviours and not events. For this reason, each alternative behaviour must end with either a process de nition or one of the special processes exit or stop.
An Introduction to LOTOS
4.1.4 Non-Determinism
As mentioned in section 4.1.2 the notation dial ?any_id:id_sort can be considered as a choice of dial events, each parameterised with a dierent value from the sort 'id sort'. This choice may be resolved by interaction with the environment if, for example, the process synchronises with another process oering dial !id1. However in cases where the environment does not resolve the choice, the choice is made non-deterministically. That is, any of the alternative events may occur.
4.1.5 Example of a process de nition
We can now consider a more complete speci cation of the behaviour of a phone making a call. Informally, the behaviour can be described as follows.
Lift the phone o to get a dial tone. Attach the name of the phone (phone id) to this event (the value of which can be passed into the process). Dial another phone to get a ring tone or an engaged tone (depending on the state of the phone being dialled). Attach values to identify the phone doing the dialling and the phone being dialled. If the last event gave a ring tone, the next event for the phone should be a connect. Eventually the phone should then be placed on. If the last event gave an engaged tone, the next event should be an on. An on should be followed by an exit statement (to indicate the successful termination of the process).
Note that after each event we should allow for the possibility of the phone being placed on. This has been omitted here to keep the speci cation simple. (* The process MakeCall specifies the behaviour when a phone makes a call. *) 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
Comments Any text enclosed between the symbols '(*' and '*)' is regarded as a comment in LOTOS. If a process has any gates, they are listed inside square brackets following the process name. If a process has any parameters these are listed in round brackets following the gates.
7
The Tempo Project
8
The keyword exit in the process header gives the functionality of the process (the keyword noexit or exit(list of sorts ) may also be used here). In this case the functionality is exit, indicating that the process may terminate successfully. The functionality noexit should be used when the process cannot terminate, perhaps because it recursively calls itself. The keyword exit within the process body is a special process which represents successful termination (there is also a keyword stop which indicates inaction or deadlock).
4.2 The data typing component
The data typing component of LOTOS deals with the description of data structures. We have already introduced the idea of sorts above (when, for example, we referred to phone id:id sort). A sort is simply a set of data values whilst a type de nition is a set of sorts along with the operations that can be performed on them. We use as an example of a data type, the type Identi er used in the phone system. The basic format is as follows. type Identifier is ... (* other types to be imported into this type definition *) sorts ... (* names of all the sorts defined in this type *) opns ... (* names and functionality of all the operations that can be performed on the sorts *) eqns ... (* a list of equations that the operations above must satisfy *) endtype
These sections of the data type de nition must appear in the order given above.
4.2.1 Importing type de nitions
A list of previously de ned data types may be given after the keyword is. These data types may have been de ned either earlier in the speci cation or in the standard library (see below). All sorts, operations and equations from these imported types will then be imported into the type de nition being created. This allows complex type de nitions to be built up from smaller, simpler type de nitions. Note that a number of commonly used data types have been de ned as part of the ISO standard [ISO88]. These are de ned in a standard library and can be imported in the same way as user de ned data types. For the Identi er data type, we will need to import the NaturalNumber data type (to enable us to map our identi ers id1, id2 and id3 on to natural numbers) and the Boolean data type. However, NaturalNumber imports the Boolean type de nition so it is automatically imported when we include NaturalNumber.
4.2.2 Sorts
This section of the data type de nition contains a list of all the sorts to be de ned. For the Identi er data type, we will de ne just one sort, namely id sort.
4.2.3 Operations
This section contains all the operations which may be performed on id sort. An operation is a function, taking zero or more sorts as its domain, but always returning exactly one sort as its codomain. Operations are de ned by their signature. For example,
An Introduction to LOTOS opns id1, id2, id3 NatRep _eq_, _ne_
9 : -> id_sort : id_sort -> nat : id_sort, id_sort -> bool
Comments Operations with no domain sort (such as id1, id2 and id3) are called constants. By default, operations are pre x, i.e. the operation name precedes the parameters (as with NatRep above). Operations can be de ned as in x, by placing ' ' symbols around the operation name (as with eq and ne above).
4.2.4 Equations
The equations de ne the constraints which the operations must satisfy. For example, we can de ne the natural number representation of an identi er, NatRep, as follows. eqns ofsort nat NatRep(id1) = succ(0); NatRep(id2) = succ(NatRep(id1)); NatRep(id3) = succ(NatRep(id2));
(* id1 -> 1 *) (* id2 -> 2 *) (* id3 -> 3 *)
Comments The keyword ofsort de nes the result sort of the equations. In this case all our equations return a natural number. The operation succ is de ned in NaturalNumber along with the constant 0. These operations can be used since we imported NaturalNumber into our type de nition. Variables can be used in equations to represent any value from a given sort. For example, forall ofsort x eq y x ne y
x,y:id_sort bool = NatRep(x) eq NatRep(y); = not(x eq y);
Comments The statement forall x,y:id_sort means that x and y can take any value from the given sort. So, the equations above are de ned for any possible pair of identi ers from sort id sort. The left hand side of the equation (left of the '=' symbol) is the operation being de ned and the right hand side (right of the '=' symbol) de nes the value the operation will take. In the example above, if NatRep(x) eq NatRep(y) then the right hand side is true, so the left hand side takes the value true.
4.2.5 Renaming of data types
All the examples above, have dealt with the de nition of new data types. However it is possible to simply rename an existing data type. For example, the phone example requires a list of those phones which are currently engaged. The standard library already contained the de nition for a set, so it was decided to just rename this type (and also add additional features). The new type has been called ListIds0 since it is not the nal version of the type ListIds. type ListIds0 is Set renamedby sortnames ListIds for Set endtype
The Tempo Project
10
Comments Note that as well as renaming sortnames it is also possible to rename operations. (Use a line such as opnnames NewOpn for OldOpn.)
4.2.6 Actualization
Sometimes, it is convenient to write 'generic' data types. That is, data types such as queues and sets which could take various data sorts. For example, it is convenient to de ne the Set data type using a formal parameter to represent the elements of the set. This set could then be actualized by using natural numbers for the element. In this way, the de nition of a set can be re-used instead of having to repeat the operations and equations if, for example, a set of characters was also required. As mentioned in the above section, we required a list of identi ers (representing those phones that were engaged). To create this type Rename the sort Set as ListIds, as shown above. Call this new type ListIds0 Actualize ListIds0 with the Identi er type and say which sort names replace the formal parameters, as shown below. type ListIds is ListIds0 actualizedby Identifier using sortnames id_sort for element bool for fbool (* see second note below *) nat for fnat (* " " *) endtype
Comments It is also possible to have formal operations and equations as well as sorts, (see [Bol88] for details on how types with formal parameters are de ned). The SEDOS version of the standard library Set data type that we used required the use of the formal sorts fbool and fnat in its equations. These must be actualized by the sorts bool and nat respectively. This material is beyond the intended level for this introductory paper, but has been included above for completeness.
5 Further LOTOS
5.1 More process de nitions
In section 4.1.5 we gave a slightly simpli ed form of the MakeCall process. To write a process to model the behaviour of a phone receiving a call, we need to re-use the part of the code dealing with the dial event (since any phone involved in a conversation may dial other phones). So we could rewrite our MakeCall process as below (omitting the gate lists for brevity). (* The process MakeCall specifies the behaviour when a phone makes a call. *) process MakeCall[ ... ](phone_id:id_sort):exit:= off !dialtone !phone_id; DialSomeone[ ... ](phone_id) endproc
(* The process DialSomeone specifies the behaviour
An Introduction to LOTOS when one phone dials another. This process is called by both MakeCall and ReceiveCall. *) process DialSomeone[ ... ](phone_id:id_sort):exit:= ( dial !ringtone !phone_id ?callee:id_sort; connect !phone_id !callee; DialSomeone[ ... ](phone_id) ) [] ( dial !engagedtone !phone_id ?callee:id_sort; on !phone_id; exit ) [] ( on !phone_id; exit ) endproc
Now we can write our process for receiving a call. Informally, The phone starts ringing (as a result of being called by another phone). The phone can then either stop ringing or it could be picked up to answer the call. If the phone stops ringing, the process should terminate successfully (through an exit). If the phone is answered, a connection is made. The phone should now be allowed to dial other phones. (* The process ReceiveCall specifies the behaviour when a phone receives a call. *) process ReceiveCall[ ... ](phone_id:id_sort):exit:= ring !phone_id; ( ( stop_ring !phone_id; exit ) [] ( off !connect !phone_id; DialSomeone[ ... ](phone_id) ) ) endproc
The behaviour of the phone is now either that of process MakeCall or that of process ReceiveCall. Both of these processes exit, but we want a phone to be able to make or receive more than one call. To do this, we can use the enable (or sequential composition) operator >>. (* The process Phone specifies the behaviour of a single phone. The behaviour can either be that of MakeCall or ReceiveCall. *) process Phone[ ... ](phone_id:id_sort):noexit:= ( MakeCall[ ... ](phone_id) [] ReceiveCall[ ... ](phone_id) )
11
The Tempo Project
12 >> Phone[ ... ](phone_id) endproc
Comments The >> operator means that upon the successful termination of MakeCall or ReceiveCall (depending on which path through the speci cation was taken), the process Phone is enabled. Note that should MakeCall or ReceiveCall not terminate successfully (i.e. the process does not exit), then Phone will not be enabled. The functionality of the Phone process has been declared as noexit since it cannot terminate. If MakeCall or ReceiveCall terminate successfully then Phone is called, resulting in a 'loop forever' situation.
5.2 Use of the parallel operators
Unlike the rst simpli ed version of a phone system that we gave, phones cannot communicate directly with each other. Instead, all communications must go through an exchange. To model this we will use the two special forms of the parallel operator |[ ... ]|, parallelism of independent processes (|||) and parallelism of dependent processes (||).
5.2.1 Parallelism of independent processes
The phones in our system can be modelled as interleaved processes. This is represented in LOTOS by the operator ||| which behaves as the general parallel operator used with an empty gate list. This operator does not alter the order of events in a single process, but events from dierent processes may be interleaved in any order. For example, a; b; ... ||| c; d; ...
could result in any of the six behaviours below. or
a; b; c; d c; a; b; d
or or
a; c; b; d c; a; d; b
or or
a; c; d; b c; d; a; b
Now we can write a process Phones which models the behaviour of all the phones in the system. process Phones[ ... ]:noexit:= Phone[ ... ](id1) ||| Phone[ ... ](id2) ||| Phone[ ... ](id3) endproc
Comments id1, id2 and id3 are parameters of the Phone process. This means that the three (independent) phone processes can be distinguished by their phone identi er.
5.2.2 Parallelism of dependent processes
We want to model the exchange so that all communications between phones go through it. This means that we must make the exchange synchronise with every gate from the (interleaved) phones which is to be used for communication. In our example, this is all the gates. To achieve this we could use the general parallel operator |[ ... ]| and list
An Introduction to LOTOS all the gates, but there is shorthand notation for this in LOTOS, namely the operator ||. Although we have not yet de ned the Exchange process, we know that it must control the overall behaviour of the system. We can say that this overall behaviour should be Phones[ ... ] || Exchange[ ... ]
since we have said that every gate in the phone processes must be synchronised with the exchange. All that is left for us to specify now is the Exchange process. As stated above, it is this process which controls the overall behaviour of the system. To do this, it must maintain a list of those phones which are currently engaged. It is also useful (for a future implementor of the system) to maintain a list of connections. This must re ect the fact that when C joins an existing conversation between A and B, the list of connections change from fA to Bg to fA to B, B to C, A to Cg. We chose to describe the Exchange process as a list of alternative behaviours, each of which resulted in the two lists being updated (when necessary). The most obvious way to maintain these lists seemed to be through the use of the exit(list of values) construct, followed by an enable in which this list of values was passed to the Exchange process again. This value passing is achieved by use of the accept list of values in ... construct. For example, process Exchange[ ... ](engaged:ListIds, connections:ListPairs):noexit:= SubExchange[ ... ](engaged, connections) >> accept engaged:ListIds, connections:ListPairs in Exchange[ ... ](engaged, connections) endproc process SubExchange[ ... ] (engaged:ListIds, connections:ListPairs) :exit( ListIds, ListPairs ):= ... (* a list of alternative behaviours, each of which end with the statement exit( new_engaged, new_connections ) where new_engaged and new_connections are the updated lists. *) endproc
Comments Note that the functionality of the SubExchange process is exit(ListIds, ListPairs ). This means that the process will terminate successfully and will exit with the values new engaged and new connections. To accept these two values in Exchange, it is necessary to state the sort of the values.
13
The Tempo Project
14
5.3 Selection Predicates
The predicate is a way of imposing restrictions on the values that are allowed in the variable declaration. When we dial a phone we want the phone to have a dierent action depending on whether or not it is engaged. dial !ringtone ?from_id:id_sort ?to_id:id_sort [SystemPhone (to_id) and (to_id Notin engaged)]
or dial !engagedtone ?from_id:id_sort ?to_id:id_sort [SystemPhone (to_id) and (to_id Isin engaged)]
Comments SystemPhone(x) is a user-de ned data type operation which returns true or false, depending on whether the parameter x is a valid phone in the system or not. Assuming we have a valid system phone, if the phone dialled is not in the engaged list then we obtain a ringtone. Otherwise, if the phone dialled is in the engaged list, we obtain an engaged tone.
5.4 The Complete Speci cation
The complete speci cation of the phone system can be found in Appendix A. The speci cation is annotated throughout by comments enclosed by (* and *). For reasons explained below, the speci cation has been modi ed so that only phone id1 is allowed to initiate a call, the modi ed lines being marked by (*