SOFTWARE VERIFICATION RESEARCH CENTRE DEPARTMENT OF COMPUTER SCIENCE THE UNIVERSITY OF QUEENSLAND Queensland 4072 Australia TECHNICAL REPORT No. 95-15 A Modular Extension to Z for Specification , Reasoning and Refinement Ed . Kazmierczak , Peter Kearney , Owen Traynor and Li Wang February 1995 Phone : +61 7 3365 1003 Fax : +61 7 3365 1533 Note : Most SVRC technical reports are available via anonymous ftp , from ftp.cs.uq.edu.au in the directory / pub/SVRC/techreports . A Modular Extension to Z for Specification , Reasoning and Refinement Ed . Kazmierczak ? , Peter Kearney , Owen Traynor and Li Wang Software Verification Research Centre , y Department of Computer Science , The University of Queensland , Qld . 4072 , Australia . Abstract We introduce the concept of modules for the Cogito specification language , SL1 -LRB- a variant of Z -RRB- . An outline of the module reference mechanism , parameterisation and access methods is presented . Some illustrative examples and rationale are included and the advantages of the module concept in the context of reasoning and refining Z specifications are discussed . We pay particular attention to the additional features of SL1 which are designed to support refinement and reasoning about specifications . Also we provide a structural translation of SL1 modules to Ada packages which is the basis for a fuller translation of code level specifications to Ada code . 1 Introduction Modularity is crucial to the management of the software development process . It is the most important mechanism for managing complexity , achieving a separation of concerns and isolating changes . However , the features for achieving modularity must be chosen carefully since they have wide ranging repercussions . As well as providing a means for structuring specifications , modularity also has implications for refinement and for structuring the associated theories for reasoning . In our system , the key unit for maintenance of both specifications and proofs is the specification module . The Cogito methodology and system -LSB- BKKT94 -RSB- has the Z-based specification language SL1 at its core . The omission of high-level structuring mechanisms in Z -LSB- Spi92 -RSB- was seen as a major deficiency if Z was to be used for large scale development . This , in combination with other deficiencies of the Z formalism and the need to include programming language constructs prompted the design of SL1 . SL1 modules are managed by associating modules with units in a library . The importation information in a specification contributes to configuration information at the library level -LSB- Tra94 -RSB- . The library , and its associated dependency information , is managed by the Cogito repository manager . The repository manager maintains various types of dependencies between specifications , theories and proofs as well as other artifacts of the software development process . ? Correspondence to E. Kazmierczak . E-mail : eka@cs.uq.oz.au . Phone : +61 -LRB-07-RRB- 3651642 . Fax : +61 -LRB-07-RRB- 365 1533 . yThis work was supported by Special Research Centre Funding from the Australian Government The design of SL1 modules has been partly influenced by the fact that specifications will be developed to Ada -LSB- US 83 -RSB- code . The transition from detailed designs to implementations in Ada should be as straightforward as possible , with the modular structure of the detailed designs implying a package structure for the Ada implementations . Without these features , the projection to Ada implementations would require complex analysis and translation rules in order to ensure correct Ada is produced . The module mechanism is also minimal , in that extensions may be made to accommodate languages whose module reference semantics are more liberal than those used here . If a more liberal approach were taken , languages with a stricter notion of module reference would be very difficult to accommodate . The modular structure of the final program is not necessarily defined by the modular structure of the initial specification -LSB- Kaz92 -RSB- . Changes to the modular structure of specifications may be made in the process of refinement to detailed designs and implementations . Modules in SL1 perform two roles . First , they provide an encapsulation mechanism which allows a state and its associated operations to be defined -LRB- conceptually corresponding to a state machine -RRB- . Second , they define the theory in which that machine can be reasoned about . Thus , modules structure the specifications and define a theory structure for reasoning about the properties of the specifications . The specification structuring features are a significant benefit in the later stages of design and in constructing implementations from detailed designs . In this paper the graphical representation of the syntax of SL1 is used , based on the Object-Z representation for classes -LSB- DKRS91 -RSB- . An ASCII syntax may also be used , tools are available which translate the ASCII to the graphical notation . 1.1 Related Work There are a number of other language design efforts which have added higher level structuring to Z . In particular , extending Z with object orientation is a popular activity -LRB- for example , Object-Z -LSB- DKRS91 -RSB- , Z + + -LSB- Lan91 -RSB- -RRB- . One of the main reasons that such an approach was not taken with SL1 is that the technology for reasoning about such object-oriented specifications is a subject of ongoing research . None of these languages have a mature formal definition . In addition , there is no consensus as to appropriate formal refinement methods for the development of object oriented specification . Other approaches to structuring Z specifications -LSB- Hay92 -RSB- are rather more sophisticated than required for development to code -LRB- in fact they make translation or projection to languages such as Ada quite difficult -RRB- . These approaches tend to have general and powerful notions of structure which admit , for example , partial parameterisation of modules . Again , these approaches do not have well defined semantics as yet , and support for reasoning about such specification is only touched upon in their definitions . Conversely , the SL1 module concept is relatively simple . Construction of the theories generated from specification modules is relatively painless and translation of the modular structure of detailed designs , expressed in SL1 , to implementation language equivalents is straightforward . 2 The basic forms of modules Modules provide a means of grouping together and accessing related declarations and definitions . In its simplest form , a module is simply an encapsulation of a sequence of declarations . The chief mechanism for referencing other modules is import . Import brings into scope , but does not make visible , the entities declared in the referenced module . Entities in a referenced module may be accessed via qualified names . A qualified name A : f consists of a module name A followed by the name of the entity f defined in A which is to be accessed . If the referenced module imports other modules then these too are in scope and the entities contained therein may also be accessed via qualified names . 2.1 Simple Import SL1 provides several forms of import , the first of which is a simple import . The other forms of import allow renaming on import -LRB- see section 2.3 -RRB- and instantiating parameterised modules on import -LRB- see section 2.4 -RRB- . An example of a simple import is given in Figure 1 where the module Squaring is imported into the module Circle . All the entities in Squaring are in scope in module Circle and can be accessed by prefixing the name of the entity with the name of the module from which it is exported . Thus , Squaring.sqr refers to sqr in the module Squaring . Squaring sqr ; sqrt : N ! N 8 x : N ffl sqr -LRB- x -RRB- = x ? x ; 8 x ; k : N ffl -LRB- sqr -LRB- k -RRB- < = k -RRB- ^ -LRB- sqr -LRB- k + 1 -RRB- > x -RRB- -RRB- sqrt -LRB- x -RRB- = k Circle import Squaring ; area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = -LRB- Squaring : sqr -LRB- radius -RRB- ? 22 -RRB- = 7 Figure 1 : Simple import . Allowing entities in modules to be referenced solely by means of qualified names is excessively cumbersome in practice . To alleviate this problem SL1 also provides a visible declaration which makes entities in an imported module directly accessible without the need for a qualified name though the qualified name can still be used if desired . It does not make the entities in transitively imported modules visible . Thus in SL1 the visible declaration is non-transitive . For example , in module Cylinder in Figure 2 the addition of the declaration visible Circle means that we can reference the entity area in Circle directly without qualification but we can not access the entities sqr and sqrt of Squaring directly . Squaring is transitively imported into Cylinder but is not transitively visible . The entities sqr and sqrt however , are in scope and may be accessed via qualified names -LRB- for example Circle.Squaring.sqr or Squaring.sqr -RRB- . Cylinder -LRB- ? ? Properties of a fixed length cylinder ? ? -RRB- import Circle ; visible Circle ; length : N cylinder area : N ! N 8 radius : N ffl cylinder area -LRB- radius -RRB- = 2 ? area -LRB- radius -RRB- + -LRB- 2 ? radius ? length ? 22 -RRB- = 7 Figure 2 : Making entities of an imported module visible . Note that the majority of the languages which will be the focus of development will have non-transitive reference mechanisms at the module level -LRB- cf. Ada , Modula2 -RRB- . Non-transitivity of visible declarations may cause the importation and visibility parts of module definitions to be more verbose than would be the case if all imported items were immediately made visible , but this mechanism does contribute significantly to the narrowing of the module interface . This does not exclude modules from promoting the visibility of an imported entity to the exported interface of the module . Again , this is simply more verbose than would be the case in the transitive counterpart . Enforcing non-transitivity also has implications for theory generation and the associated deduction mechanisms . This is discussed in more detail later . Cylinder import Circle ; visible Circle ; length : N area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = 2 ? Circle : area -LRB- radius -RRB- + -LRB- 2 ? radius ? length ? 22 -RRB- = 7 Figure 3 : Linear visibility . Visibility of imported entities is linear . If two entities are in scope and visible and have the same unqualified name then the directly visible entity is the most recently declared of the two . In Figure 3 another entity called area is declared in module Cylinder0 . This entity hides the function area already declared in Circle even though it is declared to be visible in Cylinder0 . The function area in Circle is still in scope and can be accessed by using its qualified name . 2.2 Nesting Modules Modules may be nested . When a nested module -LRB- submodule -RRB- is defined , previous declarations from the enclosing module -LRB- s -RRB- are visible within the submodule . After the declaration of the submodule , the module name is visible , but not the entities declared within the submodule . To make the declared entities of the submodule visible , a visible declaration may be used . Figure 4 gives an example of a nested module . Outside the enclosing module , the name of a submodule is brought into scope by importing its enclosing module . However , the entities of the submodule are not directly visible . An explicit visible declaration is required to make the submodule entities visible . This provides a convenient means of hiding some details of a module within a nested module . 2.3 Narrowing Interfaces and Renaming Methodologically , the interface to a module should be as narrow as possible . Selectively making some , but not all , components of an imported module visible is possible in SL1 by explicitly including in the visibility declaration the entities to be made visible from the referenced module . This is illustrated in Figure 5 where sqr in Squaring is made visible but sqrt is not . Circle Squaring sqr ; sqrt : N ! N 8 x : N ffl sqr -LRB- x -RRB- = x ? x ; 8 x ; k : N ffl -LRB- sqr -LRB- k -RRB- < = k -RRB- ^ -LRB- sqr -LRB- k + 1 -RRB- > x -RRB- -RRB- sqrt -LRB- x -RRB- = k visible Squaring ; area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = -LRB- sqr -LRB- radius -RRB- ? 22 -RRB- = 7 Figure 4 : A nested module . Circle import Squaring ; visible Squaring -LSB- sqr -RSB- ; area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = -LRB- sqr -LRB- radius -RRB- ? 22 -RRB- = 7 Figure 5 : Narrowing a module interface through selective visibility . A module M may be instantiated with a specified name S , which declares a new module S as a distinct copy of the module M . The names of the declared entities of S are qualified by the new module name . This is illustrated in Figure 6 , which imports Squaring , instantiating it as the module S . The entities S : sqr and S : sqrt are available for use . Of course , a visible S declaration could be used to permit abbreviated reference to those entities . The implications of instantiation for reuse of state-based specifications is discussed in section 3 . Circle import Squaring as S ; area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = -LRB- S : sqr -LRB- radius -RRB- ? 22 -RRB- = 7 Figure 6 : Simple instantiation . When a module is instantiated , entities of the module may be re-named . For example , Figure 7 illustrates the importation and instantiation of Squaring with the entity sqr renamed to f . Circle import Squaring -LSB- f = sqr -RSB- as S ; visible S ; area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = -LRB- f -LRB- radius -RRB- ? 22 -RRB- = 7 Figure 7 : Instantiation with renaming . 2.4 Parameterisation Modules may be parameterised with a restricted set of entities . These entities include given sets -LRB- types -RRB- and operations as well as any entity already defined in the SL1 mathematical toolkit . For example , Figure 8 shows part of a sort module parameterised by the type of object to be sorted , the ordering relation on the items to be sorted , and the ordering relation to be used on item indices . Note that all entities within a parameterised module which rely on one of the formal parameters to that module are , in the Z sense , themselves generic . Sort -LRB- Item ; ord : Item ? Item ! bool ; nord : N?N ! bool -RRB- sorted : seq Item ! bool sorted -LRB- hi -RRB- 8 L : seq Item ffl L < > hi -RRB- sorted -LRB- L -RRB- , -LRB- 8 i ; j : domL ffl nord -LRB- i ; j -RRB- -RRB- ord -LRB- L -LRB- i -RRB- ; L -LRB- j -RRB- -RRB- ... Figure 8 : A parameterised module . Instantiation of the module is required for the instantiation of the internal entities . When a parameterised module is referenced , it must be fully instantiated . Partial instantiation , where some of the module parameters are left uninstantiated , is not available in SL1 . UseSort import Sort -LRB- N ; < = ; < = -RRB- as SortNats ; ... Figure 9 : Instantiating a parameterised module . Figure 9 shows the import and instantiation of the Sort module with specific parameters . Instantiation and renaming may be combined , as illustrated in Figure 10 , where sorted is renamed to natsorted . 3 Support for the Cogito Methodology UseSort import Sort -LRB- N ; < = ; < = -RRB- as SortNats -LSB- natsorted = sorted -RSB- ; ... Figure 10 : Instantiating a parameterised module with renaming . SymTab -LRB- SYM ; VAL ; k : N -RRB- SType == SYM 7 7 ! VAL State st : SType # -LRB- dom st -RRB- < = k Init st = f g OP Update s ? : SYM v ? : VAL -LRB- # -LRB- dom st -RRB- < k -RRB- ^ -LRB- s ? 62 dom st -RRB- st = st ? fs ? 7 ! v?g OP Lookup s ? : SYM v ! : VAL s ? 2 dom st v ! = st -LRB- s ? -RRB- changes only -LRB- fg -RRB- Figure 11 : SL1 specification of simplified symbol table In addition to the basic forms of modules described in section 2 , SL1 provides constructs which explicitly support the Cogito system specification and program development methodology -LSB- BKKT94 -RSB- . In Cogito , systems are specified by defining the set of allowable states , the initial state of the system and the operations which may change the state , just like in Z . One difficulty with Z however , is that it does not provide an explicit mechanism for stating what roles individual schemas play in the overall specification . Consequently when developing tools to support specification and refinement one Z schema in a specification looks much like another . Refinement in Cogito occurs between modules and is intended to reflect a refinement of one state machine , specified by an SL1 module , by another state machine which is also specified by an SL1 module . In formalising the refinement relation it is important to know the role that schemas play in the specification . Consequently , we distinguish between state , initialisation , operation and auxiliary schemas in SL1 specifications . The notation presented below is used during the software develop - ment process to generate the appropriate proof obligations for refinement . The semantics of schemas however , remains unchanged . 3.1 Formalising state machines In SL1 , a module may define a state machine , which consists of a state schema , an initialisation schema , and a number of operation schema . In defining these components , auxiliary schema may be used . A simple example is shown in Figure 11 which shows a parameterised module defining a simple symbol table . The state schema is distinguished by being named with the reserved identifier State . The initialisation schema is identified by the reserved identifier Init . The Init schema implicitly includes a dashed copy of the State schema . Thus the Init schema in full for the example of Figure 11 is : Init st : SType # -LRB- dom st -RRB- < = k st = f g This treatment of initialisation accords with the fact that an initialisation is required to establish the state invariant , but is not entitled to assume it ; the ` old ' state is not available . Note that we use dashed variables for the initial state here , as in -LSB- Wor92 -RSB- . The motivation for this is that in general an initialisation may need to be refined to the code which establishes it , and the use of the dashed convention allows a uniform treatment of refinement of initialisation and other operations . The schemas Update and Lookup are identified as operations of the state machine defined by this module by using the keyword OP . An operation schema implicitly includes the State schema , and a copy of the State schema in which all components are dashed . Thus , in fully explicit form , the operation schema Update is : Update s ? : SYM v ? : VAL st ; st : SType -LRB- # -LRB- dom st -RRB- < k -RRB- ^ -LRB- s ? 62 dom st -RRB- st = st ? fs ? 7 ! v?g # -LRB- dom st -RRB- < = k # -LRB- dom st -RRB- < = k Note that operation schemas have a three-part structure : a signature and two predicates . The first predicate is an explicit precondition . To preserve compatibility with the schema calculus , a schema with explicit precondition is not treated semantically as a new form of schema . Rather , the explicit precondition is conjoined with the rest of the schema . Thus Update here is equivalent to : Update s ? : SYM v ? : VAL st ; st : SType -LRB- # -LRB- dom st -RRB- < k -RRB- ^ -LRB- s ? 62 dom st -RRB- st = st ? fs ? 7 ! v?g # -LRB- dom st -RRB- < = k # -LRB- dom st -RRB- < = k However , the Cogito toolset generates a proof obligation that the stated precondition , in conjunction with the state invariant , implies the calculated precondition of the schema . Discharging this proof obligation acts as a useful check on the consistency of the specification . If this proof obligation is satisfied , the stated precondition , in conjunction with the state invariant , is equivalent to the exact precondition of the operation . Having the exact precondition available is very useful in refinement , since refinement proof obligations often refer to the precondition of an operation . The notation changes only fg in the operation Lookup asserts that no state variables change . Here the only state variable is the state component st . Thus in this context changes only fg is equivalent to st = st . In general , the notation changes only S asserts that for all variables v in the signature such that there is a dashed counterpart v in the signature with the same type , and such that v does not occur in S , v = v . This notation has been introduced to provide a compact and flexible way of asserting that parts of the state remain unchanged . Generally it is more compact to list the variables which may change , as in the changes only predicate , rather than those which do not . A variant of the changes only notation allows the use of a schema as an argument . If S is a schema , then changes only S is equivalent to changes only V where V is the set of variables in the signature of S . 3.2 Schema variables and modules Schema variables in different modules are defined in different name spaces . The full name of a schema variable v appearing in a module M is M : v . The usual visibility mechanisms can be used to enable elision of the module name part . Because schema variables from different modules are distinct , there can not be unintended clashes between schema variables declared in different modules . Distinctness of schema variables from different modules also means that , as a default , the states of imported module instances are not merged . Consider the example module in Figure 12 which defines a state machine consisting of two symbol tables . It uses one symbol table to store negative key values and the other to store positive key values . Note that the state declaration for TwoSyms includes both state schemas from s1 and s2 . Thus the state has access to variables st1 : st and st2 : st . This kind of apartness for state components is what is most commonly required in building up a composite state from components . In the more unusual situation in which state merging is required , this can be achieved by renaming the schema variables of imported schema to new , common schema variables . Renaming is used in the operations of Figure 12 . For example , the operation Update uses either st1 : Update or s2 : Update , depending on whether its argument s ? is positive or not . The variables s ? and v ? of Update are new and defined in the current module TwoSyms . -LRB- Their underlying names are TwoSyms : s ? and TwoSyms : v ? -RRB- . They are distinct from the variables st1 : s ? and st1 : v ? of st1 , for TwoSyms import SymTab -LRB- Z ; string ; 200 -RRB- as st1 ; import SymTab -LRB- Z ; string ; 50 -RRB- as st2 ; State st1 : State ; st2 : State Init st1 : st = f g st2 : st = f g OP Update s ? : Z v ? : string -LRB- s ? > ^ # -LRB- dom st1 : st -RRB- < 200 ^ -LRB- s ? 62 dom st1 : st -RRB- -RRB- _ -LRB- s ? < = ^ # -LRB- dom st2 : st -RRB- < 50 ^ -LRB- s ? 62 dom st2 : st -RRB- -LRB- s ? > -RRB- changes only fst1 : Stateg ^ st1 : Update -LSB- s ? = st1 : s ? ; v ? = st1 : v ? -RSB- -RRB- -LRB- s ? < = -RRB- changes only fst2 : Stateg ^ st2 : Update -LSB- s ? = st2 : s ? ; v ? = st2 : v ? -RSB- -RRB- OP Lookup s ? : Z v ! : string s ? < ^ s ? 2 dom st1 : st _ s ? > = ^ s ? 2 dom st2 : st s ? < -RRB- changes only fs1 : Stateg ^ st1 : Lookup -LSB- s ? = s1 : s ? ; v ! = s1 : v ! -RSB- s ? > = -RRB- changes only fs2 : Stateg ^ st2 : Lookup -LSB- s ? = s2 : s ? ; v ! = s2 : v ! -RSB- Figure 12 : SL1 module defining a state machine with two symbol tables example . Thus to reuse the operation st1 : Update , the input variables of st1 : Update are renamed to the input variables of TwoSyms : Update . Schema variables within one module are defined in the same name space , and thus the schema calculus within a module works as for Z : variables with the same name are merged during schema calculus operations . 4 Implications for the Proof Theory A reasoning environment for SL1 has been constructed using the Ergo theorem prover -LSB- UW94 -RSB- . The Ergo theory structuring facilities allow SL1 modules to be faithfully modelled at the theory level . In this section we discuss some of the implications of structuring theories in this manner . 4.1 SL1 Module Structure and Theory Structure From every SL1 specification module a theory can be derived in which theorems about the entities occurring in that module can be proved . The structure of a theory derived from an SL1 module closely resembles the structure of that SL1 module . That is , if an SL1 module A imports another SL1 module B then the theory derived from module B is imported into the theory derived from module B. Informally , this means that the definitions , axioms and theorems in the theory derived from B can be referenced in the definitions , axioms and importantly , the proofs of the theory derived from A. Furthermore , if module A makes module B visible then the theory derived from B is also visible in the theory derived from A . In short , the mechanisms used to structure Ergo theories are identical to those used to structure SL1 modules . For example the theory hierarchy in Figure 13 results from the SL1 module Cylinder . Maintaining the consistency of specifications under revision can be a complex task . In particular , the domino effect , where revision of a low level specification causes extensive revision of developments -LRB- as found in , for example , Eves -LSB- KBM +93 -RSB- -RRB- , needs to be controlled . For example , in the Eves system , if the formulation of sets of integers is changed , then virtually every proof in every development must be redone . One discipline for limiting the effects of changes is to ensure that definitions , axioms and theorems in a theory only refer to entities in directly imported theories and not to entities in any transitively imported theory . Non-transitive visibility supports this discipline by providing a mechanism for referencing only directly imported entities without the need for qualified names . Thus , qualified names occurring in a theory indicate exactly where this discipline has been violated . Another facet of the Cogito methodology is that if specification modules are validated then the theory derived from an importing module , like Cylinder , will be a conservative extension -LSB- Sch67 -RSB- of the theory derived from imported modules like Circle . In brief , a theory T conservatively extends a theory T if every theorem of T is a theorem of T and every T theorem provable in T is provable in T . In addition , schemas -LRB- and all the operations of the schema calculus -RRB- are defined in Ergo , simplifying the translation of specifications to Ergo theories . The theorem prover is also populated with a complete representation of ZFC set theory and the Z mathematical toolkit as well as having definitions of most of the Z library operators . Z Types are also defined as part of the SL1 theory base , allowing type-safe manipulation of the Z operators within the theorem prover . 4.2 Structuring the Proof Process In addition to the benefits gained above , structuring theories allows us to develop proofs using the theory structure -LSB- SB83 -RSB- . A proof being developed in a given theory may have subproofs which can be performed in some ancestor theory in the hierarchy . This affords the opportunity to structure the theorem proving process by proving lemmas in the theory in which they conceptually belong . This provides a simpler context in which to perform such a proof . Also since all theories generated from validated SL1 modules are conservative extensions of the theories they import , any such lemma of the importing theory can in be proved in the imported theory . For example , consider a theory T1 which imports and conservatively extends a theory T 2 . A provable lemma in T1 whose vocabulary is entirely within T2 can be proved in T 2 , which will then be available to all theories which import T 2 . To effectively utilise the theory structure in proofs , a number of support mechanisms are desirable . First , when applying or using definitions of any form , it must be possible to identify the theory which has their defining occurrence . Second the proof system must be able to generate a new context for a subproof which excludes all the premises of the parent proof which do not have visible definitions in the target context . In general , the target context is the minimal context required for discharging the subproof . Excluding definitions has no effect on the completeness of the approach , since they ? ? Squaring sqr : N ! N sqrt : N ! N 8 x : N ffl sqr -LRB- x -RRB- = x ? x 8 x ; k : N ffl -LRB- sqr -LRB- k -RRB- < = x ^ sqr -LRB- k + 1 -RRB- > x -RRB- -RRB- sqrt -LRB- x -RRB- = k Circle import Squaring visible Squaring area : N ! N 8 radius : N ffl area -LRB- radius -RRB- = 2 ? radius ? radius ? 22 = 7 8 radius : N ffl cylinder area : N ! N length : nat visible Circle import Circle Cylinder cylinder area -LRB- radius -RRB- = 2 ? radius ? length ? 22 = 7 + 2 ? area -LRB- radius -RRB- Figure 13 : The Hierarchy of Theories Derived from the SL1 Module Cylinder are guaranteed not to be applicable in the new context -LRB- even to the conjecture -RRB- . A more substantial benefit is that since each subproof is carried out in its minimal context , searching and heuristic tactics will be more efficient . Where proofs have large contexts -LRB- for example where they require multiple theories -RRB- then such structuring will result in substantial improvements in efficiency . As an example , consider the theory structure in Figure 14 . JJJJJJJ ^ ? ? ? ? ? ? ? / import NATS . f : N ? N ! N. import NATS . q : N ? N ! N. p : N ! N. ... ... g : N ! N. Theory A Theory B import NATS , A , B. 8 x : N ffl f -LRB- x ; g -LRB- x -RRB- -RRB- = q -LRB- x ; p -LRB- x -RRB- -RRB- . Theory C Figure 14 : Structuring the Proof Process If we wish to prove the theorem 8 x : N ffl f -LRB- x ; g -LRB- x -RRB- -RRB- = q -LRB- x ; p -LRB- x -RRB- -RRB- in theory C then we may perhaps proceed by rewriting f -LRB- x ; g -LRB- x -RRB- -RRB- to normal form in theory A and rewriting q -LRB- x ; p -LRB- x -RRB- -RRB- to normal form in theory B and comparing the results in theory C again . Alternatively we may need to first show some lemmas in theory A and some lemmas in theory B before being able to show the final result . No matter which proof strategy is decided upon , we can always reason about f -LRB- x ; g -LRB- x -RRB- -RRB- in theory A and lemmas relevant to f -LRB- x ; g -LRB- x -RRB- -RRB- remain in theory A and likewise for q -LRB- x ; p -LRB- x -RRB- -RRB- . Since we are structuring our theories by extension then these results are automatically available in theory C also . These ideas are partially supported in the current version of Ergo -LRB- V4 .1 -RRB- . A full implementation is planned for Ergo 5.0 . This implementation effort will begin in early 1995 . SymTabRef -LRB- SYM ; VAL ; k : N -RRB- State keys : 1 : : k ! SYM vals : 1 : : k ! VAL high : : : k 8 i ; j : 1 : : high ffl i < > j -RRB- keys -LRB- i -RRB- < > keys -LRB- j -RRB- Init high0 = OP Update s ? : SYM v ? : VAL -LRB- high < k -RRB- ^ 8 i : 1 : : high ffl s ? < > keys -LRB- i -RRB- high0 = high + 1 keys = keys ? fhigh0 7 ! s?g vals = vals ? fhigh0 7 ! v?g OP Lookup s ? : SYM v ! : VAL 9 i : 1 : : high ffl keys -LRB- i -RRB- = s ? changes only fg 9 i : 1 : : high ffl -LRB- keys -LRB- i -RRB- = s ? ^ v ! = vals -LRB- i -RRB- -RRB- Figure 15 : SL1 specification of a ` concrete ' symbol table , using data structures closer to the implementation level . 5 Support for Refinement and Program Development 5.1 Representing Refinement in SL1 The module mechanism of SL1 provides explicit support for refinement and program development . A representation relation -LRB- cf. VDM -LSB- Jon90 -RSB- -RRB- between SL1 modules as state machines can be specified within an SL1 module . Since a module has a single explicit state and operation schemas , an interpretation of the abstract operations and state of one module can be given in terms of the more concrete state and operations of another . For example , Figure 15 shows an SL1 specification defining a module with the same external behaviour as SymTab but using more concrete data structures . These data structures correspond to a ` parallel array ' implementation , in which keys and corresponding values are stored at the same index in two arrays . The variable high records the index of the last stored key . Figure 16 shows a module defining the representation relation between the states of SymTab and SymTabRef , and the refinement relation between the state machines they define . Refine SymTab -LRB- SYM ; VAL ; k : N -RRB- import SymTab -LRB- SYM ; VAL ; k -RRB- as Abs ; import SymTabRef -LRB- SYM ; VAL ; k -RRB- as Conc ; visible SymTab ; SymTabRef ; Rep Relation Abs : State Conc : State dom st = fs : SYM j 9 i : 1 : : high ffl s = keys -LRB- i -RRB- g 8 i : 1 : : high ffl st -LRB- keys -LRB- i -RRB- -RRB- = vals -LRB- i -RRB- Refine -LRB- Abs ; Conc ; RepRel ; -LSB- -LRB- Abs : Init ; Conc : Init -RRB- -RSB- ; -LSB- -LRB- Abs : Update -LSB- s ? = Abs : s ? ; v ? = Abs : v ? -RSB- ; Conc : Update -LSB- s ? = Conc : s ? ; v ? = Conc : v ? -RSB- -RRB- ; -LRB- Abs : Lookup -LSB- s ? = Abs : s ? ; v ! = Abs : v ! -RSB- ; Conc : Lookup -LSB- s ? = Conc : s ? ; v ! = Conc : v ! -RSB- -RRB- -RSB- Figure 16 : SL1 module defining the relationship between abstract and concrete symbol table modules . The Refine command specifies the data-refinement relationship between the components of the modules : Abs is to be refined to Conc , with the representation relation Rep Relation , and with the specified correspondence between operations . Note that the operations have their input and output parameters renamed to common names , since we wish to compare the behaviour of corresponding operations for the same inputs and outputs . Thus design decisions are recorded explicitly as part of the specification structure . This fact , in combination with the library mechanisms for the management of specification modules , provides a means for managing developments . The modularisation of the design process is an important consideration if we wish to support programming in the large . There is some debate as to where such refinements should be recorded and managed . Often , the management task is seen as a tool issue and refinement is considered wholly at some meta level -LRB- which is reflected by recording the manner in which various tools are applied -RRB- . The module mechanism of SL1 is able to reflect quite naturally important aspects of the development process . Actual development steps are reflected by maintaining versions of a specification . Progressing from one version of a specification to another denotes a development step , where the representation of the development step should record the tools and contexts used to achieve the refinement . The details of the actual development performed are reflected in the specification itself . Modelling of data refinements is particularly attractive in this context . 5.2 Constructing Implementations One of the aims of the Cogito project is to progress as far as possible towards implementations . The approach differs from the typical refinement calculus method in that there is no explicit representation of the concrete syntax of a specific programming language . Rather , the modelling of a set of general programming language concepts is given in the specification language , and these become targets for low level refinement rules . Once all operations on state are refined to specifications involving only these constructs , then projection to the specific concrete syntax of a programming language can be undertaken . There are two main aspects to such a projection . The first is the overall structure of the implementation in terms of the partitioning of the solution into modules . The second is the task of producing the computation structures which implement the operations defined in each module . From a design perspective , the definition of the modular structure of an implementation has significant benefit in the overall development process . Most design methods which concentrate on system architecture only construct the module and interface parts of an implementation in the design phase . Cogito intends to go further than this , in that the modular structure of the implementation will be constructed as well as the actual bodies of code implementing the solution . In the next section a set of rules which construct an architectural design skeleton , to be further populated with code , is given . These rules specifically target Ada as the implementation language . The translation assumes that the specification of a detailed design also defines an architectural structure for the eventual solution . It is one of the aims of SL1 that the transition from detailed designs to implementations in Ada should be as straightforward as possible , with the modular structure of the detailed designs implying a package structure for the Ada implementations . Without these features , the projection to Ada implementations would require complex analysis and translations rules in order to ensure correct Ada code is produced -LRB- cf. -LSB- Gro91 -RSB- -RRB- . The translation to Ada is sketched here by defining an informal set of translation rules . 6 Translating SL1 to Ada The refinement process ends when detailed design specifications contain only those SL1 constructs in the executable sublanguage . At this point SL1 modules may be translated to Ada packages . In order to model the translation to Ada we make use of a number of translation functions -LRB- M , W , D , F , A -RRB- . The semantic function M transforms SL1 module declarations into Ada package interface declarations : M : SL1 Module Dec ! Context ! Ada Package The auxiliary function W determines , on account of the SL1 import declarations , the Ada context clauses needed for the generation of the Ada module . W : SL1 Declaration ! Context ! Context Clause List The auxiliary function D translates the body of an SL1 declaration to a list of Ada declarations . D : SL1 Declaration ! Context ! Ada Declaration List The auxiliary function F determines the formal generic parameters required in Ada generic packages which model SL1 parameterised modules . F : SL1 Formal Param List ! Ada Generic Params The auxiliary function A determines the instantiation of the formal generic parameters in Ada packages with actual parameters which models the instantiation of parameterised SL1 modules with actual parameters . A : SL1 Formal Param List ? SL1 Actual Param List ! Generic Package Instantiation The function M is very straightforward and can be viewed as simple syntactic manipulation . The function W is used to determine the with clauses required in the translation and D is used to establish the use clauses required in the translation . Both these functions are more complex than M because the scope and visibility rules of SL1 do not match those of Ada exactly . The functions F and A are little more than syntactic manipulation except that the function A requires a list of formal generic parameters to generate the correct syntactic form of generic package instantiations . We do not discuss A and F further here . 6.1 Translating SL1 Modules A non-parameterised SL1 module is translated into a package . Id ... Declarations ... > W -LSB- -LSB- Declarations -RSB- -RSB- package Id is D -LSB- -LSB- Declarations -RSB- -RSB- end Id ; The with clauses of the library unit are generated from the import declarations of the module using the function W . The visible and private parts of the package are also generated from the declarations of the module but using the function D . A parameterised SL1 module is translated into a generic package . Id -LSB- FormalParams -RSB- ... Declarations ... > W -LSB- -LSB- Declarations -RSB- -RSB- generic F -LSB- -LSB- FormalParms -RSB- -RSB- package Id is D -LSB- -LSB- Declarations -RSB- -RSB- end Id ; The formal parameters of the module determine the formal parameters of the generic package . 6.2 Determining the with Clauses SL1 has transitive module reference but non-transitive visibility . On the other hand Ada has nontransitive scope : entities are in scope only in the package in which they are declared and any package which directly imports that package . The function W deals with this by recursively descending the imported modules and generating the with clauses for these before generating those for the current module . This procedure terminates when the declarations contain no more import clauses . The context argument in the function W maintains a list of all the SL1 modules in the library of the current SL1 module which may be imported . We utilise a function Lookup which , given a module name Id and a context C returns the text of the SL1 module corresponding to Id in the context C . We have , W -LSB- -LSB- import Id1 -RSB- -RSB- -LRB- C -RRB- = W -LSB- -LSB- Lookup -LRB- Id1 ; C -RRB- -RSB- -RSB- -LRB- C -RRB- ; with Id1 and W -LSB- -LSB- import Id1 as Id2 -RSB- -RSB- -LRB- C -RRB- = W -LSB- -LSB- Lookup -LRB- Id1 ; C -RRB- -RSB- -RSB- -LRB- C -RRB- ; with Id1 and W -LSB- -LSB- import Id1 -LRB- ActParams -RRB- as Id2 -RSB- -RSB- -LRB- C -RRB- = W -LSB- -LSB- Lookup -LRB- Id1 ; C -RRB- -RSB- -RSB- -LRB- C -RRB- ; with Id1 and W -LSB- -LSB- dec1 ; dec2 -RSB- -RSB- -LRB- C -RRB- = W -LSB- -LSB- dec1 -RSB- -RSB- -LRB- C -RRB- ; W -LSB- -LSB- dec2 -RSB- -RSB- -LRB- C -RRB- and W -LSB- -LSB- dec -RSB- -RSB- -LRB- C -RRB- is blank if dec is any of the other forms of SL1 declaration not containing import statements . 6.3 Determining the Package Declaration The function which determines the structure of the package specification is D. Recall that D acts within a package specification and within the context previously established by the function W . Consequently for import Id we need do nothing because W has already provided all the required with clauses . This leaves us to deal with renaming on import and visible declarations . We have D -LSB- -LSB- import Id1 as Id2 -RSB- -RSB- = package Id2 renames STANDARD : Id1 and D -LSB- -LSB- import Id1 -LRB- ActParams -RRB- as Id2 -RSB- -RSB- = package Id2 is new STANDARD : Id1 -LRB- A -LSB- -LSB- ActParams -RSB- -RSB- -RRB- and again D -LSB- -LSB- dec -RSB- -RSB- is empty if dec is any of the other forms of SL1 declaration not containing import statements . The renaming declaration in Ada models SL1 module renaming . The renaming of a module is translated into a renaming declaration in Ada . Notice that generic modules can not be renamed due to limitations of Ada -LRB- and Ada-9X -RRB- . Note also that we allow for a module Id to be renamed to itself . Since the simple name of a declaration is hidden within the declaration itself , the package Id1 is referred to by using an expanded name . The prefix , STANDARD , is used in Ada to reflect the fact that each module unit is declared immediately within package STANDARD itself . In broad terms SL1 's visible declaration corresponds to Ada 's use clause . The use clause in Ada ensures that all entities of a package previously introduced via a with clause are directly visible within the current package , unless hidden by a local declaration . We have D -LSB- -LSB- visible Id -RSB- -RSB- = use Id and D -LSB- -LSB- visible Id -LSB- VisibleList -RSB- -RSB- -RSB- = use Id In this last clause we deliberately do not implement the visibility of SL1 faithfully which allows us to simplify our translation rules . The result of this choice is that entities which are visible at a point in the SL1 specification will be visible in Ada translation but the converse is not true . Indeed , SL1 gives finer control over the visibility of entities in imported modules than Ada does . Finally we have , D -LSB- -LSB- dec1 ; dec2 -RSB- -RSB- = D -LSB- -LSB- dec1 -RSB- -RSB- ; D -LSB- -LSB- dec2 -RSB- -RSB- In this last clause we need to do some more analysis than is actually demonstrated here . If an entity f is declared in SL1 modules A and B and both A and B were imported and made visible in a third module C the linear visibility would determine whether A : f or B : f is visible in C . In Ada the situation is different . If both A and B are imported and made visible then fully qualified names would be required to resolve the resulting name clash in C -LSB- Geh84 -RSB- . Consequently our translation D will interpose fully qualified names when such clashes occur . 7 Conclusion We have discussed the module mechanism of the Z based specification language SL1 and discussed the implications of the SL1 module mechanism for structuring theories , refining modules and for translating detailed designs to Ada package structures . In particular , extending Z with modules provides the following benefits : ffl large specifications can be structured into modules with clearly defined interfaces ; ffl the development of implementations -LRB- and especially architectural designs -RRB- is simple ; ffl supporting state machines and refinement between state machines -LRB- which is traditionally only achieved via informal conventions in Z -RRB- ; ffl data refinement can be modelled within the specification formalism . SL1 module structures correspond closely to Ergo theory structures which simplifies the translation of SL1 to Ergo theories . Also the theory structure derived from an SL1 specification models the structure of the SL1 specification faithfully . This greatly simplifies validating and reasoning about specifications . Also , managing theories , specifications and proofs based on the same modular structure is possible . The development of support tools for constructing , analysing and refining SL1 specifications is currently underway . At the time of writing , parsers , a recognition editor and a typechecker are available as is the Ergo theorem prover . The Ergo theorem prover has been populated with an environment for reasoning about SL1 specifications -LRB- including over 2000 derived theorems -RRB- and the development of a translator from specifications to Ergo theories is underway . A repository and library manager which supports and coordinates the development and analysis of SL1 specifications has been implemented and is currently being populated with library specification modules and their derived theories . Acknowledgements The authors would like to thank the other members of the Cogito Group for many useful discussions and feedback . In particular : Anthony Bloesch -LRB- largely responsible for the Ergo theory population -RRB- , John Staples and Mark Utting . References -LSB- BKKT94 -RSB- Anthony Bloesch , Ed Kazmierczak , Peter Kearney , and Owen Traynor . The Cogito Methodology and System . To Appear in Proceedings Asia Pacific Software Engineering Conference 94 , 29 pages , 1994 . -LSB- DKRS91 -RSB- R. Duke , P. King , G. Rose , and G Smith . The Object-Z Specification Language version 1 . Technical Report Technical Report 91-1 , Software Verification Research Centre , University of Queensland , 1991 . -LSB- Geh84 -RSB- N. Gehani . Ada : An Advanced Introduction Including Reference Manual for the Ada Programming Language . Prentice Hall , 1984 . -LSB- Gro91 -RSB- The Hood Technical Group . The HOOD Reference Manual , July 1991 . -LSB- Hay92 -RSB- Hayes , I.J. and Wildeman , L.P. Towards Libraries for Z . In J. P. Bowen and J. E. Nicholls , editors , Z User Workshop : Proceedings of the Seventh Annual Z User Meeting , Workshops in Computing . Springer-Verlag , 1992 . -LSB- Jon90 -RSB- C.B Jones . Software Development using VDM . Prentice Hall , second edition , 1990 . -LSB- Kaz92 -RSB- E. Kazmierczak . Modularising the specification of a small database system in extended ml . Formal Aspects of Computing , 4 -LRB- 1 -RRB- :100 -LCB- 142 , 1992 . Springer-Verlag . -LSB- KBM +93 -RSB- S. Kromodimoeljo , Pase B. , Saaltink M. , Craigen D. , and Meisels I . A Tutorial on EVES . Technical Report Technical Report , ORA Canada , 1993 . -LSB- Lan91 -RSB- K. C. Lano . Z + + , an object oriented extension to Z . In J. Nicholls , editor , Z User Workshop : Proceedings of the Fifth Annual Z User Meeting , Workshops in Computing . Springer-Verlag , 1991 . -LSB- SB83 -RSB- D. Sannella and R. Burstall . Structured Theories in LCF . In Proceedings of the 8th Colloq . on Trees in Algebra and Programming , Lecture Notes in Computer Science 159 , pages 377 -LCB- 391 . Springer Verlag , 1983 . -LSB- Sch67 -RSB- J. R. Schoenfield . Mathematical Logic . Addison-Wesley Publishing Company , 1967 . -LSB- Spi92 -RSB- J. M. Spivey . The Z Notation : A Z Reference Manual . Prentice Hall , 1992 . -LSB- Tra94 -RSB- O. Traynor . The Cogito Repository Manager . To Appear in Proceedings Asia Pacific Software Engineering Conference 94 , 17 pages , 1994 . -LSB- US 83 -RSB- US Government Printing Office . Reference Manual for the Ada Programming Language - ANSI/MIL-STD 1815A , 1983 . -LSB- UW94 -RSB- M. Utting and K. Whitwell . The Ergo Interactive Theorem Prover V4 .0 . Technical Report 94-14 , Software Verification Research Centre , The University of Queensland , 1994 . -LSB- Wor92 -RSB- J. B. Wordsworth . Software Development with Z. Addison-Wesley , 1992 .

O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O B O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O B O O O O O O O O O O O O O O O O O O O O O B O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O

formal development environments
formal specification