276 30 1MB
English Pages 128 Year 2005
Editorial I am pleased to announce some changes in the composition of the TOSEM Editorial Board. The 3-year term expired for the following Associate Editors: Prem Devanbu, Constance Heitmeyer, Kevin Sullivan, and Catalin Roman. I wish to thank them publicly for the their service to the journal and, more generally, to the software engineering community. The following colleagues joined the Board in January 2004: Laura Dillon, Paola Inverardi, Mehdi Jazayeri, and Pamela Zave. The group was expanded in January 2005 to include George Avrunin, Mary Jean Harrold, Gail Murphy, Oscar Nierstrasz, David Rosenblum, and Tetsuo Tamai. Their brief bio sketches are listed below. I wish to welcome all of them and thank them in advance for the contribution they will provide in keeping the high standards and scientific reputation of the journal. CARLO GHEZZI Editor-in-Chief Associate Editors Effective January 2004 Prof. Laura K. Dillon Department of Computer Science and Engineering Michigan State University 3115 Engineering Building East Lansing, MI 48824-1226, USA email: [email protected] http://www.cse.msu.edu/∼ ldillon Dr. Laura (Laurie) K. Dillon received her Ph.D. degree in Computer Science from the University of Massachusetts, Amherst (1984). She previously served on the faculty at the University of California, Santa Barbara (1985–1998). Currently, she is a professor and interim chair of Computer Science at Michigan State University. Laurie’s research interests center on formal methods for specification, analysis, and testing of software systems. She has served the software engineering community on various editorial boards, program committees, funding panels, and professional advisory committees. Most recently, she was program co-Chair of ICSE’03 and she sits on the Executive Committee of ACM SIGSOFT. Prof. Paola Inverardi Dipartimento di Informatica Via Vetoio, Loc. Coppito I-67100 L’Aquila, Italy email: [email protected] http://www.di.univaq.it/inverard/paola.html Paola Inverardi is full professor at the University of L’Aquila. Previously she has worked at IEI-CNR in Pisa and at Olivetti Research Lab in Pisa. She is head ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005, Pages 119–123.
120
•
Editorial
of the Department of Computer Science at the University of L’Aquila where she leads the Software Engineering and Architecture Research Group. Her main research area is in the application of formal methods to software development. Her research interests primarily concentrate in the field of software architectures. She has actively worked on the verification and analysis of software architecture properties, both behavioural and quantitative for component-based, distributed and mobile systems. She has served as general chair, program chair, and program committee member for many international conferences. She is currently Chair of the Steering Committee for the European Software Engineering Conferences (ESEC). Prof. Mehdi Jazayeri Faculty of Informatics University of Lugano 6900 Lugano, Switzerland email: [email protected] ttp://www.infosys.tuwien.ac.at/Staff/mj Mehdi Jazayeri is currently dean of the Faculty of Informatics and professor of Computer Science at the University of Lugano, Switzerland. He also holds the chair of distributed systems at the Technical University of Vienna. He spent many years in software research and development at several Silicon Valley companies, including ten years at Hewlett-Packard Laboratories in Palo Alto, California. His recent work has been concerned with component-based software engineering of distributed systems, particularly Web-based systems. He is a coauthor of Programming Language Concepts (John Wiley, 1998), Fundamentals of Software Engineering (Prentice-Hall, 2002), and Software Architecture for Product Families (Addison-Wesley, 2000). Dr. Pamela Zave AT&T Laboratories 80 Park Avenue, Room D205 Florham Park, New Jersey 07932, USA email: [email protected] http://www.research.att.com/info/pamela Pamela Zave received a Ph.D. in Computer Sciences from the University of Wisconsin, Madison. She taught at the University of Maryland before joining AT&T Bell Laboratories in 1981. Dr. Zave’s chief interests are requirements engineering and formal methods for software development. She is best known for her work on multiparadigm specification, the executable specification language PAISLey, and the Distributed Feature Composition architecture. In 2002, she was named a Fellow of the ACM for her contributions to the use of formal methods in telecommunication software. Associate Editors Effective January 2005 Prof. George Avrunin Department of Mathematics and Statistics ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Editorial
•
121
University of Massachusetts 710 North Pleasant Street Amherst, MA 01003-09305, USA email: [email protected] http://ext.math.umass.edu/∼avrunin/ George Avrunin is a professor in the Department of Mathematics and Statistics and an adjunct professor in the Department of Computer Science at the University of Massachusetts. His primary research interests are in formal methods, especially finite-state verification and model checking, and requirements engineering. He has served as conference chair for the International Symposium on Software Testing and Analysis and as a program committee member for numerous conferences. He received his Ph.D. in Mathematics from the University of Michigan in 1976. Prof. Mary Jean Harrold NSF ADVANCE Professor of Computing College of Computing Georgia Institute of Technology 801 Atlantic Drive Atlanta, GA 30032-0280 [email protected] http://www.cc.gatech.edu/∼harrold Mary Jean Harrold is the NSF ADVANCE Professor of Computing at Georgia Tech. She performs research in analysis and testing of large, evolving software, fault-localization using statistical analysis and visualization, monitoring deployed software to improve quality, and software self-awareness through realtime assessment and response. Professor Harrold received an NSF NYI Award and was named an ACM Fellow. She serves on the editorial board of ACM TOPLAS, on the Board of Directors for the Computing Research Association (CRA), as vice chair of ACM SIGSOFT, as co-chair of the CRA Committee on the Status of Women in Computing (CRA-W), and as a member of the Leadership Team of the National Center for Women and Information Technology. She received her Ph.D. from the University of Pittsburgh. Prof. Gail Murphy Department of Computer Science University of British Columbia 201-2366 Main Mall Vancouver BC Canada V6T 1Z4 e-mail: [email protected] http://www.cs.ubc.ca/∼murphy/ Gail Murphy is an associate professor in the Department of Computer Science at the University of British Columbia in Vancouver, Canada. She received her M.S. degree and Ph.D. degree in Computer Science and Engineering from the University of Washington in 1994 and 1996, respectively, and B.S. (Honors) degree from the University of Alberta in 1987. From 1987 to 1992, she worked ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
122
•
Editorial
as a software designer at a telecommunications firm. Her research focuses on creating and evaluating methods and tools to help software developers manage and evolve the structure of the software systems they are developing both at design time and in source code. Prof. Dr. Oscar Nierstrasz ¨ Informatik (IAM) Institut fur ¨ Bern Universitat ¨ Neubruckstrasse 10, CH-3012 Bern, Switzerland E-mail: [email protected] http://www.iam.unibe.ch/∼oscar/bio.html Oscar Nierstrasz has been a professor of Computer Science at the Institute of Computer Science (IAM) of the University of Bern since 1994, where he leads the Software Composition Group. He is the author of over a hundred publications and co-author of the book Object-Oriented Reengineering Patterns (Morgan Kaufmann, 2003). Prof. Nierstrasz has been active in the international object-oriented research community, serving on the programme committees of the ECOOP, OOPSLA, ESEC and many other conferences, and as the programme chair of ECOOP ’93 and ESEC ’99. He completed his B.S. (Math) at the University of Waterloo in 1979, his M.S. in 1981, and his Ph.D. in 1984 at the University of Toronto, in the area of Office Information Systems. Since then he has worked at the Institute of Computer Science in Crete (1985) and in the Object Systems Group at the Centre Universitaire d’Informatique of the University of Geneva, Switzerland (1985–1994). Prof. David S. Rosenblum Department of Computer Science University College London Gower Street London WC1E 6BT, United Kingdom Prof. David S. Rosenblum holds the Chair in Software Systems in the Department of Computer Science at University College London and is Director of London Software Systems, a research institute established jointly with Imperial College London. He received his Ph.D. in 1988 from Stanford University, USA, and he currently holds a Wolfson Research Merit Award from the Royal Society of the UK. He has published widely in testing and run-time monitoring of software and in event-based computing, and his recent research has been investigating problems in Internet-scale publish/subscribe infrastructures. In 2002, he received the International Conference on Software Engineering’s Most Influential Paper Award for his ICSE 1992 paper on assertion checking in C programs. He previously served on the editorial board of the IEEE Transactions on Software Engineering and is currently the Chair of the ICSE Steering Committee. Prof. Tetsuo Tamai Graduate School of Arts and Sciences The University of Tokyo ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Editorial
•
123
3-8-1 Komaba, Meguro-ku Tokyo 153-8902, Japan email: [email protected] http://www.graco.c.u-tokyo.ac.jp/∼tamai/ Tetsuo Tamai received the B.S., M.S. and D.S. degrees in mathematical engineering from the University of Tokyo. He became a professor of the Graduate School of Arts and Sciences, the University of Tokyo in 1994 and has been in that position ever since. His current research includes high reliability componentbased software engineering, collaboration and role modelling, formal analysis of software architectures, and software evolution process. He has been sharing responsibilites of a number of international academic conferences, including PC of ICSE’s, RE’s, ESEC/FSE’s, ICSM’s and many others, as well as steering committee of APSEC and IWPSE.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
A Scalable Formal Method for Design and Automatic Checking of User Interfaces JEAN BERSTEL Institut Gaspard-Monge, Universite´ de Marne-la-Vallee ´ STEFANO CRESPI REGHIZZI Politecnico di Milano GILLES ROUSSEL Institut Gaspard-Monge, Universite´ de Marne-la-Vallee ´ and PIERLUIGI SAN PIETRO Politecnico di Milano
The article addresses the formal specification, design and implementation of the behavioral component of graphical user interfaces. The complex sequences of visual events and actions that constitute dialogs are specified by means of modular, communicating grammars called VEG (Visual Event Grammars), which extend traditional BNF grammars to make them more convenient to model dialogs. A VEG specification is independent of the actual layout of the GUI, but it can easily be integrated with various layout design toolkits. Moreover, a VEG specification may be verified with the model checker SPIN, in order to test consistency and correctness, to detect deadlocks and unreachable states, and also to generate test cases for validation purposes. Efficient code is automatically generated by the VEG toolkit, based on compiler technology. Realistic applications have been specified, verified and implemented, like a Notepad-style editor, a graph construction library and a large real application to medical software. It is also argued that VEG can be used to specify and test voice interfaces and multimodal dialogs. The major contribution of our work is blending together a set of features coming from GUI design, compilers, software engineering and formal verification. Even though we do not claim novelty in each of the
A preliminary version of this article appeared in Proceedings of the International Conference on Software Engineering (ICSE 2001) (Toronto, Ont., Canada, May 12–19). IEEE Press, New York, 2001, pp. 453–462. This research was partially supported by Esprit Open LTR Project “Gedisac” and by Miur Project “Firb RBAU01MCAC: Applicazioni della Teoria degli Automi all’Analisi, alla Compilazione e alla Verifica di Software Critico e in Tempo Reale.” Authors’ addresses: J. Berstel and G. Roussel: Institut Gaspard-Monge, Universit´e de Marne-laVall´ee, 5, Bd Descartes, 77454 Marne-la-Vall´ee Cedex 2, France; email: {berstel,roussel}@univmlv.fr; S. Crespi Reghizzi and P. San Pietro: Dipartimento de Elettronica e Informazione, Politecnico di Milano, P.zza Leonardo da Vinci, 32, 20133 Milano, Italia; email: {crespi,sanpietr}@elet.polimi.it. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or direct commercial advantage and that copies show this notice on the first page or initial screen of a display along with the full citation. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, to redistribute to lists, or to use any component of this work in other works requires prior specific permission and/or a fee. Permissions may be requested from Publications Dept., ACM, Inc., 1515 Broadway, New York, NY 10036 USA, fax: +1 (212) 869-0481, or [email protected]. C 2005 ACM 1049-331X/05/0400-0124 $5.00 ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005, Pages 124–167.
Design and Automatic Checking Method for User Interfaces
•
125
techniques adopted for VEG, they have been united into a toolkit supporting all GUI design phases, that is, specification, design, verification and validation, linking to applications and coding. Categories and Subject Descriptors: D.2.2 [Software Engineering]: Design Tools and Techniques—User interfaces; D.2.4 [Software Engineering]: Software/Program Verification— Formal methods, model checking; H5.2 [Information Interfaces and Presentation]: User Interfaces—Theory and methods General Terms: Design, Verification Additional Key Words and Phrases: Human-computer interaction (HCI), applications of model checking, GUI design
1. INTRODUCTION Current industrial practice for designing graphical user interfaces (GUI) uses toolkits and interface builders, mostly based on visual programming languages, for producing the layout. These tools allow a simple and quick description of the geometric display, and may even give some support for designing interaction of components (e.g., QTDesigner by Trolltech, JavaBeanBox in Sun’s BDK, Visual C++ or Glade). However, the dialog control must be hand-coded with conventional programming techniques and there is no support for checking the dynamic behavior of the interface other than testing. This situation is unsatisfactory at best, since the resulting systems may be unreliable and difficult to revise and extend. In particular, the reactive nature of event-driven systems (such as a GUI) makes them much more difficult to test, since the output values strongly depend on the interaction that may occur during the computation. Traditional testing techniques may be costly and inadequate for complex GUI, yet the importance of verification and validation cannot be underestimated, since the majority of software applications in any domain have a complex GUI. The current inadequacy of existing techniques for GUI design and verification is particularly felt for safety-critical software, where, disregarding also the important ergonomic needs pointed out by Gray et al. [1999], rich and potentially useful user interfaces may be discarded in favor of primitive interfaces that are easier to test and more dependable. Formal techniques may allow one to perform systematically, or even automatically, validation and verification activities like testing, simulation and model checking [Clarke et al. 1986; Holzmann 1997], and to prove that the modeled systems possess desired properties. Hence, the validity of the design may be assessed ahead of development. Formality is widely acknowledged to support the construction of more reliable software, and hence is becoming more popular in critical areas. Many formal methods have been proposed for GUI design [Palanque and Patern`o 1997], such as (augmented) transition diagrams in Hendricksen [1989], Petri nets in Bastide and Palanque [1995], formal grammars in Reisner [1981], process algebras in Patern`o and Faconti [1992], and temporal logic in Brun [1997]. However, general formal methods are considered difficult to use by most engineers, and often get unwieldy as the system complexity grows (i.e., they are beneficial only for small systems or single components). Also, the methods proposed to give complete support ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
126
•
J. Berstel et al.
to GUI design so far are not amenable to automatic verification techniques, supporting mainly simulation and testing. As pointed out by Shneiderman, [1997, p. 159]: “Scalable formal methods and automatic checking of user interface features would be a major contribution”. We propose a new simple formal method, which combines various features such as modularity, code generation and automatic verification, to give a scalable notation to specify, design, validate and verify GUIs. Our approach, called Visual Event Grammars (VEG) is based on decomposing the specification of a large GUI into communicating automata. Breaking a complex scene down into communicating pieces may dramatically diminish the number of states, as shown by popular notations such as Statecharts [Harel 1987]. Each automaton is an object, described by means of a grammar, specifying a small part of the control of the scene, such as the behavior of a window or a widget. Automata may share common behavior and hence be seen as instances of general models. Automata interact by sending and receiving communication events in order to realize the expected global behavior. Data values, such as the actual contents of a text field or the color of a widget, may be associated with events and states, and Java code can manipulate them, following an attribute grammar style [Knuth 1968] of computation. The VEG approach allows the automatic generation of efficient code from the specification of the interface, and its integration with commercial design tools, by implementing the various automata as interacting parsers (where the input stream of each parser is the sequence of input events for the corresponding window or widget). A toolkit has been prototyped, to produce Java classes that implement the logical behavior of the GUI and to integrate them with the layout. Up to now, the toolkit handles interfaces of WIMP (Window, Icon, Menu, Pointer) style. Extensions to more sophisticated interaction paradigms like virtual reality or voice interactions are possible, and discussed in Section 7. The VEG approach also allows clean separation both of data vs. control and layout vs. behavior. More precisely, separation of data and control means that every VEG specification is composed of a “purely syntactical” part, describing the event-driven behavior of a GUI (the control), and of a “semantical” part, implementing data manipulation. In fact, as already remarked, a VEG specification is akin to an attribute grammar, where the syntax aspects are complemented by semantic functions. The VEG approach thus follows the classical Model-View-Controller architecture pioneered by SmallTalk 80: the controller is specified with the syntax, and it interacts with the model and the view by means of input events and attributes. In particular, the specification and design of a GUI is independent of its actual layout. This allows portability and ease of modification, but also the reuse of the same logic in implementing different interfaces for the same service (such as in the Sisl approach of Ball et al. [2000]), possibly with different data manipulation. Web services are a typical application that may benefit from this separation. For instance, the website of Politecnico di Milano has been redone a few times, mostly because the layout was unsatisfactory: each time the same services had to be partly reprogrammed, while with VEG this would have been unnecessary. Also banking systems may benefit from the layout/logic separation: they offer multichannel access through ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
127
an automated teller machine, a web-based interface or bank-by-phone interface [Godefroid et al. 2000]. Usually, code duplication occurs, with the associated rise in development and maintenance costs, but this can be avoided with the present approach. The separation of data and control, together with the independence of the layout, is convenient not only for maintenance and reuse, but also for fast prototyping. GUI prototyping is often necessary for the customer to understand whether the GUI is the right one. The layout may be very changeable in this phase. With VEG, we can quickly specify the logic, choose a layout, give it to the user of the application and verify what has to be changed. The layout may be thrown away afterwards, but VEG specifications remain. Data processing is not needed at this moment: only the control part of the GUI is programmed. Usually, the additional cost of rapid prototyping is that an expensive prototype must be thrown away. With VEG, the initial prototype may be a less costly VEG specification that can often be reused and extended into the final system. Apart from the merits of individual notations, one of the major obstacles in the diffusion of formal methods outside academic research is the perceived difficulty in their use. Formal specification languages are considered hard to master, and formal verification techniques, such as theorem proving, to be for real experts only. On the other hand, automata, such as those used in VEG, are among the easiest formalisms, and every software engineer is familiar with them. Moreover, advances in automatic verification toolkits, such as model checking, are greatly simplifying formal verification, since in principle “pushbutton” verification is possible for many systems specified with automata. In general, however, a specification or a program has to be “abstracted” to be amenable for automatic verification with model checkers. In fact, the number of states of even simple programs is typically too high for model checkers, especially because of the large range of data values. Constructing a powerful enough, sound abstraction may require considerable ingenuity, since the abstracted program must be a compromise between efficiency (i.e., the size of the state space for concrete model checkers such as SPIN [Holzmann 1997], or the size of formulas encoding the system for symbolic model checkers such as SMV [Clarke et al. 1986]) and effectiveness (i.e., the meaningfulness of the verification results on the abstracted program). In particular, the abstraction must be safe with respect to the properties of interest (e.g., deadlock freedom): if the property holds in the abstracted system then it holds in the original program. A lot of research efforts are currently underway to allow the development of safe abstractions for programming languages such as C and Java (e.g., Ball et al. [2000] and Corbett et al. [2000], but the results still seem hard to generalize and use. In the VEG toolkit, however, an abstraction that is safe with respect to many important properties (such as deadlock-freedom and state invariants) can automatically be derived from the original specification, with a meaning that is very close to the original one. Typically, in VEG, the abstracted version is the control (finite-state) part of the specification, while data and related functions are ignored. When dealing with abstracted programs, however, even when an abstraction is shown or is known to be safe, spurious counterexamples may ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
128
•
J. Berstel et al.
occur, that is, errors in the abstracted program that do not correspond to feasible computations on the original program. In this case, one may either accept the result (and then try to fix a program that is already correct) or use some form of proof or symbolic execution of the counterexample on the original program, to understand whether the positive is a true one. In our experience with VEG specifications, the problem of spurious counterexamples does not seem to hamper verification as much as in software model checking. An explanation for this is that the notation and the methodology used tend to enforce a clear separation between control and data, while in traditional programs, where this distinction is usually not present, the control flow graph is a very poor abstraction. Moreover, since GUIs are usually event-driven, control-intensive systems, often the abstracted VEG specification is very close to the one used to produce the application: there is a high level of coherence between the application and its formal model. We based verification and validation on SPIN, a widely disseminated modelchecking tool. Communicating automata fit particularly well into the domain of automatic verification: the VEG notation can be easily translated into the Promela language, which is the input language of SPIN. Currently, our toolkit supports, with simple “pushbutton” options, automatic detection of design errors such as deadlock and unreachable states, but it also allows state invariant verification, simulation and test case generation. The VEG support for verification may also help in checking features of an interface and in detecting requirement errors. For instance, a Save button in an Editor application should be reachable from every state where the document has been modified. This means that the GUI will never run into a configuration where a user will no longer be allowed to save her data. This is a liveness property, which can be easily verified by a model checker. Another example is the verification that all needed resources are available before a process can start: in a text editor, a document must be created or opened before writing into it. We found that even very large GUI can easily be checked, since usually the number of its (control) states is much smaller than the current limits of model checkers. Our work draws on a long, well-established tradition of user interface design, called dialog independence [Hartson and Hix 1989; Hill 1986] or syntaxsemantics dichotomy [Foley 1987; Foley et al. 1989; Jacob 1982; Olsen 1983, 1984; Reisner 1981; Shneiderman 1982 and others], and in particular on the Seeheim model of Green [1983]. The goal of these models is the separation of the application from its user interface. Some of these works also applied contextfree or regular grammars to the description of dialogs (already in 1981). The reason is that grammars have various advantages over other approaches. For instance, the terminal alphabet of a grammar is usually composed of highlevel events at the application level, such as Start, Quit, Cut, etc., allowing platform-independence and often also widget-independence. Also, some authors introduced a special notation to supplement grammars whenever they seem unsuited to describe some features. For instance, Van den Boss [1988] has proposed and developed a special rich notation, exceeding the power of context-free grammars. For this and similar approaches, however, the possibility of automatic verification of the specification becomes quite small, since the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
129
more powerful the model is, the more reduced the automatic verification activities may be. VEG does not suffer of this problem, since most features extending traditional grammars are still finite-state, and the others (e.g., attributes) can usually be abstracted away during the verification phase. Also, in VEG, special care was taken in order to introduce a small number of features that are really useful in designing GUI, while avoiding baroque notations often used in other approaches. Grammar approaches disappeared from the scenes of GUI design, since they do not have constructs that are present instead in notations such as the above-cited Petri nets and Statecharts: they did not deal with parallelism, lacked structuring constructs and synchronization or communication mechanisms, and failed in cleanly integrating the data structure aspects of GUI into their control structure aspects. However, the VEG constructs support parallelism and structuring, and the use of attribute grammars neatly combines data and control structures. The major contribution of our work is blending together a set of features coming from GUI design, compilers, software engineering and formal verification. Even though we do not claim novelty in each of the techniques adopted for VEG, they have been united into a toolkit supporting all GUI design phases, that is, specification, design, verification and validation, linking to applications and coding. One of the major advantages of the VEG approach is the possibility of the interaction of development and step-by-step verification, thus allowing early and continuous testing of the application. The article is organized as follows: Section 2 introduces the basic VEG control notation, Section 3 extends the notation with data manipulation, Section 4 illustrates automatic verification in VEG, Section 5 shows an example of modular GUI design and of its verification, Section 6 reports on the implementation, and Section 7 discusses extensions to more sophisticated interaction paradigms. Finally, Section 8 describes related work and Section 9 draws a few conclusions. An Appendix defines VEG syntax and semantics. 2. THE VEG FORMAL FRAMEWORK The basic idea underlying the VEG framework is to consider sequences of user input events as sentences in a formal language. These sentences obey some syntactic rules described by grammars (or automata). For example, in some circumstances, opening a document that is already open should be forbidden. In this sense, the grammar describes all authorized sequences of input actions. 2.1 A Simple Example The scene of this introductory example is composed of a window with three main graphical components (see Figure 1): the central component is a small widget representing a juggler while the other two are buttons, labeled Start and Stop respectively, to control the juggler’s behavior. When the window is started, the juggler is idle. When the Start button is pushed, the juggler is expected to resume or to start juggling. On the contrary, when the Stop button is pushed, the juggler is required to stop juggling and to become idle. In addition, there is a Quit action to destroy the scene, selected by pushing the small cross at the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
130
•
J. Berstel et al.
Fig. 1. A Juggler.
topmost, right-hand corner of the window. We ignore the other buttons on the topmost part of the icon. We classify the user actions of pushing the Start, Stop or Quit buttons as input events, denoted with , and respectively. A simple VEG specification of a Juggler window is the following one: Model SimpleJuggler Axiom inactive inactive ::= \createScene idle idle ::= \startJuggling juggling juggling ::= \stopJuggling idle ::= \destroyScene End SimpleJuggler
A model such as SimpleJuggler is the smallest unit of modularity in VEG. A model is a local grammar describing the behavior of an automaton,1 and it is composed of a set of grammar rules. A rule has an optional left-hand side: a variable name (also called a state or a nonterminal symbol), such as inactive, idle or juggling. A rule always has a right hand-side, describing the behavior of the model when in that state. When a rule has an empty left-hand side, it is called a default rule and it may be applied in every state. A rule is similar to a production in the traditional sense of BNF grammars, containing nonterminal elements (the states idle and juggling) and terminal elements, which are either input events (such as and ) or visual actions, (such as \createScene and \startJuggling). Also other types of elements may appear in a rule, to be detailed later. The textual notation reflects the category of the items: input events are in angle brackets, as , and visual actions start with a backslash, as \stopJuggling. An input event is actually an abstraction of a low-level event (such as a left-click of the mouse) or even of a low-level event sequence. For instance, in this example, the event models reception of a closing message received from the window manager, while and model the activation of the corresponding buttons. 1 The
automaton must be deterministic and often it is finite-state. Deterministic pushdown automata are also allowed, but they are rarely useful and limit the possibilities of automatic verification. Some of the constructs of VEG may actually lead to infinite-state behavior, as explained in Section 4. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
131
The VEG notation does not specify how the input events are linked to the lowlevel events. For instance, the input event is not explicitly connected to a left-click of the mouse on a PushButton labeled Start. The link between events is not expressed in VEG, but by means of a dedicated, platform-dependent tool, which filters low-level events and translates them into input events. In our example, the and input events could have been synthesized from button activation, menu selection or keystrokes shortcuts. In fact, the precise view of a “button” in the juggler (i.e., a visual object to be provided by some graphical component of the platform) is not specified: the only logical requirement is that this component may be activated, disabled and enabled. Since the same VEG specification is compatible with different layouts and portable on different platforms, it is possible to experiment with various layouts and platform elements and to reuse specifications defined in different projects, with a different layout. Visible actions are the GUI responses to the interaction with the user. For example, the visible action \createScene is used to create a window or a widget, which are visual objects of the platform. Visible actions correspond to suitable callbacks, defined in a Semantic Library; they can also have parameters (i.e., variables), as described in Section 3. The content of the action may be explicitly programmed in a programming language or selected from a set of predefined actions. 2.1.1 Models, Instances, Visual Objects, Creation and Destruction of Scenes. Each model must be considered akin to a class in object-oriented programming languages. Hence, it must be instantiated before use. Each instance, also called a VEG object, has its own reference and its state, but it obeys the same rules of behavior prescribed in its model. The initial state of the object is an axiom specified at its instantiation. Each VEG object usually has a visual counterpart, called the visual object associated with the instance (such as a PushButton, a TextWindow, etc.), which depends on the platform. The link is prepared at run-time by the visual action \createScene, which creates and initializes all the necessary visual components. The window or the widgets so defined are associated with a VEG object: only one window or one widget may be associated with one VEG object at any time. The visible action \destroyScene is used to destroy the window or the widget associated with a VEG object. When a window is destroyed, also all its visual components are destroyed. Some VEG objects may not be associated with visual objects, for instance, because they behave as a controller of other models or because the corresponding visual objects have not been created yet. 2.1.2 BNF Format and Syntax-Diagrams. In general, the right-hand side of a rule may be in extended BNF format, that is, with the alternative operator |, the optionality operator [ ] and the iteration operator { }. In this article, we use a simplified format for rules, called generalized right-linear, detailed in the Appendix, which is very convenient for automatic verification. Here we just notice that each rule may have various alternatives, separated by the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
132
•
J. Berstel et al.
operator “|”, each having at most one nonterminal variable in the rightmost position. The textual notation of formal grammars that was shown here is introduced only for explanation purposes. It is not always very convenient, since often GUI designers have a preference for visual tools. Actually, the VEG toolkit includes a visual tool for entering and editing formal grammars represented as syntax diagrams, with a specific visual notation, but it is not detailed in this article (see Figure 4). Internally, grammars are represented by an XML document, which of course is not expected to be directly edited or read, allowing the reuse of existing XML tools. 2.2 VEG Constructs for Modular Decomposition The aim of this section is to introduce and illustrate some of the other concepts used in the VEG framework, mainly modularity, enabling/disabling of widgets, parallel composition and communication events. Any nontrivial GUI can hardly be described with one model. The overall grammar of a GUI system is usually partitioned into larger units, called packages. Each package is a collection of models, with standard visibility rules, similar to those of Java. Model declarations may also be imported from other packages. Models may be instantiated and launched in a specified state, and then run in parallel by means of parallel composition in the following sense. They concurrently listen for input or communication events collected by a Dispatcher module: when receiving one event, a component is activated, consumes the event, executes a state transition and then goes back to the “listening” state. When a component is activated, the other components are not allowed to collect events until the first component has completed a state transition. Therefore, parallel composition has an interleaving semantics. To illustrate these features, we take an overly simple case and show how the Juggler specification could be broken down into modules, by separately specifying the control of each component. The level of abstraction is lowered for the purpose of explanation of our model, by attaching a VEG object to each visual component of the juggler instead of abstracting a visual component with an input event. This also shows that our tool allows GUI designers to consider different levels of abstraction, even in the same specification. The choice of the abstraction level may also have an influence on the validation phase described in Section 4: the more detailed the specification, the more precise (and the more difficult) the validation. A model called Activator is in charge of controlling a button, regardless of the actual widget implementing it. An instance of Activator may be in one of two states: enabled or disabled. When enabled, it may be activated (e.g., pushed): in this case it sends a message (a communication event) activated to any model willing to listen and goes to the disabled state. When disabled, it waits for a message enable: if it receives it, it goes back to the enabled state. Also, an Activator object, when created, may be started in any of the two states. This may be easily accomplished because a model may have more than one axiom, to be selected at creation time. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
133
This can be described in VEG with the following specification, which we assume is part of a package called BasicComponents. Package BasicComponents Model SimpleActivator Axioms disabled, enabled enabled ::= !activated disabled disabled::=?enable enabled End SimpleActivator
The input communication events (i.e., received messages) start with a question mark, followed by the name of the event, such as in ?enable. Output communication events (emitted messages) start with an exclamation mark followed by the name of the event, such as in !activated. In both input and output communication events, the name of the source or of the destination of the event is optional. The juggler can be described by a model as follows: Model Juggler Axioms idle idle ::=?start.activated \startJuggling !stop.enable juggling juggling::=?stop.activated \stopJuggling !start.enable idle End Juggler
A juggler, when idle, expects to receive a communication event ?start.activated, that is, an event activated coming from a SimpleActivator called start. Next it starts juggling and sends an event enable to a SimpleActivator called stop, going to the state juggling. The definitions of start and stop must be given in the same package of the Juggler. When juggling, a juggler waits for a communication event activated coming from stop: if it receives it, it stops juggling, enables the Activator start and becomes idle again. Notice that the optional ability of specifying the source and the destination of communication events may avoid name clashes of events among different models, but it reduces the genericity of the model (e.g., the SimpleActivator). Another model, called Box, is in charge of creating and initializing the visual objects and instantiating the models. To start a juggler, one has to instantiate the Box. Model Box Axioms start start ::= \createScene begin begin ::= launch( –parallel composition of objects juggler = Juggler.idle, start = SimpleActivator.enabled, stop = SimpleActivator.disabled) running running ::= \destroyScene End Box
The launch operator (which may appear also in many rules) is used to denote a parallel composition: some children processes are created, named and started in the specified state. This is a form of dynamic instantiation of windows and widgets. In the example, an instance of the Juggler is created and initialized in ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
134
•
J. Berstel et al.
the idle state, by means of the statement Juggler.idle, acting as a constructor of an object of type Juggler, and its reference is stored in a instance variable called juggler; two instances of SimpleActivator are created in the enabled state and in the disabled state, respectively and are stored in the instance variables start and stop. The three instances are then started in parallel. In this example, the Box is only a container without human interactions (except for the event ) in charge of launching the other components and of initializing the scene. In other cases, such as the speech dialogs of Section 7, a container may be a privileged center of communication between its members and other components. The complete specification of the juggler is organized in a package as follows: Package JugglerPackage import BasicComponents Model Juggler. . . Model Box . . .
Object names are global in the same package. All objects run in parallel (in the sense already explained) and may synchronize by exchanging communication events (which, basically, are higher-priority, internally-generated events). 2.2.1 Enabling and Disabling Widgets. In the Juggler example, the start Activator cannot be activated when the Juggler is already juggling. This behavior results from the VEG specification: when the Juggler is in the state juggling, the start Activator is in the state disabled and the input event is not accepted in this state. In other words, the event is not in the lookahead set of the state disabled. In general, the lookahead set is the set of events that may be accepted in the current state. Various approaches may be followed for handling occurrence of events that are not in the current lookahead set. First, the GUI may simply ignore the event. This solution, however, has a problem because the user of the GUI is left wondering which actions will have an effect. A friendlier approach is to disable the components responsible for handling the event: Nymeyer [1995] introduced the use of lookahead sets to disable the components (such as buttons or menu items) that are not relevant at a given time, by shading them out: shading is precisely a visual counterpart of disabling. A more general solution is that more general actions can take place to treat undesired events, under the responsibility of the receiving instance. In this framework, the instance is just informed that it cannot be reached from a given component and it executes the appropriate action that may disable and shade the component or raise a warning in response to undesired component events, etc. This solution also simplifies the reuse of the same logic with multiple views, and is followed for instance by Bastide and Palanque [1995]. VEG allows the designer to follow any of these approaches. 3. MANAGING DATA STRUCTURES The expressive power of syntax is not always adequate to model-specific behaviors. For example, a typical login session needs a function to check whether the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
135
password is correct. This kind of utility routine is of course independent of GUI design, but the result of a routine may influence GUI behavior to a significant amount. Semantic functions and variables are designed for modeling this role. They are collected in a so-called Semantic Library and are written in a classical programming language (Java in our prototype). The result is an attribute grammar-style declarative specification. A semantic function takes some values as arguments and may compute other values as result. Also visible actions may receive/return values. Variables (or semantic attributes) can be associated with input events, states and communication events in order to store values to be passed to and from functions and actions. For instance, many input events, such as pressing a key or pointing and clicking, have some values associated with them, such as the character entered or the numeric value selected on a scale. Such values may be stored in one or more variables (attributes) of the event. Values associated with communication events may be used to interface the models in a parallel composition. Each variable must be properly initialized before its use. For instance, whenever a VEG specification describes a state transition, each variable associated with the next state must be initialized calling a suitable semantic function. The set of values a variable can take constitutes its domain. A domain can be any data type, simple (Boolean, integer, . . .) or structured (array, record, . . .). Attribute domains are declared with the syntax of the programming language to be used for coding the semantic library. Some semantic functions may play a special role: they are semantic predicates and semantic actions. Semantic predicates are boolean functions that can be used as guards in a syntactic alternative of a production, as shown next, and hence may have a direct effect on the behavior of a GUI. Semantic actions may be inserted in any point in the VEG productions and are meant to model actions that the GUI must accomplish in response to events, but without a visual effect (such as searching an element in a list, storing a value in a file, etc.). Semantic actions and predicates are typically used to link a GUI to the actual application. 3.1 Example of Semantic Functions A Login Session is a dialog where a user is required to enter a username and a password in order to start a session with a remote host. The dialog box is composed of two text-input fields, user name and password and the button Ok. After entering name and password, pressing the Ok button starts a verification procedure. If the login is correct, the dialog is closed and the connection is established. If the login is not correct, the user is asked to retry. After a fixed number of failed login attempts, the dialog is closed. It is possible to abort the dialog at any time by pressing the Quit button. In a possible VEG specification, the action of pushing the button labeled Ok after filling the two textfields is modeled with an input event . The user name and the password are two string variables userName and passwd of the event. The integer attribute n of the state login keeps track of the number of login attempts. To deal with variables, the specification is annotated with ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
136
•
J. Berstel et al.
suitable calls to semantic functions that are italicized here. Each annotation is preceded by a slash, such as /login.n = 0. Model LoginSession Axioms start start ::= \createScene /login.n = 0 login login ::= /login.n = increment(login.n) if/loginCorrect(enterData.userName, enterData.passwd) launch(Session.start(enterData.userName)) \destroyScene elsif /notTooMany(login.n) \message(“Retry”) login else \message(“Login Failed”) \destroyScene fi End LoginSession
The semantic predicates loginCorrect and notTooMany are used to discriminate among the various alternatives, by means of an if . . . elsif . . . else fi construct. We assume that there is one model called Session, which is instantiated and launched in the state start, receiving also the current value of userName; the latter value will be used by the Session object to initialize a variable associated with the state start. When the semantic functions loginCorrect, notTooMany, increment, to be included in a Semantic Library, are properly implemented in Java, the VEG toolkit is able to generate an integrated LL(1) parser/semantic analyzer, as illustrated in Section 6, and included in the runtime architecture of VEG. The first version of a VEG specification need not detail semantic functions and variables, to be added in a successive refinement. In this case, a VEG specification is said to be purely syntactical. For instance, the rules for the login specification could be written as: start ::= \createScene login login ::= /increment if /loginCorrect launch(Session.start) \destroyScene elsif /notTooMany \message(“Retry”) login else \message(“Login Failed”) \destroyScene fi
Executable code cannot usually be generated from a purely syntactical specification, which may lack variables and the implementation of actions. However, powerful forms of verification and validation, as shown in Section 4, are allowed for such specifications, making them very useful for prototyping and design. Since, in this article, we are mainly interested in showing the support of VEG to design, verification and validation, rather than explaining how to program a real GUI, all VEG specifications in the remainder of the paper are purely syntactical. 3.2 Predefined Semantic Functions In the example of Section 3.1, only loginCorrect really needs to be defined by a semantic function, since notTooMany and increment could be specified with finite-state counting. Using finite-state constructs instead of semantic functions is preferable for validation purposes, since clearly Java programs are much harder to deal with than finite-state machines. However, explicit finite-state control can be very inconvenient: counting up to a threshold K requires at least ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
137
K control states. To make finite-state control easier, VEG provides a set of predefined finite-state semantic functions and variables, such as those related to modulo counting: finite counters, Boolean variables, increment or decrement, modulo comparison, initialization, comparison with a constant. Even though they are considered semantic functions, they are translated to finite-state constructs for verification and validation. Potentially, these finite-state constructs may also lead to very large state spaces, but this is rarely the case. Currently, only counters and another set of finite-state semantic functions, namely the group selection features shown in Section 3.3 below, are part of the VEG toolkit. However, new semantic functions can be defined and modeled by finite-state constructs, possibly driven by verification needs. Nevertheless, in the generated code, they are treated at the same level as programmer-defined semantic functions. 3.3 Containers, Groups and Counters The children of a VEG object, at a given instant, are defined as the components launched (i.e., instantiated) by the object and which did not terminate their execution yet. A VEG object that may generate children is called a container. Some special VEG constructs are available to simplify communication among the children and between the container and its children. A container can broadcast a communication event to all its children, by using the target all (e.g., !all.enable sends an event enable to all the children of the container). To allow more flexibility, a container may also broadcast communication events to a selected set x of children, called a group, or to its complement ∼x. The creation and the modification of groups may be accomplished by means of a set of predefined semantic actions and predicates, called group selection mechanisms: the action /x.add adds, to the group x,the child that sent the latest communication event to the container, while the action /x.remove, removes it from x, if present; the semantic predicate /x.isEmpty may be used to check whether a group x is empty, while /x.clear makes xempty. For instance, the fragment ?selected /G.add !G.enable !∼G.disable first waits for an event called selected. When a child c sends the event, c is added to the group G. Then, an event enable is sent to all the children in the group G,and hence also to c, and an event disable is sent to the remaining children. An example of application of group selection mechanisms can be found in Section 5. Group selection features, while being realized with semantic actions and predicates, are essentially finite state, as long as the number of children is bounded, and hence do not hamper the possibility of automatic verification of VEG specifications. In fact, they are useful shorthand notations to avoid an increase in the rules of a model. 4. AUTOMATIC VERIFICATION AND VALIDATION Model checking [Clarke et al. 1986; Holzmann 1997] is a powerful and useful technique, allowing the automated verification that a finite state machine verifies a given property, often specified in a temporal logic language. Model checking is thus the ideal verification tool, because it is completely automated. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
138
•
J. Berstel et al.
However, the verification of nontrivial software systems requires the implementation to be abstracted to make the verification feasible. Abstracting a program into a meaningful and relevant finite-state version is not an easy task, since the number of possible states of the system must be greatly reduced. Hence, an abstraction must introduce significant approximations to the original system. The VEG formalism has been designed in such a way that an abstraction of the system can easily be obtained, allowing an automatic translation into the Promela language of the model checker SPIN. In fact, when studying formal features of an event-driven user interface, the actual values of the parameters passed to and from the semantic and visible actions may be ignored: it suffices to record the event that a semantic or visible action has been called, rather than calling it. When semantic predicates are present, however, this introduces a loss of precision, since the predicates used as guards of a branch cannot be evaluated anymore: the choice of the branch to be followed becomes nondeterministic. The translation into Promela considers only some predefined semantic actions of VEG, such as the already cited counters and selection mechanisms, for example, checking that no event is ever sent to an empty group. Also other semantic actions, such as the number of attempts in the login dialog example, may be easily modeled. On the other hand, programmer-defined semantic actions (ad hoc coded in Java) are ignored by the translation and treated as part of the terminal alphabet. However, the set of predefined semantic actions can be further extended to deal with other semantic actions that can be modeled in Promela. 4.1 Transducers, Local and Global States, Reachability Stable States In order to define the translation from VEG into Promela, a VEG specification P can be conceptually represented as a transducer (see, e.g., Berstel [1979]) TP computing a transduction from an input alphabet of input events to an output alphabet of (visible and semantic) actions. A transducer is a kind of state/transition automaton: the automaton is initially waiting for input events in an initial configuration; when it “reads” an input event then it makes a transition, consisting in the computation of semantic functions, variable values, internal exchange of communication events, and emission of suitable output symbols. The transition is completed when the transducer becomes ready to read another input event. The transducer TP is actually composed of various VEG objects, which may be created and destroyed. Each object is in a local state ct , σ t , where ct is a control state (such as the state login), and σ t is an assignment of a value to each semantic variable defined in the state (e.g., σ t (login.name) is the string assigned to the variable login.name). A (global) state of the transducer TP is composed of a local state for each object, that is, it is a global configuration for TP . In the following, global states are assumed to be stable, that is, to correspond to configurations where the transducer is waiting for input events and no local state change is still pending. A global state S′ is a successor of a global state S if S′ may be reached from S in one transition; S′ is reachable from S if it is either a successor of S or a ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
139
successor of a state reachable from S. Each transducer has an initial state: let the reachability Reach(T P ) of a transducer TP be the set of states of TP that are reachable from the initial state. 4.2 Semantically Branching Transducers and Abstract States Often, TP contains semantic predicates on variables other than counters and groups, which may cause different branches to be taken depending on variable values. Denote with Abst(T P ) the transducer obtained from TP as follows: (1) replace the if . . . else constructs, which contain semantic predicates involving semantic variables other than counters and groups, with the alternative operator “|”; (2) eliminate semantic variables and functions, other than those for counters and groups; (3) eliminate all arguments of semantic and visual actions. In practice, the transducer Abst(T P ) corresponds to a purely syntactical version of TP . In general, the transduction computed by Abst(T P ) is different from the transduction computed by TP : in this case, TP is called semantically branching. For each local state of the form ct , σ t its abstract version is Abst(ct , σ t ) = ct , σ ′ t , with σ ′ t being the restriction of σ t to counter and group variables. An abstract state of TP is a obtained from a global state of TP by considering the abstract versions of its local states. We overload the name Abst to denote also the operation of abstraction on a state or on a set of states. A state is also called concrete when it is not abstract. 4.3 Reachability, Deadlock, Invariants We now show that the abstraction Abst is meaningful for deadlock detection, analysis of unreachable states and state invariant verification. It is easy to see that: Abst(Reach(TP )) ⊆ Reach(Abst(TP )) (∗) that is, the abstract states in the reachability of TP are also in the reachability of Abst(T P ). Hence, if a concrete state is reachable for TP , its abstract version must be reachable for the transducer Abst(TP ). This suggests that information about TP may be deduced from verifying Abst(TP ). Given a transducer TP , assume that all its semantics functions, semantic actions and visible actions terminate for all their inputs. A deadlock state for TP is a state that has no successor; TP is deadlock-free if no state in Reach(T P ) is a deadlock state. A state property is a set of states of TP . A state invariant J for TP is a superset of Reach(T P ) (i.e., Reach(T P ) ⊆ J). For instance, a state invariant for the Juggler example may assert that the Activator start is in the local state enabled if, and only if, the Activator stop is in the local state disabled. Notice that if an abstract state verifies a state property, its concrete versions also do, as precised in Statement 1, part 3, that follows. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
140
•
J. Berstel et al.
The following properties are a consequence of the previous definitions and of property (*): STATEMENT 1 (1) For each state x of T P , if Abst(x) is not reachable in Abst(T P ), then x is not reachable in T P . (2) If Abst(TP ) is deadlock-free, then TP is deadlock-free. (3) Let J be a state property defined on the states of Abst(T P ). Then for all abstract states c, σ ′ , if c, σ ′ ∈ Reach (Abst(T P )) ⇒ c, σ ′ ∈ J then c, σ ∈ Reach(T P ) ⇒ c, σ ∈ J ∧ , where J ∧ = {c, σ | Abst(c, σ ) ∈ J}. PROOF. Part (1) is an immediate consequence of Property (*). Part (2) follows by contradiction: if TP has a deadlock state x, then, by (*), Abst(x) is reachable in Abst(T P ). Notice that the only case of a deadlock state is a communication event pending for an object that is able to consume it (typically, the event was sent to an object that was not waiting for it). In fact, in VEG, as formalized in the Appendix, each if · · · fi construct has always an else branch, in each state all guards depend only on (communication or input) events, and we assumed that all visual actions and semantic functions terminate on all inputs: a deadlock never arises because of variable values. Hence, since Abst(x) has the same communication event still pending (because it is not abstracted), it must also be a deadlock state. Part (3) is just a special case of the main result of Clarke et al. [1994]. A direct proof is as follows: let c, σ ∈ Reach(TP ). Apply the Abst operator on each side: c, σ ′ ∈ Abst(Reach(TP )). By (*),c, σ ′ ∈ Reach(Abst(T P )). By hypothesis and modus ponens, c, σ ′ ∈ J. Thus, c, σ ∈ J∧ . Statement 1 shows that the chosen abstraction is safe with respect to reachability analysis, deadlock-freedom and state invariants. However, the verification on the abstract version may find spurious counterexamples, that is, errors on the abstraction only. In fact, the converse properties of Statement 1 may not hold when TP is semantically branching. For instance, a concrete state guarded by a semantic predicate may be unreachable because the predicate is always false, while its abstract version is reachable (because it has no guard), contradicting the converse property of Part (1); also, the abstract version may be a deadlock state, even though is not reachable in TP , thus leading to a spurious counterexample. 4.4 Finite vs. Infinite State Often, Abst(T P ) is finite-state (e.g., the Juggler example) and hence it can be verified by using conventional model-checking techniques. The number of states of Abst(T P ) for a GUI is usually not very large: for instance, it can be just a few hundreds for a simple text editor like the Windows Notepad and even much larger numbers can be handled by model checkers. The transduction Abst(T P ), however, is not finite-state when the number of VEG objects in Abst(T P ) cannot be bounded by any integer (e.g., the user is allowed to instantiate any number of copies of a window). In this case, Abst(T P ) is called an unbounded transduction and cannot be verified using the standard ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
141
model-checking techniques of SPIN. In this case, we introduce another approximation, by fixing an upper bound N on the number of VEG objects that can be created. Under these assumptions, we obtain a finite-state approximation Abst N (TP ) of Abst(T P ). The transduction Abst N (TP ) can be verified by model checking when N is not too large. The verification results for Abst N (TP ) are in most cases extendable to Abst(T P ) and then to TP , as shown by the next statement. STATEMENT 2. Let Abst(T P ) be an unbounded transduction. (1) If a state x is reachable in Abst(T P ), then it is reachable in some Abst N (TP ). (2) If there is a deadlock in Abst(T P ), then there is a deadlock also in some Abst N (TP ). (3) If an invariant J is not verified for Abst(T P ), then it is not verified also for some Abst N (TP ). Statement 2 cannot give any guarantee that the results of a verification on a finite-state version Abst N (TP ) may be extended to an unbounded Abst(T P ): for a given N , Abst N (TP ) may not be a safe abstraction of TP . For example, a deadlock in Abst(T P ) may occur only when a certain number k > 0 of instances of a model have been created: checking only Abst N (TP ) with N < k cannot detect the deadlock. However, it is often the case that either a system does not work correctly for a small value of N (such as three) or it works correctly for every N . Hence, even with small values of N we can increase the confidence in the correctness of the specification: the results of the verification obtained on the approximation give some useful and meaningful hints on the correctness of the original specification and may potentially detects errors, although they cannot be automatically generalized. There are also cases where the generalization is actually guaranteed, as shown by Norris Ip and Dill [1996]. A symmetry-based reduction on finite, unordered sets (not to be used as an array index or a loop index) allows the automatic reduction of an infinite state case to a finite state one. This technique could be exploited also for VEG, since its assumptions are often verified by VEG containers. 4.5 Verification and Validation in Practice During the experiments that various developers and we performed, many errors have been found and corrected on complex specifications by using SPIN. Once an error is found, SPIN builds a counterexample that shows the internal sequence of events and state transitions leading to the error. Knowing the internal behavior of the system makes debugging much easier: in traditional testing of the actual GUI, only the “external” behavior of the program is visible. At present, there is no tool allowing to trace back errors from SPIN to the original VEG specification, but this is not a major obstacle for comprehension, since the generated Promela code is conceptually, even though not syntactically, very close to the original VEG specification. We do not expect average GUI designers to find Promela easy to use as a design language, since its constructs may have a very subtle semantics. Also, ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
142
•
J. Berstel et al.
it is not clear how to integrate semantic functions into Promela code. However, we included in VEG only that small part of Promela’s expressive power that is useful for GUI construction. Hence, VEG is much simpler and explicitly devoted to the production of GUIs, and it can be much more convenient to use than Promela for such applications. Some of the errors detected with SPIN could have been found also with simulation and testing, but some would have probably escaped even an accurate testing phase. For instance, in the specification of a Notepad-style editor (a small piece of which is reported in Berstel et al. [2001]), when the mouse button was held to make a selection, it was possible to activate other dialogs with keystrokes and to send commands such as paste or cut (for instance, allowing to cut a text which was not yet completely selected). With SPIN this error was immediately reported by deadlock detection, before designing the layout and linking it to the VEG specification. This kind of error can also be found with traditional testing, but with higher costs of detection and correction. As already defined, validation is also supported by means of state invariants (i.e., Boolean assertions that predicate about the states of the various model instances) to be checked against a VEG specification. State invariants are meaningful only in stable states (i.e., configurations where the transducer is waiting for input events and no local state change is still pending). State invariants in VEG are typically associated with a model or a package but they may also be associated with a rule, to denote invariant properties that hold whenever an object is in the stable state associated with a rule. The notation x(S) may be used as a boolean predicate to denote that the object named x is in the stable state S. Also, to allow bounded quantification, the notation existsX(S) may be used to denote that at least one launched instance of a model X is in the state S. Analogously for forallX(S). Of course, since SPIN allows the checking of linear temporal logic formulas and the verification of logic assertions, an experienced model-checking specialist could directly use SPIN for stating and proving the desired properties. However, we prefer to provide some explicit support in VEG for defining at least invariant properties, so GUI designers avoid of dealing with Promela. For instance, an invariant for the above-cited Notepad example of Berstel et al. [2001] is that the cut and the copy items of an Edit menu are enabled if, and only if, the text is selected. If the text is a VEG object that may be in one of two states: unselected and selected, then the invariant may be written as the conjunction of the following two formulas, where -> and && stand for logical implication and logical conjunction respectively: text(unselected) -> cut(disabled) && copy(disabled) text(selected) -> cut(enabled) && copy(enabled)
Each invariant is translated into an assertion of SPIN. SPIN can verify assertions (i.e., Boolean formulas) in any point of the specification, with the same effort of deadlock and reachability analysis. This kind of validation activities is well supported by SPIN. In the above example of the Notepad editor, there was actually a problem with the copy button, which, as usual in text editors, should always be enabled whenever the text is ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
143
Fig. 2. The switcher.
selected: actually, the copy button was an Activator that became disabled after its activation, even though the text remained selected. The problem was that the controller did not send an event to enable it again after an activation. This is a specification error, which could not be detected by deadlock or unreachability analysis, but which was easily found using the assertion checking capabilities of SPIN to verify that the above invariant text(selected) -> cut(enabled) && copy(enabled) was not verified. SPIN showed the path leading to the error, allowing us to identify the problem in the usage of activators that become disabled after the activation. Again, the error could have been found also with traditional testing, but with much higher costs of detection and correction. SPIN also allows writing temporal logic specifications. Currently, our tool provides no direct notation for doing this: a formula must be inserted via the SPIN interface. This requires a certain level of competence with SPIN and with temporal logic. 5. HIERARCHICAL DESIGN OF SCALABLE COMPONENTS AND ITS VERIFICATION This section shows how to combine some VEG constructs for modular design of graphical interfaces, in order to obtain a hierarchical description of visual communicating modules. To show that VEG is scalable, we illustrate the modular design of a typical GUI. The following example shows also how complex communication is modeled by a VEG grammar and illustrates the group selection mechanisms. 5.1 The Switcher The Switcher is a user interface with two or more lists, and one button allowing transfer from one list to another. This interface is used for instance in some ftp tools, and was popularized by the Macintosh Font/DA Mover. A typical layout is shown in Figure 2 with only two lists. Indeed, the main purpose of the application consists in allowing the move of a selected item from its list to other lists, when the Transfer button is activated. The interface has an apparent simplicity, but the interaction between ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
144
•
J. Berstel et al.
the components is rather involved. For instance, the transfer button is enabled only if at least two lists have been opened and some item has been selected in one list. However, the button should not be enabled when only one list is open, even if an item has been selected, since no transfer may occur in this case. Each of the lists is composed of an Open button and of a widget that can show a set of items. This button allows a sequence of items in the list to be loaded. As shown in Figure 2, there is also a Save button. The role of this button is to save the lists that have been modified. Of course, this button may be activated only after a transfer has taken place since the last save action. We assume for simplicity that pushing the Quit button causes the application to quit without a save dialog, but this could be easily extended to a more realistic, and user friendly, case. The state of a list is one of closed, ready or selected. Here, closed means that no file has been loaded yet, ready means that a file has been loaded, but no item has been selected; and selected is the remaining case, that is, an item has been selected in the list. We assume for simplicity (but this is not critical) a singleselection model: only one item can be selected at any time. When several lists are ready, only one can be selected: the selection of one item in a list immediately deselects any item that could have been selected in another list. In view of the hierarchical design we adopt here, the VEG specification of the Switcher is composed of a Box with four components: transfer, the transfer button, save, the save button, quit, the quit button and the controller, that is a container of the lists. The buttons transfer and quit have all the same behavior: they may be enabled or disabled based on the global state of the system (hence, on receiving suitable communication events). This behavior of the menu entries is so general that it should be inserted in a library of reusable components, such as the package BasicComponents. Hence, we first describe a more complex Activator than the one used in Section 2, namely an activator that can also be disabled or enabled by receiving a suitable communication event regardless of its current state. To make the Activator as general as possible, the enabling/disabling events are considered only if a source called client, specified as a parameter of the model, has sent them. The actual value of the client parameter is a VEG object to be specified at creation time. The client is also the target of the communication event activated. This model may also be included in the Package BasicComponents. Package BasicComponents Model Activator(client) Axioms disabled, enabled enabled ::= \changeAspect !client.activated disabled DEFAULT ::= ?client.disable disabled – default rule | ?client.enable enabled End Activator
A default rule is in charge of handling the disable and enable events (hence, no rule for the disabled state is necessary). The visible action \changeAspect must be specified for changing the aspect of the button (e.g., changing the displayed text, etc.). ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
145
The Controller contains instances of a List model, each one associated with an open button. To make the design modular, all communications to and from the lists is through the controller. For instance, no knowledge even of the existence of the lists is necessary for the transfer button: it just notifies the controller when it is activated. This design has also the advantage of allowing a variable number of lists, without any modification to the Controller model, except for the initialization (start) state. The Box model, part of a package Switcher, is used to launch a switcher window, instantiating the various buttons and a Controller described below. Both the Transfer and the Save buttons are Activators. The lists are not initialized here, but by the Controller itself. Package Switcher Model Box Import BasicComponents Axioms start start ::= \createScene – scene initialization launch( cont = Controller.enabled, save = Activator(cont).disabled, transfer = Activator(cont).disabled ) running running ::= \destroyScene End Box
After scene initialization, the Box launches a Controller called cont and two Activators, called save and transfer, by instantiating the client parameter of the Activator model with the controller itself. Then, the Box goes to the running state where it waits for the input event (associated with the Quit button), before destroying the scene. The list components of the switcher have a less general behavior and the corresponding model is included in the Switcher package rather than in a library package. A list is initially closed. When its open button is pushed (i.e., an open input event is generated), it executes a visible action \load (such as, load a list of items from a file and show them), it notifies the controller and goes to the state ready. In the ready state, if an item is selected the list goes to the selected state, notifying the controller; if it is opened again (e.g., loading a new set of items) it stays in the current state; otherwise, it waits for the controller to send suitable events in order to save its current content or to insert a new item in the list (by means of the visible actions \load and \insert). In the selected state, another item may be selected, or the list may be opened again (losing the previous selection and notifying the controller) or it may save the current content; finally, the list may receive a setTransfer event, deleting the current item. Notice that changing the selected item is treated internally to the list (i.e., no communication event is sent). Moreover, there is no input event to deselect a list: deselection may only be triggered by a selection in another list or by a new open command on the same list (possibly, with the effect of reopening the file). The specification of the actual item to be inserted or deleted is left to the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
146
•
J. Berstel et al.
semantic part of the specification (e.g., a reference to it may be exchanged via the communication events getTransfer and setTransfer). Notice that a list does not notify the controller when it is reopened. Package Switcher Model List Axiom closed closed ::= \load !firstOpened ready | ?save /save closed | ?getTransfer closed ready ::= !selected selected | \load ready | ?save /save ready | ?getTransfer \insert ready selected ::= selected | \load !unselected ready | ?deselect ready | ?save /save selected | ?setTransfer \delete ready End List
The Controller cont is used to synchronize the behavior of the lists. After launching the lists, the controller may be in one of the states: allClosed, oneReady, severalReady, transferable. In the allClosed state, the controller waits for one of the lists to become open. In the oneReady state, it waits for another list to become open. If a list is selected before any other list is opened, then the controller stays in the state oneReady, but it adds the list to a group, called sel, in charge of storing the last selected list. If the second list is opened, then it checks whether the first list was already selected (if sel.clear): if this is the case, a transfer is already possible, otherwise it goes to the severalReady state. When one list is ready and another is selected, then the controller enables the transfer button and enters the state transferable. Finally, if the save button is activated, the controller notifies all lists in the group and goes back to severalReady. In the state transferable, if the transfer button is activated (transfer.enable), the controller makes the transfer happen, sending the getTransfer and setTransfer events, enabling the save button and going back to severalReady. Otherwise, if one of the lists is unselected, it goes back to severalReady, or if a list is selected, it deselects the list which was selected, clears the sel group and add the selected list to the group, staying in the transferable state. Finally, if the save button is activated, the controller notifies all lists to save their content. The List model and the Controller model were designed to work without any knowledge about names and number of the lists. Since each list has three states, it may seem that 3n states are required to represent the behavior of the Controller for n > 1 lists. In fact, only four states are needed because of the selection mechanism, which allows the identification of symmetric configurations. For instance, oneReady holds in four configurations, namely when one of the lists is either ready or selected and the others are closed, but it can be ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
147
represented with one state since the group selection keeps track of which list is selected. This state saving may appear small if n is small (four states against nine if n = 2), but the number of states of the controller is actually a constant, not changing with the number of lists. The save button is enabled only after a transfer has been done. Package Switcher Model Controller Axiom start Group sel start ::= launch(List.closed, List.closed) allClosed allClosed ::= ?firstOpened oneReady oneReady ::= ?firstOpened if /sel.isEmpty severalReady else !transfer.enable transferable fi | ?selected /sel.add oneReady | ?unselected /sel.remove oneReady severalReady ::= ?firstOpened severalReady | ?selected /sel.add !transfer.enable transferable | ?save.activated !all.save severalReady transferable ::= ?firstOpened severalReady | ?selected !sel.deselect /sel.clear /sel.add transferable | ?unselected /sel.remove !transfer.disable severalReady | ?transfer.activated !sel.setTransfer !∼sel.getTransfer /sel.clear !save.enable severalReady | ?save.activated !all.save transferable End Controller
5.1.1 Variations of the Example. We could avoid the use of the semantic predicate isEmpty, by expressing this choice syntactically, introducing a new additional state to record the configuration when the only ready list is also selected. On the other hand, we could add further semantic predicates and merge also the states transferable and severalReady. The choice between syntactic and semantic solutions should be driven by readability of the code and by the fact that verification is simpler with the syntactic solution. This example, while small, is very complex. However, the complexity resides in its logic and not in the VEG notation, as it should be clear by looking at the very long informal description of its detailed behavior. The VEG notation is actually much clearer than any informal one. Moreover, some of the complexity of the notation depends also on the fact that the example has been designed to work with many lists: a transfer is done from the selected list to all other ready lists. For instance, for three lists, just write in the controller: start ::= launch(List.closed, List.closed, List.closed) allClosed
This illustrates the generality and extendibility of this approach and the reusability of the components. However, one should not assume that the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
148
•
J. Berstel et al.
validation of the two-list switcher implies the three-list version is correct: the latter specification should also be validated with SPIN. It is also easy to generalize the Controller specification in order to handle dynamic instantiation of lists. However, in this case, verification should be bounded to a maximum number of lists (three being the most reasonable bound).
5.2 Verification and Validation of the Switcher The Switcher example was the perfect test bed for applying verification and validation techniques before implementation, since its subtle logic may cause many design errors. Actually, various errors were found in earlier versions of the Switcher by using deadlock detection in SPIN. For instance, the original specification used a SimpleActivator instead of an Activator. We recall that if a SimpleActivator is enabled then it waits either for a disable event or an activate event, but it does not expect an enable event. However, the Controller, after every transfer, sends an enable event to the Save button, which is already enabled and cannot receive it: the system enters a deadlock. Another example is the original specification of the switcher, intended to allow any number of lists, where some parts relied on the assumption that only two lists were used. For instance, the specification of the List wrongly assumed that no save event could be received when the list is still closed: with more than two lists, a save event may actually be received by a closed list after a transfer between two ready lists, since the statement !all.save sends a save event to all lists, whether ready or closed. Similarly, the getTransfer event is sent to all lists, including the closed ones: a first version of the specs did not deal with a getTransfer in the closed state of the lists, causing a deadlock in the specification. Reachability analysis allowed us also to find that we introduced some useless alternatives in the Controller rules (e.g., waiting for an unselected event in the severalReady state of the Controller, which will never happen, since in this state no List is selected): the alternatives were eliminated, leading to a simpler specification. Another issue is validation: how can we be confident that the behavior of the Switcher is exactly the intended one? As already remarked, simulation and testing may also be used, but property verification may be a very useful validation technique. For instance, it is easy to understand that the correct behavior of the Controller is based on the fact that in the state closed no list is ready, in the state oneReady only one list is ready, in the state severalReady at least two lists are ready but none is selected, and in the state transferable one list is selected and at least another list is ready. These properties can be considered as invariants of the specified system. In particular, the invariant asserting that if the Controller cont is in the state transferable then there is one List that is in the state ready and another one that is in the state selected, is written as: cont(transferable)-> existsList(ready) && existsList(selected) ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
149
As already pointed out, also the temporal logic LTL may be used. For instance, the above invariant may be written in temporal logic as: [](stableState -> (cont(transferable) -> (existsList(ready)&&existsList(selected)))
where stableState (with a suitable definition) holds whenever the system is in a stable state. Another example is a liveness property that does not hold on the Switcher specification (where is the Eventually operator): [](stableState -> (existsList(selected) -> cont(transferable) ))
with the meaning that if a list is selected, then sooner or later the Controller will reach the state transferable. This was verified by SPIN to be false on a 4-list switcher in only 20 atomic steps, showing that there is infinite cycle open/select/open . . . of events for the same list, preventing the controller from ever reaching the state transferable. 6. EXPERIMENTS, IMPLEMENTATION AND OTHER FEATURES OF VEG This section reports on the VEG implementation and its application, describing also some minor features of VEG to make GUI design more flexible and more efficient. 6.1 The VEG Toolkit The notation and results presented in the previous sections are part of a Long Term Research project of the European community, called Gedisac (Graphical Event-Driven Interface Specification and Compilation). The project comprised several partners from university and industry. The aim of the project was to develop a set of tools, based on compiler technology, to support GUI design and testing. These tools are designed to complement traditional layout tools such as those provided by Java Workshop or J++. The intended users of the tools are both GUI designers and programmers. The toolkit, developed in Java, includes a visual editor of VEG specifications, a parser generator, and tools and libraries for linking specifications to the platform. The development process is depicted in Figure 3. The GUI designer interacts with the Visual VEG Editor (VVE) to write a VEG specification (a snapshot of the toolkit is shown in Figure 4). Following a request, the VVE produces three different specifications: the first one is an internal XML encoding of the VEG specification without attributes. The second one contains the set of semantic routines used by the VEG specification implemented in the target language Java (Semantic Library Skeletons). The third one is the Promela translation. The designer may check the consistency of the specification, by using the Promela file as input to the SPIN model checker. This model checking is done in a separate process and could be omitted, but this step is essential for verification and validation activities. In order to produce the real application, the XML file is used to build a set of communicating parsers and semantic evaluators. These objects are linked with the semantic libraries and with the visual components corresponding to the models, which produce the actual input events. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
150
•
J. Berstel et al.
Fig. 3. The VEG development process.
Fig. 4. A snapshot of the Visual VEG Editor (on the example of a pocket calculator).
6.2 Applications and Experiments Realistic applications have been specified and implemented, like a Notepadstyle editor, a graph construction library and a large real application to medical software. Various experiments (reported in Campi [2000]) have found no difference in performance between VEG-generated code and hand-written Java code implementing the same application. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
151
Fig. 5. Window of GUI of a medical application whose behavior was developed using VEG.
Fig. 6. Experimental data for the medical software application.
The development of the complete medical application took originally 24 person/months, of which GUI development accounted for 3.6 p/m. The GUI was redesigned in 1999 with VEG by Txt e-Solutions, an Italian-based software company. The GUI consisted of 10 windows, one of which is shown in Figure 5, and 90 widgets of various kinds (such as buttons, lists, text fields). The developers of the medical software application claimed overall significant time-saving over the original development, as shown in Figure 6. The largest benefits were, predictably, concentrated in the testing phase (the potential benefit of verification and validation via SPIN was not addressed in this project since that feature was not yet supported). We consider this a good indication of VEG potential, since the redesigned GUI was fairly efficient and was developed quickly. However, the comparison with the original development must be used with some caution: the original data were collected from previous documentation of unknown quality, and it is usually easier to redesign than to design, even when different people are involved. 6.3 Run Time Architecture Each model of a VEG specification corresponds to a Java class defining a LL(1) integrated parser/analyzer. The ANTLR compiler-compiler [ANTLR], based on ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
152
•
J. Berstel et al.
a LL(1) parser generator, is used to generate Java code. The Java library defining the semantic functions is statically linked to the final application. When a model is instantiated, a new parser/analyzer instance is created. During the execution of the instance, attributes and semantic functions are evaluated and executed, following traditional techniques for L-attributed grammars [Katayama 1984]. Look-ahead sets are computed in advance and may be used for enabling/disabling of widgets (see Section 2.2). The choice of ANTLR, apart from the excellent quality of the tool, is based on its explicit support to attribute definition and evaluation and to the BNF format. Moreover, every VEG module corresponds quite naturally to a parser class of ANTLR, and new VEG objects may be instantiated simply with a call to the Java new operator, making the implementation of the launch operator straightforward. All internal communication events, generated by the parsers in response to input events, are collected and processed by a Dispatcher module. Communication events are queued and then sent to the relevant parser(s). According to the operational semantics of VEG, no new input event is accepted until the parsers reach a stable configuration (i.e., one when no communication event is still pending). The link between input events and low-level events (such as pressing a mouse button) is currently implemented by a Visual Platform Editor, which defines a suitable listener for each widget in the actual layout. Each listener basically defines a mapping from low-level events (or even sequences thereof) into VEG input events. The code for the layout is then automatically linked with the parser/analyzer code. 6.4 Plug and Play Plug and Play is the possibility of run-time extension of a GUI with a new component. Given a VEG application, the GUI development tool is able to provide two objects: an executable file that includes the run-time support, or an Application Package that can be included in an existing VEG run-time architecture. The Application Package consists of Java classes in the format of .class files, implementing the parsers and the Semantic Library specific to the package, and of a translation table, mapping platform events to input events. Also, the Application Package includes the Application Interface, that is, a list of the communication events accepted and generated by the application. To be able to include a new package, the components of VEG run-time support should be defined as containers of objects, and should include only code that is independent of the particular application. The current VEG toolkit, however, gives no support to plug and play, because of its prototypal nature. 6.5 Other Features of the VEG Notation VEG has a few more features, which we briefly summarize here, that are not currently supported by the VEG toolkit and are not included in the description of syntax and semantics of the Appendix. 6.5.1 Reset and Quit. There are two special predefined states, called reset and quit. When the next state is reset, the control must return to the initial ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
153
state, and also all data values are reinitialized. If the object entering the reset state is a container, then by default a special !reset event is sent to each member of the group. When the next state is quit, then the object is terminated. If the object is a container, by default the special event !quit is sent to each member of the group. The ?reset and ?quit events are by default handled by default productions, which force the receiving object to enter the states reset and quit, respectively. The default behaviors of the reset and quit states and of the default productions for ?reset and ?quit may be overridden by defining ad hoc rules. 6.5.2 Timeouts and Delays. VEG has also mechanisms to specify delays and timeout. For instance, to describe the behavior of the “timed help bullet”, a bullet appears next to a widget only after the mouse pointer has been continuously over the button for some time. Delays and timeouts may be modeled in VEG with a special input event called , which takes a delay as an argument. Thus, means a delay of 20 units. For instance, the VEG rule: state0 ::= \doit1 state1 | ?got it \doit2 state2 | \doit3 state3
specifies the following behavior. When entering state state0, the object starts a clock. If any event (either an input or an communication event) is received before the end of the delay (here, 20 units), then the action corresponding to the event is taken: either doit1 or doit2 are executed and the object changes to state1 or state2. If, instead, no event is received before the timeout expires, then the behavior continues as if a event is received: action doit3 is executed and control goes to state3. A timeout event is considered to be served only when the corresponding alternative starts its execution. 6.5.3 Modal and Hidden Dialogs. A dialog is modal when it has priority over the other active dialogs. For instance, a window notifying an error must block the execution of the other components of the GUI until the user clicks the “Ok” button. Modal dialogs may also be specified in VEG, by using the keyword Modal model. To improve performance, also hidden models may be specified, that is, models whose creation and destruction is only apparent. An instance of a model declared hidden is created when its container GUI starts its execution. However, it stays hidden (i.e., invisible) until the instance is launched. It becomes again invisible when the instance is terminated, staying ready to be launched again. It is actually destroyed only when the application ends. This technique is often used in GUI design since it may have a considerable effect on performance. 7. SUITABILITY OF VEG FOR OTHER INTERACTION STYLES Our hypothesis that the specification of interaction is independent of the layout of the visual interface offers potential application to spoken and multimodal dialog management, a promising channel for communicating via mobile and portable terminals such as cell phones. Here, we only report initial investigation ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
154
•
J. Berstel et al.
on the potential of VEG for modeling spoken and multimodal man–machine dialogs. Some more reporting on other interaction styles may be found in the Conclusions. Dialog management systems (DMS) have a long history behind them, and encompass conceptual and technical knowledge from several sources: speech recognition/synthesis, grammars, theory of speech acts, AI plan-based approach, etc. Surveys of the state-of-the-art are in Cole et al. [1996] and Churcher et al. [1997], who provide the frame for our discussion. In spoken DMS, two aspects have to be managed: how user sentences (or lesser units) are interpreted, and the strategy to perform the intended task, for example, to make a travel reservation. Multimodal DMS that combines widget-based and spoken interaction will be considered at the end. The typical building blocks of a spoken DMS are: speech recognition, meaning extraction, response generation, and speech output. In addition, the application block exports the methods that are specific of, say, a travel reservation service. The dialog manager block (DM) coordinates the other blocks. In some systems, the dialog strategy is localized into another block, the task manager. Recognized speech is transcribed, parsed and semantically interpreted. Next the DM matches the interpretation with the expectations of the application, and produces a written reply (a prompt), in accordance with a predefined strategy, via the response generation block. The speech output block synthesizes the speech. Since speech recognition errors as well as other forms of misunderstanding often occur, a recovery strategy is required, allowing the conversation to continue. Low-end voice dialog systems are very simple and constrain the user to choose the reply from a small set of single words. They can be readily specified within the framework of VoiceXML 2.0 [Larson 2003], a proposal for implementing conversational voice Web applications that can be accessed by teleor cell-phones. Their logical structure is essentially a tree of multiple-choice questions that is easy to model in VEG. It is more interesting to consider systems that allow more sophisticated dialogs. However, if dialogs are more complex than a single question followed by a system response, discourse phenomena (e.g., ambiguity, anaphora, ellipsis) complicate the interaction. These more natural dialogs require advanced language analysis methods, which are beyond the scope of VEG approach. In the middle, between these two extremes, we focus on dialogs in which user requirements are spread over more than one turn and a user utterance may consist of more than one prompted word. To map such organization onto the VEG model, we depart from generality and consider a specific, typical case, the DMS design approach of McGlashan [1996], which has been applied to several reservation and inquiry services. Its principles are: (1) Only the system’s goals are represented in the dialog model: user utterances are not assigned dialog acts. (2) Only local transitions are modeled: the dialog as a whole is not modeled, but global structure can still emerge. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
155
(3) Task level information in user utterances is assigned a semantic function indicating its effect on the accessible part of the discourse model. These functions are applied to goals in the current dialog model: they may satisfy a goal, modify it, or introduce another one. The results are then evaluated to find which goal makes an optimal continuation of the dialog, and the system reports these goals to the user. We are going to examine the analogies, but also the important differences, between spoken dialogs and GUIs. For instance, in the former case, the initiative is taken by the system, which has a goal to accomplish, and recursively pursues some subgoals: leaving the initiative to the user, as in GUIs, would present the risk of losing control, because of the difficulty of interpretation of free speech. Consider an example of a user request, the completion of a query to a flight database: this goal is recursively decomposed into goals of various types, such as open the dialog, seek information, seek information via spelling, check information, give information, explain behavior, force termination, and close the dialog. When a goal is active the system initiates by prompting the user, then processes the user utterance. Prompting is determined by the strategy and by the state of the dialog: for instance, the confirmation strategy may consist of a Y/N answer or of a spelling answer. The utterance is transcribed into a text by the recognizer; to increase recognition rate, the recognizer may be guided by supplying the list of words which are acceptable in this dialog state. The transcription is passed to the meaning extractor. The difficulty and uncertainty of this task for free speech exceeds the possibility of the typical user interfaces we are considering, and would require sophisticated AI techniques. More pragmatically, a careful choice of system prompts can restrict the user language and overcome the shortcomings in speech recognition. The semantic interpretation is matched against the current open goals, and determines their evolution in accordance with the strategy. For instance, after a prompt for seeking information, depending on the recognized transcript, a goal of confirmation (by Y/N or by spelling) may be activated, or a goal of behavior explanation. In essence, in this design approach, the user turn is a data-entering action, where the data-type depends on the current goal. Examples are Y/N answers, spelling of a city name, or more complex queries consisting of such as aggregate: . In fact, a user turn is the analogue of a conceptual widget. For instance, a user turn after a prompt for entering a city name can be simulated by a menu-like widget that offers the list of all cities, plus an unknown item for unrecognized names. In the same way, a user turn returning aggregate information may be simulated by multiple list menus. Thus, in substance, user turns can be modeled by a set of VEG models akin to our early login example. Each model matches a certain state of the dialog that is a certain set of active goals. After a user turn, the recognized item is assigned to a VEG semantic variable (or to an aggregate variable). Then, the dialog manager is the analogue of a VEG controller model; it activates the relevant user turn models, by sending them communication events. In order to choose the models to activate, the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
156
•
J. Berstel et al.
manager interrogates the application (typically a database server) and makes use of the dialog strategy. After utterance recognition, the user turn models are disabled. Refinements are needed to cope with uncertainty in voice recognition and meaning extraction, as well as with user misunderstanding the prompts, or supplying inconsistent, incomplete or redundant information. To simulate this behavior in VEG, we propose to return, in addition to the selected menu-like items, a confidence number which can condition the choice of the next goal. For instance, a low confidence would trigger a confirmation goal, by Y/N answer or by spelling. Moreover, to avoid dialog drifting into unproductive loops, the dialog manager may count how many times a goal has been activated. Over a threshold, the manager may move to an explanatory goal (to tell the user what information is missing or inconsistent), or force termination. In the above description, we did not discuss how dialog strategies should be incorporated into the manager. In some dialog design approaches, the strategies are encapsulated into a separate block, while in others the strategy is wired into the manager. Using VEG, both ways are possible: the manager model can interact via communication events with a separate strategy model; or the manager rules may directly implement the decision logic of the intended strategy. Comparing spoken and visual dialogs, we find the former to be less predictable and more subject to user errors. Extensive use of default rules should allow sufficient control over dialog. Semantic variables may be associated with communication events, allowing the manager to send the list of relevant words together with the enabling signal, to the user turn models. Finally, we briefly consider multimodal dialog systems, taking again an example from McGlashan. In addition to the speech and language component, the multimodal dialog system is composed of a direct manipulation interface which provides graphical information and widgets for navigation, an animated face whose speech is synchronized with the lips movement. A dialog manager is required to coordinate interpretation and generation in both modes. According to McGlashan, the manager differs from a pure voice DM in the following respects: nonspeech I/O, referencing visual objects, modality selection, navigation and filtering. Information carried by the two modalities should be interchangeable: a user may provide input via buttons and the system speak in reply; or the user may refer in speech to a visual object, for example, by saying “OK, print them all”. The last case must be dealt with by finding compatible accessible concepts (say a timetable) the pronoun “them” refers to. This requires rather well-established linguistic techniques. Often, interaction may require fusion of different modalities (e.g., by saying “OK, print these” and then selecting the desired objects with a few mouse clicks), as in systems first introduced in Bolt [1980] and studied more recently by Nigay and Coutaz [1995]. Limiting our consideration to the use of VEG, we do not see any special difficulty arising from multimodality, but rather the contrary. The VEG approach is suitable to multimodal dialogs by the central assumption of independence of the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
157
layout of the visual interface. For instance, modality selection in system turns is dictated by the characteristics of the output information, and the expressiveness and efficiency of the alternative modalities for realizing it. Sometimes both modalities are enabled, for example to present a travel schedule by voice and by a displayed table. Modality selection criteria and fusion can be wired in the dialog manager (or encapsulated into a separate building block). In conclusion, the VEG approach, although originally not intended for voice or multimodal interaction, appears to be suitable to specify these modalities. Model checking or other formal methods have apparently never been considered for early validation of dialog managers, while they may provide a great potential contribution. A difficulty we anticipate is that our model-checking approach does not consider the semantic variables in the state space to be explored, while most spoken dialogue interfaces make essential use of them (city names, flight identifier, etc.) A solution is partitioning the semantic space into a finite set of cases, corresponding to the dialogue acts and goals: opening, seek information, confirmation, explanation, etc. This would allow the model checker to explore a significant but not overwhelming state space. 8. RELATED WORKS There are of course many formal notations, other than grammars, which have been widely applied to GUI specification design, at least in academic research. Among those formal methods that have been explicitly tailored towards GUI applications, we recall the cited [Bastide and Palanque 1995; Brun 1997; Patern`o and Faconti 1992], which have allowed the implementation of successful design toolkits. However, they have the disadvantage that the modeling power of their notation is typically not finite-state, making them harder to verify than VEG. Up to now, GUI validation and verification (V&V) has been addressed mainly by applying testing techniques. A recent example is in Memon et al. [2000], where test cases are generated and then checked with a test oracle. Formal verification methods such as theorem proving and model checking have already been applied to interactive system verification (see, e.g., the review of Campos and Harrison [1997]). For instance, HOL, a higher order logic theorem prover, has been used by Bumbulis et al. [1996] to verify user interface specifications. Because of the equivalent expressiveness of the formalism used in the analysis and of the specification language, properties may be studied on the original specification rather than on its approximation. However, theorem proving usually requires complex user interaction to derive the proof, which may be overkill for many properties that could be checked automatically by model checkers. Theorem provers are more adequate when the verification process cannot be automated, as for instance the verification of a user interface specification against its perception by the users [Doherty et al. 2000]. Model checking has also been applied for V&V of GUI, for example, by Dwyer et al. [1997], where an existing GUI is abstracted into a finite state version that can be checked with Symbolic Model Verifier (SMV) of Clarke et al. [1986]. In Abowd et al. [1995], user interfaces are specified using Action Simulator, a language to specify simple finite state machines, and then translated into the ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
158
•
J. Berstel et al.
SMV input language, in order to be checked against some Computational Tree Logic (CTL) formulas. The main drawback of this work is the poor expressive power and extensibility of Action Simulator, since only very small systems can be modeled with this tool. On the other hand, simplicity may also be an advantage in certain cases and some kind of interface simulation is possible. Several other works using model checking to verify user interfaces use the powerful notion Interactor [Faconti and Patern`o 1990; Duke and Harison 1993] as the structuring concept of the specification. An Interactor is a component that encapsulates a state, interacts with its environment through events and is capable of rendering its state into some presentation medium. In Patern`o [1995], interactors are specified using Lotos. For verification, the specification is translated into a finite state machine and then analyzed using Action-based Temporal Logic (ACTL). In d’Ausbourg et al. [1996], interactors are directly extracted from the GUI and modeled in the synchronous language Lustre, which is also used to verify properties. The first difference of these two approaches with VEG is that they base verification on events, rather than on states, making expressing of invariants harder. The work of Patern`o [1995] does not propose an executable version of the specification. This is not the case of d’Ausbourg et al. [1996], but the expressive power of the resulting specification appears to be poor (only the Boolean data type is available for communication) and no code generation support is provided. Campos and Harrison [2001] propose to introduce verification with SMV at the early stages of the specification. As in Patern`o [1995], they use interactors to structure their specification but they limit the specification to the parts of the system required by the property to be verified. This minimizes the number of states to explore, and permits verification of internal parts of the system together with its interface, but it forbids executability of the specification since only a small part of the application is specified. In general, these approaches (test oracles, theorem provers or model checkers) have the advantage of being applicable to any GUI (programmed in any language), but they need to build an explicit high-level model of the system: the abstraction to be applied is application-dependent and there is no guarantee of the significance of the verification results. In VEG, we already have a high-level model of the system: the model checker verifies exactly the same specification that will be implemented, giving greater confidence in the analysis. Moreover, the model checker may be applied as a debugging tool to verify and validate a GUI before its implementation takes place, rather than only checking it afterwards. Finally, it is a clear that a certain amount of testing of the GUI is always necessary, even after formal verification: in principle, the model checker could also be used to generate test cases (and test oracles) as well Gargantini and Heitmeyer [1999]. VEG shares these advantages of allowing formal verification and automatic code generation with various formal methods, such as the already cited Statecharts and many others. The language Esterel [Berry and Cosserat 1984], in particular, appears suitable for the specification, verification and implementation of human–computer interfaces (e.g., in Fekete et al. [1998]). Esterel, however, is a general-purpose language, certainly much richer than VEG, but it is not specialized for GUI development. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
159
Another aspect of VEG is that the specification is layout-independent, that is, the first version of a GUI can be written without worrying about the layout, and then different layouts can be adopted. For instance, this approach is similar to Ball et al. [2000], where interactive services using more media than one channel are considered (e.g., automated teller machine, bank by phone or web-based interfaces). The key principle is that all user interfaces share the same service logic (Sisl: Several Interface Single Logic). The logic is specified in an event-based model with a constraint-based language using reactive constraint graph described in XML and translated into Java. The constraint graph may be translated into state machines for automatic test case generation. VEG shares many features with the Fudget toolkit of Carlsson and Hallgren [1998]. Fudget is a declarative-style, high-level notation, based on a functional programming language, supporting hierarchical design, layout-independence, concurrent programming, extensibility and state encapsulation. These advantages are also present in the VEG toolkit, which in a sense is also based on a functional notation (attribute grammars), but Fudget gives a more limited support to verification and validation. Software Model Checking (e.g., the Bandera tool of Corbett et al. [2000]) is now an important research subject. The main issues in the field are identifying safe abstractions (i.e., an abstraction where all the violation of the desired properties of a given program can always be found on the abstracted version) and eliminating spurious counterexamples (counterexamples for the abstraction only, corresponding to infeasible paths). In VEG, we already have a safe abstraction that is less subject to the problem of spurious counterexamples, at least for event-driven specifications. The semantic part (the Java code) of a specification is however ignored by our analysis, assuming that other techniques, such as traditional testing, are adopted. An interesting approach would be the integration of software model checking, for the semantic parts, into the VEG techniques. 9. CONCLUSIONS AND FUTURE WORK In this article, we have shown how to apply grammars to the specification, design, verification and implementation of GUI. Dialogs are specified by means of modular, communicating grammars called VEG (Visual Event Grammars). A VEG specification is independent of the actual layout of the GUI, but it can be easily integrated with various layout design toolkits. Moreover, a VEG specification may be verified with the model-checker SPIN, in order to test its consistency and correctness, to detect deadlocks and unreachable states, and also to generate test cases for validation purposes. Since GUIs are usually event-driven, control-intensive, rather than data-intensive, applications, model checking techniques can be very effective. Efficient code is automatically generated by the VEG toolkit, based on compiler technology. Realistic applications have been specified, verified and implemented, like a Notepad-style editor, a graph construction library and a large real application to medical software. One of the major advantages of the VEG approach is the possibility of the interaction of development and step-by-step verification: the “push-button” ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
160
•
J. Berstel et al.
model-checking facility of our toolkit allows continuous testing of the system under development, also very early in the design phase. Moreover, since many aspects of behavior may be easily described using VEG and combined with the layout long before coding semantic actions, VEG may give strong support to rapid prototyping: a user may be shown not only a traditional GUI mock-up, but rather a working GUI that may include most behavioral aspects. Our examples emphasized WIMP interaction style, with only some discussion on other input styles, such as voice interaction [Bolt 1980] or multimodal dialogs, in Section 7. This should not be considered as a limitation but only as a convenient simplification for exposition. More input styles such as virtual reality [Foley 1987] can be modeled in our framework as long as the “numerical” part of the events is considered in the semantics of the model as this already holds in the WIMP model. As an example, the insertion of values with a slider may be decomposed into a syntactic sequence of input events of the type press-dragrelease, and a sequence of the actual slider values associated with the events. The syntactic sequence may be modeled by state transitions, but the slider values must be passed as arguments to semantic functions. A 3D input widget like an arcball [Shoemake 1992], is quite similar to a slider. The dragging process results in a sequence of input events containing the geometric position (a pair of numbers) of the pointer in its semantic attributes. Our model does not manage this numerical information in the syntactic part, and thus could not be used in a verification process. Anyway, this information is unbounded by nature and so it would makes verification much harder. It is a challenging problem to design a extension of our model that takes into account, at the syntactic level, changes in numerical values in a satisfactory way. Usual data structures like stacks or queues seem to be too restrictive. On the other hand, if the aim is still to use model checking tools, severe restrictions have to be imposed on the nature of numerical data as we did it already to deal with dynamic instantiation of widgets. In gesture-based interaction, the design problem is quite similar: again, numerical values associated with the events need to be handled at the semantic level. However, interface changes based on the acquired experience of the behavior of particular users, are based on thresholds, and hence they can easily be modeled by a change of state in VEG. Future work will consider the application of the method to the design of safety-critical software, in order to exploit the verification capabilities of VEG, but also to handheld devices, to exploit the one interface-many layouts capability of VEG. APPENDIX SYNTAX AND SEMANTICS OF VEG In this appendix, a description of VEG syntax and semantics is presented. A.1. VEG SYNTAX A VEG model is described by a declaration following the BNF syntax given here, where {X} means that X may be repeated zero or more times, [X] means ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
161
that X is optional and “X” stands for the terminal symbol or string X: model→
[“Package” packageName] “Model” modelName [“Axioms” axiomList] [“Group” groupList] {rule} {default Rule} “end” modelName
For each state of a model, there is exactly one rule, which is assumed to be in generalized right-linear form, informally described as follows. Let a guard be an input communication event, an input event, or a disjunction thereof, that is, (a|b|. . . ). Then: (1) the right-hand side of every rule is composed of one or more alternatives (x|y|. . . ); (2) for each alternative, there is exactly a guard in the leftmost position; and (3) for each alternative x, there is one nonterminal, called the next state, which is at the rightmost position in the alternative. The idea behind generalized right-linear rules is to make finite state verification possible for a VEG model, when semantic components are ignored. However, the current VEG toolkit is also able to deal with more general context-free rules, if model checking is not a requirement. For instance, a rule describing that in the state ready it is possible to receive either a or a and then to go back to ready again, can be written as: ready ::= \startJuggling ready | \stopJuggling ready
Formally, using a BNF syntax, a rule must have the form: rule → state “::=” ruleBody ruleBody → alternative { “|” alternative } alternative → guard conditionalRule guard → event { “|” event} event → “” | “?”communicationEvent conditionalRule → body [“if” predicate body state {“elsif” predicate body state } “else” body “fi”] state body → {outputEvent | action | launch | “if” predicate body {“elsif” predicate body } “else” body “fi”} outputEvent → “!”communicationEvent action → (semanticAction| visualAction | [variable “=”] semanticFunction) “(” variableList “)” variableList → ε | variable {“,” variable} launch → “launch” “(” launchList “)” launchList → [variable “=”] modelName[“.”axiom] [“,” launchList] predicate → semanticPredicate “(” variableList “)” defaultRule → DEFAULT “::=” [“?” conditionRule] | ruleBody
The formal description also details the if · · · else · · · fi construct, to be used in connection to semantic predicates. Notice that an else part must always be present. The lexical classes state, inputEvent, communicationEvent, semanticAction, visualAction, variable, semanticFunction, modelName, axiom ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
162
•
J. Berstel et al.
and semanticPredicate are not further detailed here. The textual convention introduced in Sections 2 and 3, where, for instance, input events are denoted in brackets, semantic actions start with a slash, etc., is not used in the graphical editor, where different classes are distinguished by their graphical appearance. Already-mentioned default productions play the role of triggers with respect to input or communication events that are not in the lookahead set. Default rules always have the lowest priority. They have the same syntax of other productions, but the symbol ‘?’ may occur as a guard to stand for all “unexpected” events. Also, the special state return may be used in default rules, with the effect that the control is returned to the state where the object was when the default rule was triggered. For example, a rule of type: DEFAULT ::= ? return may be present in a model to make it ignore all unexpected communication events. The lookahead set of a rule is the set of its guards. The complete lookahead set of a state for a model is the lookahead set of the rule corresponding to the state plus the set of guards of the default productions of the model. When there is a default rule with “?” as its left part, the complete lookahead set is the set of all input and communication events. A.2. SEMANTICS OF VEG We describe here an operational semantics of VEG applications. A VEG application is composed of various VEG objects, that is, instances of models. Each VEG object, during its lifetime, has a current local state, and has a unique object identifier, called its reference. The application has one unbounded event queue where communication events are stored. Each element of the queue is a triple , where sender is a reference to the object that generated the event, target is the intended target (i.e., one or more object references or the special keyword any to denote any target) and event is the event name. There is also a channel for input events, which are not buffered. Each input event is associated with one (and only one) object reference, again called its target. The channel is assumed to be empty whenever the event queue is not empty, that is, the communication events have priority over input events, which cannot be “detected” until the queue becomes empty. The current event is the input event in the channel if the event queue is empty, otherwise it is the communication event at the head of the queue. In every instant, one object at most is active. All objects that are not active are either suspended or deadlocked. A suspended object may become active only when it is in the target of an event that is in the complete lookahead set of its current state. If there is more than one suspended object that may become active, then exactly one becomes actually active, following a nondeterministic choice. A suspended object becomes deadlocked whenever it is in the target of an event that is not in the complete lookahead set of its current state. A.2.1 Execution of an Active Object When an object becomes active, it is executed as follows: if the current event is in the lookahead set, the corresponding rule is executed; otherwise the default ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
163
production enabled by the current event is executed. When rule execution begins, the current event is consumed (either from the input channel or from the event queue) and the corresponding alternative of the rule is executed. When the alternative is executed, the corresponding visual and semantic actions are performed, new objects may be created, semantic predicates are tested, and communication events are written into the event queue, following the left-toright order of the rule. When the rule is completed, the object’s current state becomes the new state specified by the rule, and the object is suspended. The object terminates its execution when entering the special quit state. The behavior of objects may be more formally described by the following scheduling policy: Scheduling Policy of VEG objects: while (some VEG object in the application is alive) { Pick current event E; if (no alive object is in the target of E) DEADLOCK; for each object O in the target of E if (E is not in the complete lookahead set of O) DEADLOCK; let O be one object in the target of E Consume E and send it to O; Make O the active object; Wait until O is suspended or terminates; }
A global state (or configuration) of a VEG application is the set of VEG objects that are alive in the application, each with its current state, plus the content of the event queue and a reference to the active object (if any). A configuration is stable if the communication queue is empty and all objects are suspended. A configuration is called a deadlock whenever one of its VEG objects is deadlocked. Notice that when one object is deadlocked, the event queue is not empty and no object can be made active. A.3. ATTRIBUTE GRAMMAR ASPECTS VEG adopts an L-attributed approach for attribute computation. L-attributed grammars are a class of attribute grammars allowing only left-to-right attribute dependencies in rules, enabling the integration of attribute evaluation with LL(k) parsers. In order to avoid clashes with object-oriented terminology, “attributes” in VEG are called semantic variables and the traditional terminology “inherited/synthesized” of compiler jargon is replaced by right/left. A right variable corresponds to a parameter passed to a function, while a left variable is a result returned by a function. For instance, in the example of Section 3.1, the following fragment of a VEG rule is present: login ::= /login.n = increment(login.n); . . .
the leftmost occurrence of login.n is a left variable, while the rightmost occurrence login.n is a right variable; both variables are associated with the state login. The definitions of the semantic variables and of the methods operating on them are separately provided in a Semantic Library, to be written by VEG users ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
164
•
J. Berstel et al.
or to be reused from existing libraries. A VEG grammar specifies the names of the semantic variables and of the functions, and their functional dependencies. All symbols can be associated with (left or right) semantic variables: nonterminals, input events, visible and semantic actions, semantic predicates, communication events. The following restrictions are however imposed, to make computation of variables realistic: — The domain (or class) of a semantic variable is the same for all symbols carrying that variable. — When a model may have a visual counterpart, then the first right variable associated with each axiom must represent the reference to a visual object. The semantic variables of an axiom are right values for the symbols exported by the current module and left values for the symbols imported by the module. — No right semantic variables are allowed for input events. — Only one left semantic variable is allowed for a semantic predicate, and its domain is Boolean. ACKNOWLEDGMENTS
The VEG notation and toolkit is the result of an Esprit Long-term research project, called Gedisac, started in 1998 and completed at the beginning of 2000. Special thanks to Marco Pelucchi, who developed the VEG toolkit and various prototypes, first as a graduate student and later while working at Txt e-solutions. We gratefully acknowledge the contributions of many people to the development of the VEG ideas and toolkit. Among them, Alberta Bertin, Txt esolutions; Fabien Lelaquais, Marie Georges and Christian de Sainte-Marie, Ilog; and Alessandro Campi, Politecnico di Milano. We also thank the project reviewers Gorel Hedin, Lund Institute of Technology; Ian Sommerville, Lancaster University; and project officers Pierrick Fillon and Michel Lacroix, for their many useful suggestions. Many thanks to Eliseo Martinez who has developed the new version of the VEG Visual Editor and provided Figure 4 and to Emanuele Mattaboni for developing the Visual Platform Editor. We also thank the anonymous reviewers of an earlier version of this article for their constructive feedback and many suggestions to improve the manuscript. REFERENCES ABOWD, G. D., WANG, H.-M., AND MONK, A. F. 1995. A formal technique for automated dialogue development. In Proceedings of the First Symposium of Designing Interactive Systems (DIS’95), (Aug.), ACM, New York, 219–226. ANTLR Web Site: Complete Language Translation Solutions, http://www.antlr.org. BALL, T. AND RAJAMANI, S. K. 2001. The SLAM Toolkit. In Proceedings of the 13th Conference on Computer-Aided Verification (CAV2001) (Paris, France, July 18–23). Lecture Notes in Computer Science, vol. 2102. Springer-Verlag, New York, 260–264. BALL, T., COLBY, C., DANIELSEN, P., JAGADEESAN, L., JAGADEESAN, R., LAUFER, K., MATAGA, P., AND REHOR, K. 2000. SISL: Several interfaces, single logic. Internat. J. Speech Tech. 3, 2, 93–108. BASTIDE, R. AND PALANQUE, P. 1995. A Petri net based environment for the design of event-driven interfaces. In 16th Int. Conference on Application and Theory of Petri Nets (ATPN’95) (Torino, Italy, 20–22). June 1995. G., De Michelis and M., Diaz, Eds. Lecture Notes in Computer Science, vol. 935. Springer-Verlag, New York, 66–83. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
165
BERRY, G. AND COSSERAT, L. 1984. The ESTEREL synchronous programming language and its mathematical semantics. In Seminar on Concurrency, A. W., Roscoe, G., Winskel, and S. D., Brookes, Eds. Lecture Notes in Computer Science, vol. 197, Springer-Verlag, New York, 389–448. BERSTEL, J. 1979. Rational Transductions and Context-Free Languages. B. G. Teubner, Stuttgart. BERSTEL, J., CRESPI REGHIZZI, S., ROUSSEL, G., AND SAN PIETRO, P. 2001. A scalable formal method for design and automatic checking of user interfaces. In Proceedings of the 23rd International Conference on Software Engineering (ICSE 2001) (Toronto, Ont. Canada, May 12–19). IEEE, New York, 453–462. BOLT, R. A. 1980. Put-that-there: Voice and gesture at the graphics interface. ACM Comput. Graph. 14, 3, 262–270. BRUN, P. 1997. XTL: A temporal logic for the formal development of interactive systems. In Formal Methods In Human-Computer Interaction. P., Palanque and F., Patern`o, Eds. SpringerVerlag, New York, 121–139. BUMBULIS, P., ALENCAR, P. S. C., COWAN, D. D., AND LUCENAN, C. J. P. 1996. Validating properties of component-based graphical user interfaces. In Proceedings of 3rd Eurographics Workshop on Design. Specification and Verification of Interactive Systems. F., Bodart and J., Vanderdonckt, Eds. Springer-Verlag, New York, 347–365. CAMPI, A. 2000. Design and verification of GUIs by syntactical methods (in italian). Master Thesis, Politecnico di Milano, Italy, Dec. 2000. CAMPOS, J. C. AND HARRISON, M. D. 1997. Formally verifying interactive systems: A review. In Proceedings of 4th Eurographics Workshop on Design, Specification and Verification of Interactive Systems, June 1997, M. D., Harrison and J. C., Torres, Eds., Springer-Verlag, New York, 109–124. CAMPOS, J. C. AND HARRISON, M. D. 2001. Model checking interactor specifications. Automat. Softw. Eng. 8, 3-4 (Aug.), 275–310. CARLSSON M. AND HALLGREN T. 1998. Fudgets—Purely functional processes with applications to graphical user interfaces, Ph.D. dissertation. Computing Science Department, Chalmers University of Technology and University of G¨oteborg. March 1998. CHURCHER, G. E., ATWELL, E. S., AND SOUTER, C. 1997. Dialogue management systems: A survey and overview. Report 97.06, University of Leeds, School of Computer Studies, Leeds, UK. CLARKE, E. M., EMERSON, A., AND SISTLA, A. P. 1986. Automatic verification of finite-state concurrent systems using temporal logic specifications. ACM TOPLAS 8, 2, 244–263. CLARKE, E. M., GRUMBERG, O., AND LONG, D. E. 1994. Model checking and abstraction. ACM TOPLAS 16, 5 (Sept.), 1512–1542 . COLE, R., MARIANI, J., USZKOREIT, H., VARILE, G. B., ZAENEN, A., ZAMPOLLI, A., AND ZUE, V. 1996. Survey of the State of the art in Human Language Technology. Cambridge University Press. CORBETT, J., DWYER, M., HATCLIFF, J., PASAREANU, C., LAUBACH, S., AND ZHENG, H. 2000. Bandera: Extracting finite-state models from java source code. In Proceedings of the 22nd International Conference on Software Engineering (ICSE 2000). (Limerick, Ireland, June 4–11). 439–448. D’AUSBOURG, B., DURRIEU, G., AND ROCHE, P. 1996. Deriving a formal model of an interactive system from its UIL description in order to verify and to test its behaviour. In Proceedings of the 3rd Eurographics Workshop on Design Specification and Verification of Interactive Systems (Namur, Belgium., June 5–7). F., Bodart and J. , Vanderdonckt, Eds. Springer-Verlag, New York, 105–122. DOHERTY, G., CAMPOS, J. C., AND HARRISON, M. 2000. Representational reasoning and verifications. Form. Asp. Comput. 12, 4, 260–277. DUKE, D. J. AND HARRISON, M. D. 1993. Abstract interaction objects. In Proceedings of EUROGRAPHICS 93. R. J., Hubbold and R., Juan, Eds. Computer Graphics Forum, 12, 3, 26–36. DWYER, M. B., CARR, V., AND HINES, L. 1997. Model checking graphical user interfaces using abstractions. In Proceedings of the 6th European Software Engineering Conference. 244–261. FACONTI, G. AND PATERNO` , F. 1990. An approach to the formal specification of the components of an interaction. In Proceedings of EUROGRAPHICS 90, C., Vandoni and D., Duce, Eds. 481–494. FEKETE, J. D., RICHARD, M., AND DRAGICEVIC, P. 1998. Specification and verification of interactors: A tour of esterel. Presented in Formal Aspects of Human Computer Interaction Workshop (FAHCI’98) (Sept.), Sheffield Hallam University, Sheffield, U.K. FOLEY, J. D. 1987. Interfaces for Advanced Computing, Sci. Amer. 257, 4, 127–135. FOLEY, J. D., KIM, W. C., KOVACEVIC, S., AND MURRAY, K. 1989. Defining interfaces at a high level of abstraction. IEEE Softw. 6, 1, 25–32. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
166
•
J. Berstel et al.
GARGANTINI, A. AND HEITMEYER, C. 1999. Using model checking to generate tests from requirements specifications. In Proceedings of the Joint 7th European Software Engineering Conference and 7th ACM SIGSOFT Information Symposium on Foundations of Software Eng. (ESEC/ FSE ’99) (Toulouse, France, Sept.). Lecture Notes in Computer Science, vol. 1687, SpringerVerlag, New York, 146–162. GODEFROID, L., JAGADEESAN, J., JAGADEESAN, R., AND LAUFER, K. 2000. Automated systematic testing for constraint-based interactive services. In Proceedings of the 8th International Symposium on the Foundations of Software Engineering (FSE’2000) (San Diego, Nov.). 40–49. GRAY, W. D., PALANQUE, P., AND PATERNO´ , F. 1999. Introduction to the special issue on interface issues and designs for safety-critical interactive systems: when there is no room for user error. ACM Trans. Comput.-Human. Inter. 6, 4, 309–310. GREEN, M., 1983. Report on dialogue specification tools. In Proceedings of the Workshop on User Interface Management Systems (Seeheim, Germany, Nov. 1–3). G. E., Pfaff, Ed. Springer-Verlag, New York. HAREL, D. 1987. Statecharts: A visual formalism for complex systems. Sci. Comp. Progr. 8, 231– 274. HARTSON, H. R. AND HIX, D. 1989. Human-computer interface development: Concepts and systems for its management. ACM Comput. Surv. 21, 1, 5–92. HENDRICKSEN, C. S. 1989. Augmented state-transition diagrams for reactive software. ACM SIGSOFT Software Engineering Notes 14, 6, 61–67. HILL, R. D. 1986. Supporting concurrency, communication and synchronization in humancomputer interaction—the sassafras UIMS. ACM Trans. Graph. 5, 3, 179–210. HOLZMANN, G. J. 1997. The model checker SPIN. IEEE Trans. Softw. Eng. 23, 5, 279–295. JACOB, R. J. K. 1982. Using formal specifications in the design of a human-computer interface. In Proceedings of the 1982 Conference on Human Factors in Computer Systems (Gaithersburg, Md.) ACM, New York, 315–321. KATAYAMA, T. 1984. Translation of attribute grammars into procedures. ACM Trans. Prog. Lang. Syst. 6, 3, 345–369. KNUTH, D. E. 1968. Semantics of context-free languages. Math. Syst. Theory 2, 2, 127–145. (Correction in 1971: Math. Syst. Theory, 5, 1, 95–96). LARSON, J. A. 2003. VoiceXML: Introduction to Developing Speech Applications, Prentice-Hall, Englewood Cliffs, N.J. MCGLASHAN, S. 1996. Towards multimodal dialogue management. In Proceedings of 11th Twente Workshop on Language Technology 11. Enschede, The Netherlands. MEMON, A., POLLACK, M., AND SOFFA, M. L. 2000. Automated test oracles for GUIs. In Proceedings of the 8th International Symposium on the Foundations of Software Engineering (FSE 2000) (San Diego, Calif., Nov. 6–10). 30–39. NIGAY, L. AND COUTAZ, J. 1995. A generic platform for addressing the multimodal challenge. In Proceedings of the SIGCHI Conference on Human Factors in Computing Systems (Denver, Colo.). ACM Press, New York, 98–105. NORRIS, I. P. C. AND DILL, D. 1996. Better verification through symmetry. Form. Meth. Syst. Des. 9, 1/2, 41–75. NYMEYER, A. 1995. A grammatical specification of human-computer dialog. Comput. Lang. 21, 1, 1–16. OLSEN, D. R. JR. 1983. Presentational, Syntactic and Semantic Components of Interactive Dialogue Specifications. In Proceedings of the Workshop on User Interface Management Systems (Seeheim, Germany, Nov. 1–3), G. E., Pfaff, Ed. Springer-Verlag, New York, 1985. OLSEN, D. R. JR. 1984. Pushdown automata for user interface management. ACM Trans. Graph. 3, 3, 177–203. PALANQUE, P. AND PATERNO` , F., EDS. 1997. Formal Methods In Human-Computer Interaction, Springer-Verlag, New York. PATERNO` , F. AND FACONTI, G. 1992. On the use of LOTOS to describe graphical interaction. In People and Computers VII: Proceedings of the HCI’92 Conference Cambridge University Press, 155–173. PATERNO` , F. 1995. A method for formal specification and verification of interactive systems Ph.D. dissertation. Department of Computer Science, University of York. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Design and Automatic Checking Method for User Interfaces
•
167
PETERSON, J. L. 1981. Petri Net Theory and the Modelling of Systems, Prentice-Hall, Englewood Cliffs N.J. REISNER, P. 1981. Formal grammar and human factor design of an interactive graphics system. IEEE Trans. Softw. Eng. 7, 2, 229–240. SHNEIDERMANN, B. 1982. Multiparty grammars and related features for defining interactive systems. IEEE Trans. Syst. Man Cyber. 12, 2, 148–154. SHNEIDERMANN, B. 1997. Designing the User Interface: Strategies for Effective Human-Computer Interaction, 3rd edition (July), Addison-Wesley, Reading, Mass. SHOEMAKE, K. 1992. ARCBALL: A user interface for specifying three-dimensional orientation using a mouse. In Proceedings of Graphics Interface ’92 Canadian Annual Conference, 151–156. VAN DEN BOSS, J. 1988. Abstract interaction tool: A language for user-interface management systems. ACM Trans. Prog. Lang. Syst. 10, 215–247. Received January 2002; revised June 2002 and December 2003; accepted October 2004
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation MARTIN ERWIG and ZHE FU Oregon State University
We present a program-generation approach to address a software-reuse challenge in the area of scientific computing. More specifically, we describe the design of a program generator for the specification of subroutines that can be generic in the dimensions of arrays, parameter lists, and called subroutines. We describe the application of that approach to a real-world problem in scientific computing which requires the generic description of inverse ocean modeling tools. In addition to a compiler that can transform generic specifications into efficient Fortran code for models, we have also developed a type system that can identify possible errors already in the specifications. This type system is important for the acceptance of the program generator among scientists because it prevents a large class of errors in the generated code. Categories and Subject Descriptors: D.2.13 [Software Engineering]: Reusable Software; D.1.2 [Programming Techniques]: Automatic Programming General Terms: Languages Additional Key Words and Phrases: Software reuse, program generator, ocean science, inverse modeling, Fortran, Haskell, type system
1. INTRODUCTION This article describes the successful application of a program-generation approach to enable the reuse of software in an area of scientific computing. The motivating example for the reported research is a software project in ocean science, the Inverse Ocean Modeling (IOM) system [Chua and Bennett 2001; IOM], which requires the adaptation of inversion programs to different ocean models. Inversion programs are needed to obtain important feedback about the quality of, in particular, ocean models, and more generally, models from other scientific disciplines. One inversion program typically consists of several tools which are implemented by subroutines and which work together with code implementing This work was supported by the National Science Foundation under the ITR/AP Grant OCE0121542. Authors’ address: School of Electrical Engineering and Computer Science, Oregon State University, Corvallis, OR 97331; email: {erwig,fuzh}@eecs.oregonstate.edu. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or direct commercial advantage and that copies show this notice on the first page or initial screen of a display along with the full citation. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, to redistribute to lists, or to use any component of this work in other works requires prior specific permission and/or a fee. Permissions may be requested from Publications Dept., ACM, Inc., 1515 Broadway, New York, NY 10036 USA, fax: +1 (212) 869-0481, or [email protected]. C 2005 ACM 1049-331X/05/0400-0168 $5.00 ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005, Pages 168–198.
Software Reuse for Scientific Computing Through Program Generation
•
169
the ocean model. Different inversion programs can be obtained by selecting different sets of inversion tools. A problem in this particular software project is that the same inversion algorithms and tools have to be (re)implemented for different ocean models because different models use different data structures to represent the ocean state, and the inversion tools have to work on these data structures and interact with a code that already exists for the ocean models. Scientific models to predict the behavior of ecological systems are routinely transformed by scientists from a mathematical description into simulation programs. Since these simulation programs have to deal with huge data sets (up to terabytes of data), they are often implemented in a way that exploits the given computing resources as efficiently as possible. In addition to implementation strategies that try to make the best use of parallel computer architectures, the representation of the data in the simulation programs is highly specialized for each model. Alas, this high degree of specialization causes significant software engineering problems that impact the ability of scientists to evaluate and compare their models. One particular problem is that inversion programs currently have to be rewritten for each individual forecasting model even though the process of inversion is principally the same for all models (at least for one chosen inversion algorithm). In particular, the software project poses the following challenges. (1) Tools should be implemented or specified only once. (2) Tool specifications should be readily usable, that is, scientists should not be required to modify the inversion tools. (3) Existing model code should be reusable without needing any changes. (4) The inversion programs should also work with future models. Especially the third requirement rules out an approach to develop a software infrastructure that offers components with well-defined interfaces to implement composable and reusable components. This approach is pursued by the Earth System Modeling Framework (ESMF) collaboration [ESMF]. One drawback of that approach is that scientists have to implement their models against these newly-defined interfaces which is unfortunate because scientists are forced to reimplement (large parts of) their models. Refactoring a collection of Fortran programs (in many cases consisting of hundreds of files and tens of thousands of lines of code) is a time-consuming and error-prone task that many scientists are just not willing to perform. Instead, they seem to prefer reimplementing inversion tools specifically targeted for their model. The approach we have taken is driven by the goal to leave existing model code basically unchanged. To this end, we capture the specifics of each model by a collection of parameters that are sufficient to guide the adaptation of the inversion tools to that particular model. We have developed a language called Forge (an acronym for Fortran generator) which allows the specification of Fortran subroutines in a generic way that fixes the general structure of the subroutine but may leave open some details such as the dimensions of arrays, the number of nested levels of loops, or parameters of the subroutine. By using model parameters in these specifications, the dependency of the corresponding ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
170
•
M. Erwig and Z. Fu
program parts on the ocean-model specifics can be expressed. Given a concrete set of values for the parameters, a Fortran program can be generated from the Forge specification. We have employed this language for specifying inverse ocean modeling tools. Moreover, we have developed a graphical user interface that allows scientists to create complete inversions. Our approach can be understood as a program generator that facilitates program reuse on different levels. First of all, existing model code can be reused in different kinds of inversion programs. Second, inversion tools that are defined in Forge can be reused for inversions of different ocean models which is achieved by compiling them into Fortran code depending on a set of parameters that describe the particular ocean model. Finally, the graphical user interface allows users to select different inversion outputs which triggers the generation of the required inversion tools and, in particular, the creation of a Fortran inversion program that computes the requested inversion outputs. Although the program generator was specifically designed to be used with inversions for ocean modeling, the scope and applicability of the results reported in this article are much larger. Inversion includes medical imaging, seismic exploration, retrieval of atmospheric profiles from satellite soundings, assimilation of initial data into operational weather forecast, and, in our example application, the testing of hypotheses about the dynamics of ocean circulation. Inversion differs in its objectives from, but is mathematically identical to, the engineering activity of optimal control of dynamical systems. We believe that the emphasis that we have placed on software reuse in our approach is essential for its success. In fact, we have combined what has been called generative reuse with compositional reuse [Mili et al. 2002] in the following way. First of all, the code of each ocean model is completely reused. No adaptation is needed. The ocean model code is composed with inversion tools to create inversion programs which is, therefore, an example of compositional reuse. Second, the reuse of inversion tools is realized through the program generator, that is, the tools are described only once and are translated into Fortran programs according to the parameters that are defined for the current ocean model which is, therefore, an example of generative reuse. Third, the inversion programs that are individually generated for particular selected inversion output are also examples for generative reuse. In the remainder of this Introduction, we briefly describe the background of the application area and the program-generator approach. In Section 2, we present how to generate Fortran code for IOM tools through two examples. We will describe how the type system will prevent type errors in the generated Fortran programs in Section 3. In Section 4, we discuss related work, and conclusions, given in Section 5, complete this article. In the appendices, we provide the complete syntax of Forge, the formal rules of the type system, and a complete example of a generated subroutine. 1.1 Tools for Inverse Ocean Modeling Ocean scientists are using ocean models to simulate and predict the state of oceans. Ocean models are conventionally formulated as equations of motion. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
171
The equations are solved by numerical approximation. Different ocean models use different numerical approximations. Models usually use arrays over time and space to store the state values of oceans such as velocity or temperature. Some models also consider data at fixed locations and use arrays over time only, or average over time, while other models use arrays only over space. The Inverse Ocean Modeling (IOM) system [Chua and Bennett 2001] is a data assimilation system which enables the developers of ocean models to combine their models with real observations of the ocean. The output of the IOM is a weighted least-squared best-fit to the equations of motion and to the data. The IOM consists of tools that are used for solving the equations of best fit. The information obtained by inversion programs gives important information about the quality of data produced by ocean and weather forecasting models. The accuracy of forecasting models is important for the successful planning of flight or ship routes, navy operations, and many other applications. In addition, inversion can also reveal important information about the efficiency of the observation process. Since every ocean model uses its own data structure to describe the ocean, it is very difficult for the developers of the IOM to write a system that can work for different ocean models, although the algorithms for inverse ocean modeling are the same for all models. The problem is that the genericity that is inherent in the problem cannot be expressed by Fortran. For example, we cannot declare an array variable to have a varying number of dimensions. Moreover, we cannot add a varying number of loops over a block of statements or express array indexing for a variable number of dimensions. Similarly, we cannot define subroutines with a variable number of parameters or pass subroutines as parameters to other Fortran subroutines. Although some of these language features are available in other programming languages, for example, function pointers in C, or higher-order functions in Haskell [Peyton Jones 2003], or dimensionindependent array functions in APL [Iverson 1984] or J [Iverson 1995], no single language provides all the required features. Moreover, since most of the existing ocean-model code is written in Fortran, we have to work with Fortran as a language, at least on the model side. 1.2 A Program Generator for Inverse Ocean Modeling Tools Our solution is the design and implementation of a specification language, Forge, that can be used to generate the tools provided by the IOM. Tool descriptions are parameterized by variables that capture aspects that are specific to individual ocean models. Values for these parameters have to be provided by each model for which a tool is to be created. A program generator creates Fortran code that implements a tool for any specific ocean model. The program generator is basically a compiler whose source language is Forge and whose target language is Fortran. Individual tools are combined into larger inversion programs. This process is controlled by a graphical user interface (GUI) that presents ocean modelers with a variety of inversion options such as the selection of inversion outputs and the choice of different inversion algorithm options. The graphical user interface also controls system configurations such ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
172
•
M. Erwig and Z. Fu
Fig. 1. Graphical user interface (GUI).
as Makefile and Fortran compiler options, the definition of model parameters, and different execution options which are particularly important for efficient parallel execution on supercomputers. Currently, the GUI can support three different execution options. The IOM module and the model module can be run as one single executable with either of them being the main module and calling the other, or the IOM module and the model module can be run as two separate executables that communicate via shared data files. We plan to support more fine-grained parallelism in future versions. The graphical user interface is implemented in Java and runs together with the Forge and Fortran compilers on Windows, Mac OS, and Solaris. A snapshot of the current system is shown in Figure 1. The ability to provide model parameters, to select a particular combination of inversion outputs, and to customize the inversion algorithm offers to ocean modelers a flexible customization of inversion programs along three dimensions. In this article, we do not discuss the combination of tools into inversion programs but rather focus on the issues concerning the specification of individual tools and the design and implementation of the program generator. Figure 2 illustrates the architecture of the system. The developers of the IOM system (this is the group of people developing inversion tools) define tool specifications which are written in Forge to describe the tools that the IOM provides. The tool specifications can use library functions which are mainly basic Fortran program transformers, for example, for generating loops. Library functions can also be employed to specify array index types, ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
173
Fig. 2. System architecture.
Fig. 3. Using model parameters in tools and library function calls.
see Section 2.3. The library functions are written in Haskell [Peyton Jones 2003] and are provided by computer scientists who develop these functions in close collaboration with the ocean-modeling software developers who need them. A Fortran subroutine is generated for each tool specification. The generation of Fortran code depends on a model specification that contains the information that is specific to a particular ocean model such as the dimensions of the array that is used to store the state values of the ocean. These model specifications are written by the users of the IOM tools, the ocean-model developers, who only have to understand the parameters they define and do not otherwise have to be concerned about the implementation of tools and the specification language Forge. Model specifications are essentially (name,value) pairs. However, the “values” can be complex entities such as Fortran subroutines. The Forge compiler takes a tool specification, a model specification, and library function definitions as its inputs and produces a Fortran subroutine. These generated subroutines, which correspond to the inversion tools, will be part of the inversion programs that are composed by the graphical user interface. Figure 3 shows a schematic instance of Figure 2 to illustrate how the components of the Forge system interact. In the example shown, the tool specification tool is parameterized by a model parameter p which is used, for example, in the body to control the effect of a library function f which is taken from an ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
174
•
M. Erwig and Z. Fu
extensible library of auxiliary program transformations. The value for p is taken from a model specification for which the Fortran program is to be generated. 1.3 The Forge Compiler For the implementation of the Forge frontend, we have used the Haskell scanner generator Alex [Dornan 1997] and the parser generator Happy [Marlow and Gill 2000]. The main part of the Forge compiler is written in Haskell [Peyton Jones 2003]. There are several advantages to using a language like Haskell to implement the compiler. First, the abstract syntax of Fortran programs is represented by a collection of Haskell data types that can represent only syntactically correct Fortran programs. Therefore, the syntax correctness of the generated Fortran programs is automatically guaranteed by the type system of Haskell. This property runs under the slogan “type-correct meta programs ensure syntax-correct object programs” which is discussed in more detail by Tim Sheard [Sheard 2001]. This syntax-correctness guarantee is not tied to the use of Haskell but can be achieved by using a corresponding representation in any strongly typed language. For example, in Java, syntactic categories can be represented as abstract classes and different grammar rules can be represented as concrete classes that extend the abstract classes and that contain corresponding constructors. Second, a Fortran program is obtained from an abstract syntax value of type T through a function show that is defined for the data type T . This approach of defining the abstract syntax of Fortran as Haskell data types and then developing a show function for them gives us the flexibility to easily generate programs written in other high-level programming languages such as C or C++. Since the abstract syntax of those languages is similar to Fortran, we simply have to re-implement the show function so that the rest of the compiler can be reused. In fact, with regard to the subset of Fortran used by the program generator, the abstract syntax can be reused almost without change for C or C++.1 Multilanguage support has not been an explicit goal of this project, but the abstract syntax representation supports it well in case this issue should become important in the future. Third, the core part of the Forge compiler consists of functions that translate equations into Fortran. Special attention has been paid to library functions that are implemented in Haskell. The translation functions need access to these library functions which are referenced through the specification to be compiled. 2. GENERATING FORTRAN FROM TOOL DESCRIPTIONS In this section, we illustrate the elements of the specification language Forge and their translation into Fortran through examples. We consider two convolution tools that are part of the IOM system and that are used in practice. Convolution tools are extremely important in the area of data simulation. Even though 1 As
anecdotal evidence, after presenting the current IOM system during the 2003 IOM Annual Conference, one participant from the Navy Research Lab Stennis asked about the possibility of using the whole system for their model NCOM which is implemented in C++. After the presentation, we were able to customize the IOM to produce C++ code in about 30 minutes. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
175
Table I. Size of Generated Forge Code Application Markovian convolution in time Bell-shaped convolution in space Combination functional Low-pass filter for image processing Low-pass filter for data simulation Array slicing
N 10 32 25 20 10 55
ℓ 13 20 44 16 16 8
360 816 1440 320 160 1154
the mathematical continuous definition for all convolutions can be captured by a single equation that is parameterized by a weighting function, the discrete forms of the convolution tools, which have to be used in practical systems, differ considerably. Since there is no algorithm known that could automatically transform arbitrary convolutions into efficiently implementable discrete forms, this process still has to be performed by scientists. Therefore, the input to a program generator cannot be the single continuous convolution equation, but has to be instead the mathematically derived set of discrete equations. Since these sets of discrete equations differ very much for different convolutions, a language like Forge is useful in describing each of them in a generic form that can be translated into Fortran programs based on model parameter values. Even though convolution tools are very important, Forge is not limited to the definition of convolution tools. There are dozens of different types of tools in the IOM system, for example, tools to check the consistency of models, or tools to perform transformations from the data space to the IOM space. Each must be rebuilt for compatibility with each user’s ocean model, according to the regular or irregular numerical grid, and this task can be automated by specifying the tools with Forge. Furthermore, since Forge provides a general mechanism for representing model-dependent implementations of discrete equations, any such set can be represented in Forge no matter what form the corresponding continuous equation has. Therefore, Forge can also be used by scientists working in other disciplines. However, Forge is not a general-purpose program generator. An essential ingredient of the covered tool descriptions are discrete equations. Therefore, tools that cannot be represented by discrete equations cannot be generated by Forge. We provide some data on the use of Forge in Table I. The main benefit of using Forge is not so much to generate one big program from one small specification, but rather to generate many different programs for different models from the same specification. In the table, we show, in the column labeled N , the number of different parameter combinations or models for that particular application. Note that N is not just the number of dimensions of involved arrays. For example, in the first example application, the Markovian convolution in time, we consider only up to four-dimensional arrays. The remaining number of models result from the different possibilities for placing the time dimension within the multi-dimensional array. Column ℓ gives the number of lines of the specification, and the last column shows the number of lines of code for all generated models. Markovian convolution in time and Bell-shaped convolution in space will be explained in detail in Sections 2.1 and ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
176
•
M. Erwig and Z. Fu
2.5, respectively. Combination functional is an IOM tool that maps a vector into an array whose shape is derived from two model parameters. Low-pass filters can be used in both image processing and data simulation for smoothing data. Array slicing can project an (n − 1)-dimensional array out of an n-dimensional array by selecting a dimension to project and a value within that dimension. 2.1 An Example Tool: Markovian Convolution in Time Convolution is essentially the process of averaging over weighted values. The basic idea is the value of one point is computed by averaging over the weighted values of its neighbors. The weights of the neighbors depend on the distances from the point. The number of convolutions is unlimited since each new weighting function defines a new convolution. Every convolution has the following form. X b(x) = F (x, x ′ )a(x ′ )dx ′ . 0
F (x, x ′ ) is the weighting function, x and x ′ can range over either time or space from 0 to X , which is an upper boundary of time or space, a is the weighted error, and b is the deweighted error. A similar kind of convolutions is also used in computer science. For example, in image processing, such convolutions are often used to reduce noises in an image [Castleman 1996]. The above formula is a continuous equation. Computer simulations are based on the corresponding discrete equations that can be derived from the continuous one. The corresponding ocean science and mathematics background can be found in Chua and Bennett [2001]. We omit the derivation here since it is not important for the translation of the discrete equations into Fortran. The Markovian convolution in time is one particular convolution tool defined by the following formula. The weighting function F (t, t ′ ) is exp(−|t − t ′ |/τ ), and the variables t and t ′ range over time between 0 and T , the upper time boundary. The coefficient τ is the correlation time scale which is input by the modelers. The smaller τ is, the more quickly the values of the old points will be forgotten. T b(t) = exp(−|t − t ′ |/τ )a(t ′ )dt ′ . 0
The corresponding discrete equations of Markovian convolution are as follows. In fact, the equations shown represent a slight generalization of the continuous formula that offers flexibility in how arrays are indexed, for example, starting at 0 or 1. Moreover, the equations also support the parallel execution of the subrroutine. With L = 0 and U = T , we obtain as a particular instance the equations that correspond exactly to the continuous formula. h L = 0. hn − hn−1 + τ −1 hn−1 = −2τ −1 an . t bU = −(τ/2)hU . bn+1 − bn − τ −1 bn+1 = hn . t ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
177
In the above equations, h is a temporary array, and L (U ) is the lower (upper) boundary of the arrays. The arrays are over time and space where different models may use different array dimensions for space. Moreover, different models represent the time dimension in different positions in array dimensions for efficiency reasons. Hence, in general, models differ in the dimensions of the manipulated arrays as well as in the interpretation of the stored data. Therefore, the IOM has to be able to create different subroutines for all the possible data structures used in all the models. Moreover, the IOM should also be able to provide tools for any new model that uses data structures in a completely new way. 2.2 Expressing Discrete Equations in Forge Each tool is defined by a Forge specification. Every specification has a name and possibly some parameters. These parameters are called model parameters since they refer to model-specific information that is used to guide the translation of the specification. The model parameters are given in the form Type::PName through the specification’s parameter list. For example, the specification for the Markovian convolution timeConv has one integer model parameter dim to represent the number of space dimensions of the underlying ocean model. The corresponding representation in Forge is as follows. timeConv(integer::dim)
The body of a specification consists of an interface, which is discussed in Section 2.3, and a definition of its function, given by a list of statements which can be assignments, subroutine calls, loops, or applications of library functions. For example, in the definition of the tool timeConv, we use a definition that is similar to the following. genLoops{dim | h[L] = 0.0}
Here genLoops is a library function that generates dim nested loops containing a Fortran statement that is derived from the equation h[L] = 0.0 and whose purpose is to assign 0 to a specific array location. Why can we not just use a Fortran statement directly here? Because the Fortran statement depends on the value of dim. For example, if dim is 0, the Fortran statement derived from h[L] = 0.0 will be simply the following. h(L) = 0.0
In this case, genLoops has no effect. In contrast, for dim=2, the derived Fortran statement (without the surrounding for loops) will be: h(L,dim1i,dim2i) = 0.0
where dim1i and dim2i are integer variables that are generated to be used as loop variables. In this case, the application of genLoops creates the following Fortran code. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
178
•
M. Erwig and Z. Fu
Fig. 4. Fortran translation of discrete equations.
do dim2i = X2, Y2, 1 do dim1i = X1, Y1, 1 h(L,dim1i,dim2i) = 0.0 end do end do
The boundary variables of the for loops are parameters that are created for the subroutine timeConv from the dependent-index declaration index space = X:Y[1:dim] which is explained in the next section. For the definition of the Markovian convolution in Forge, we have to translate each discrete equation into a Forge assignment statement and apply to the sequence of assignment statements the library function genLoops with the model parameter dim as follows. genLoops{dim | h[L] = 0.0; h[n] = h[n-1] - dt*(h[n-1]/tau + 2.0*a[n]/tau); b[U] = -0.5*h[U]/tau; b[n] = b[n+1] - dt*(h[n] + b[n+1]/tau) }
For dim = 2, the Fortran program shown in Figure 4 will be generated. In the generated program, a Fortran assignment statement is generated for each discrete equation, and a loop is generated for each dimension. The assignments that correspond to the second and fourth discrete equations are enclosed by an additional loop over the first dimension since n ranges over all values in the first dimension, whereas L and U are boundary values for the first dimension and denote single values in it. Therefore, the assignment statements for the first and third discrete equations are not placed inside of these additional loops. The parameter declaration of a tool definition provides the information that is required to distinguish equations that are translated into simple assignments ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
179
from those that are translated into loops. For example, since L and U are declared as parameters, their concrete values will be available when the subroutine is called, unlike n which has to be bound explicitly through a loop. Moreover, since L and U are used in the definition of the arrays, we know that they are constant with respect to the size of the arrays. However, since n is not used to define the arrays, n is a variable with respect to the size of every array. 2.3 Interfaces and Dependent Indices The main purpose of an interface is to declare local variables and input variables for the generated Fortran subroutine. Both kinds of variables will appear in the generated Fortran subroutine. While input variables will be translated into the parameters of the generated Fortran subroutine, local variables will be translated into declarations of local variables. In our example, dt, tau, L, U, a, and b will be input parameters of the generated Fortran subroutine, while the variables h and n are only used locally. Variable declarations also have to introduce the variables’ types. However, as we have already seen, the types of array variables might depend on model parameters. Therefore, we must be able to define such dependent types [Xi and Pfenning 1999] in Forge which is achieved through the concept of a dependent index. A dependent index is the model-dependent part of an array type. The following statement defines the dependent index representing the modeldependent space dimensions of the arrays in the Markovian convolution. index space = X:Y[1:dim];
A dependent-index expression introduces two variable names, X and Y in the example, and attaches a range to them, here 1:dim. This range guides the Forge compiler to create just as many pairs of Fortran variables, that is, X1, Y1, X2, Y2, . . . , Xdim, Ydim. Each pair of variables corresponds to the lower and upper boundary variables of a dependent dimension. These created boundary variables will be input parameters of the generated subroutine. It is important that the upper and lower bound of the range can be only a statically evaluable integer expression or a model parameter. This constraint is necessary to ensure that array dimensions are known at compile time for the specifications (and therefore also at Fortran compile time). The validity of the values of the upper and lower bound of the range is checked at compile time. For example, X and Y must be unused variables and the two range values must be integer expressions. Note that the difference between the first and second range value might be negative, for example, if dim is 0, in which case no variable declarations will be generated. Array types can make use of dependent indices either directly or by referring to a dependent-index definition. In general, the index type of an array is composed of a fixed, nondependent part and a dependent part. Fixed index types can be merged with dependent-index types by applying a library function that might also make use of model parameters. If only one index part is needed (fixed or dependent) to describe an index type of an array, a library function call is not required. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
180
•
M. Erwig and Z. Fu
For example, in the interface part of the Markovian convolution, the library function cons places the fixed index L:U at the beginning of a’s and b’s index types which are otherwise given by the dependent index space. index space = X:Y[1:dim]; param real :: dt, tau; integer :: L, U; real, dimension (consL:U,space) :: a, b; local real, dimension (consL:U,space) :: h; integer :: n;
In a more general version of the timeConv tool, we actually use the library function insertAt to place the fixed index at a particular position, which is represented by the variable timePos, in the list of variables represented by a dependent-index expression. real, dimension (insertAttimePos | L:U,space) :: a;
Suppose we generate a Fortran program for an ocean model in which the value of model parameter dim is 2, and timePos is 2. The previously presented code will then be translated into the following Fortran code. integer :: L integer :: U integer :: X1 integer :: Y1 integer :: X2 integer :: Y2 real, dimension (X1:Y1, L:U, X2:Y2) :: a
In the generated Fortran program, the array a has three dimensions which means one dimension of its fixed part plus two dimensions of its dependent part. The value 2 for the model parameter timePos has caused the fixed index part to be created as the second dimension index of a. The main task of library functions is to control the code generation for those parts of the generated Fortran program that rely on dependent indices. For example, the library functions cons or insertAt allow a fixed index part to be combined with dependent indices in array declarations. In Section 2.2, we have seen the library function genLoops that generated nested loops and appropriate array indexing. Library functions like genLoops, therefore, combine several tasks in guiding the translation of discrete equations by model-dependent parameters. The dependent part of an array index depends on model parameters of type integer which are used to calculate the number of the variable dimensions. By using dependent types, we can use a generic form to represent array types used in different models which have different dimensions. The dependent part of an array is never referenced in the discrete equations, but it is necessary for generating Fortran programs. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
181
Fig. 5. The Forge specification for Markovian convolution in time.
2.4 Summary: The Complete Tool Specification for the Markovian Convolution The Forge specification of timeConv is shown in Figure 5. The line numbers are shown to simplify the discussion of type checking that will be presented in Section 3. The specification refers to one model parameter dim. The dependent-index declaration of space depends on dim, which causes the array types of a, b, and h to be of dimension dim+1 since their index type is defined to depend on space which is of dimension dim and adds to space exactly one dimension, L:U. The formulas of the body correspond exactly to the discrete equations that we have seen in Section 2. The library function genLoops takes an integer as the input parameter to generate a corresponding number of nested loops over the Fortran code fragment translated from the argument equations. In the example, genLoops generates exactly dim nested loops for the equations defining h[L] and b[U] (since the index is just a boundary variable) and dim+1 nested loops for the other two equations. Since the arrays are indexed by a variable that is not an array boundary, an additional loop over the time dimension is created. We have deliberately retained much of Fortran’s syntax, in particular, with regard to type, range, and array notation to accommodate the users of Forge who know Fortran very well. This design supports the idea of “gentle slope” [Myers et al. 2000] and makes the specification language easier to learn and to apply. The complete syntax of Forge is shown in Appendix A. We can compile the above specification into a Fortran program by calling the Forge compiler forge. In addition to the specification, we have to provide the name of the model for which we want to generate code. For example, we can generate the Fortran subroutine for the tool Markovian Convolution and the model PEZ by the following command. The model name is used to locate the model specification which will be introduced in Section 2.6. forge timeConv PEZ
The generated Fortran program is written to a file timeConvPEZ.f90 whose content is shown for illustration in Appendix C. Users of the IOM system will not ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
182
•
M. Erwig and Z. Fu
invoke the compiler directly because they interact with the program generator through the graphical user interface shown in Section 1.2. 2.5 Bell-Shaped Convolution in Space We consider another IOM tool to demonstrate a further important feature of Forge, namely, the possibility of parameterizing specifications by modeldependent procedures. Similar to the Markovian convolution, the Bell-shaped convolution in space is also a tool for computing deweighted errors. The convolution is formally defined by the following formula. X b(x) = exp(−(x − x ′ )2 /L2 )a(x ′ )dx ′ . 0
In this continuous formula, a is again the weighted error, and b is the deweighted error. The weighting function F (x, x ′ ) is exp(−(x − x ′ )2 /L2 ), where x and x ′ range over space. L is the correlation length scale and is input by the modelers. The smaller L is, the more quickly the values of far neighbors will be omitted. The Bell-shaped convolution can be discretized to the following equations. θi0 = ai . θin+1 = θin + s · RHSin
for 0 ≤ n ≤ N − 1.
bi = θiN . θ is an intermediate array for solving the final result b. More specifically, θin represents the ith element of the array θ in the nth iteration. The final value of the output array is calculated in the N th iteration. s is the pseudotime step used for computing the next θ from the current θ. N is the number of iterations for computing the final result. N is given by (L2 /4)/s. RHSin is the abbreviation for n n − 2θin + θi−1 θi+1 . (x)2 Since different ocean models use different representations for space, RHSin is computed differently in different models. Therefore, Forge must be able to specify tools that are generic in the computation of RHSin . This dependency on a computation provided by each model is expressed by a subroutine parameter in the specification header. It is not really important to understand why the shown discrete equations are a solution for the continuous one or how they can be derived. The two important aspects this example is intended to demonstrate are: — discrete equations can differ considerably from the continuous equations. — we need a mechanism for including model-dependent code in inversion tools. The specification for the tool bell-shaped convolution is shown in Figure 6. In this example, computeRHS is a Fortran subroutine that has to be provided by the ocean modelers as a model parameter. This subroutine is used ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
183
Fig. 6. The specification for the bell-shaped convolution in space.
for computing the RHSin in the discrete equations of the bell-shaped convolution. This subroutine has a parameter space which is the dependent index because the boundaries of space dimensions are needed by this subroutine. For example, if the value of model parameter dim is 2, then the statement for calling the subroutine in the generated Fortran program will be as follows. call computeRHS(X1, Y1, X2, Y2, theta, rhs)
Note that the type system cannot guarantee type correctness for generated Fortran programs that were created from tool descriptions involving subroutine parameters since we have generally no access to the code of the called subroutine at the time the tool description is processed. We can only check whether the called Fortran subroutine has been declared as a model parameter. In practice, this limitation means that the generated Fortran programs might contain type errors. However, these errors will be contained in the subroutines provided by the user who is responsible for delivering correct subroutines. 2.6 Model Specifications A model specification is given by a model name, followed by model-parameter definitions. Each definition has the form PName = Expr or TName.PName = Expr. The former is for global model-parameter definitions, which means the model parameter can be used by any specification. The latter is for tool-specific model-parameter definitions. TName is a tool name in which the parameter is used, whereas PName is the model-parameter name used by that tool which can be either a variable or a Fortran subroutine name. Tool-specific model parameters cannot be used by other tools. Expr is either a constant or a Fortran ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
184
•
M. Erwig and Z. Fu
file name which contains the Fortran subroutine whose name is the model parameter. Following, we give a simple example of a model specification for the so-called “PEZ” model, the Primitive Equation Z-coordinate Model, which is a variant of the Bryan-Cox-Semtner class model [Pacanowski and Griffies 1999]. Two model parameters are defined in the model specification. The first, dim, is a global model parameter that has the value 3. The second, computeRHS, is a model parameter that can be only used by the tool spaceConv and refers to a Fortran subroutine provided by the modelers who want to generate Fortran code for spaceConv. The code of computeRHS is contained in the Fortran source file "laplace.f90". model PEZ; dim=3; spaceConv.computeRHS = "laplace.f90"
Currently, model specifications allow only the definition of parameters through a collection of name/value pairs. Future work will extend the model specifications to allow for specifications of model-specific optimizations for parallel computations. 3. THE FORGE TYPE SYSTEM The generation of syntax- and type-correct Fortran programs is of great importance in the context of scientific computing because the creation of programs that cause compiler errors disturb users, in particular for program parts they have not written themselves. A principal problem with generated code is that users cannot, in general, understand why the error occurred and, even worse, how to correct it. Such a situation must be avoided at all cost because it can quickly lead to users losing trust in the system and eventually not using it anymore. Therefore, we have put a lot of effort in designing a type system that can prevent errors in generated Fortran programs. The type system captures possible errors at Forge compile time so that inversion tools to be provided by the IOM system can be checked in advance, before they are released, and thus will always compile smoothly when the system is in use. Of course, since the users themselves also provide Fortran code that is combined with the generated code, we cannot rule out syntax or type errors completely, but when the compiler complains about errors, this will happen in user-supplied code, and it should be clear then to the users that it is their responsibility to correct the mistake in their code. The syntactical correctness of generated Fortran programs is automatically guaranteed by the type system of the host language, Haskell. Because Fortran programs are represented by a Haskell data type that can represent only valid abstract Fortran syntax, any syntax error produced by the Forge translator (or by a library function) would be caught by the Haskell type system. Thus, the program generator will ensure that any syntactically correct discrete equations used in specifications will always be translated into syntactically correct Fortran code. Furthermore, the library functions can never introduce syntax errors since they are Haskell functions on the Haskell data type representing ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
185
only syntactically correct Fortran programs. The syntax of Forge is presented in Appendix A. The goal of the Forge type system is to guarantee (as much as possible) the type correctness of the generated Fortran programs which means that any typecorrect specification will be translated into a syntax-correct and type-correct Fortran program. All expressions and statements, including library function calls and Fortran subroutine calls, are checked by the type system. We will demonstrate how the type system can prevent type errors in the generated Fortran programs through several examples. The reader interested in further details can consult the formal typing rules of the type system shown in Appendix B. 3.1 Declaration Typing In the following, we refer to the specification for the Markovian convolution in Figure 5. Declarations in a specification are used to construct two typing environments which are used in statements and expressions to check whether or not variables are used in a type-consistent way. One typing environment, , contains the type information for all model parameters, including external Fortran subroutines, and another typing environment, Ŵ, contains the type information for variables and library functions. A typing environment is a set of pairs (v, t) expressing that name v has the type t. Each declaration statement adds one or more pairs to the typing environment. Model parameter declarations in the parameter list of a specification add such pairs to the typing environment . For example, the following model parameter declaration (line 1) adds (dim, integer) into . integer :: dim
Local variable declarations and parameter declarations are used to declare Fortran variables. For example, the following declaration (line 3) adds (dt, real) and (tau, real) into the environment Ŵ. real :: dt,tau
In the typing environment Ŵ, an array type is represented as a quadruple which consists of the name of the library function used to construct the array type, the fixed index, the dependent index, and the base type of the array. For example, the following declaration (line 5) adds (a, (cons, (L, U), space, real)) and (b, (cons, (L, U), space, real)) into Ŵ. real, dimension (consL:U,space) :: a, b
A dependent-index declaration also adds a (name,type) pair into the typing environment Ŵ. In contrast to Fortran variables declared in a specification, all the dependent-index names have the type depix. Consider, for example, the following dependent-index declaration (line 2). space = X:Y[1:dim];
The type checker adds (space, depix) into the typing environment. Dependentindex names cannot be used in any expressions, they are only used to construct ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
186
•
M. Erwig and Z. Fu
array types which is ensured by their type depix. We need the type information for dependent-index names for checking the library function calls to construct array types. The rules for constructing typing environments are defined in Figure 12 in Appendix B. Array types can be constructed by calling library functions where the validity of the library function calls is checked by the rule ATY⊢ . Consider again the declaration in line 5. Since L and U have type integer, L:U is a valid fixed index. Because the name space has the type depix, it is a valid dependent index. In the typing environment Ŵ, we store the type of the library function cons which is range->depix->range, where range represents fixed index types. The type environment Ŵ is initialized with the types for all available library functions which are derived from the type signatures of the Haskell functions. In the shown declaration, the library function cons has two arguments which are a valid fixed index and a valid dependent index, respectively. Therefore, the library function call in the declaration statement is type correct. 3.2 Expression Typing The expressions in timeConv include constants, such as 0.0 (line 9), simple variables, such as tau and U (line 11), array expressions, such as h[n-1] (line 10), and expressions, such as -0.5*h[U]/tau (line 11). Determining the type of constants and variables is trivial because the type information for constants and variables can be obtained from the typing environment directly. Array expressions are more complex since arrays may have dependent indices. Forge does not allow referencing dependent indices in array expressions since it could cause type errors in the generated Fortran program. For example, suppose we have an expression a[i,1], where 1 refers to the first dimension of the dependent index. If the model parameter dim in the user model is 0, in which case there is no dependent index at all in the array a, then a[i,1] would cause a type error in the generated program because a is only a one-dimensional array. The rule in Figure 14 in Appendix B for array expressions expresses that an expression e can be indexed by index expressions e1 , e2 , . . . , and ek if the type of e is an array type with fixed ranges r1 , r2 , . . . , and rn and n ≥ k (see rule ARRAY⊢ ). Applications of operations are type correct if all the subexpressions are type correct and have types that are compatible with the operator. For example, real and integer are compatible, so tau*2 is type correct. The type of real arrays is compatible to real, so the expression -0.5*h[U]/tau in line 11 is also type correct. The compatibility of types is defined by a relation ∼. Two array types are compatible only when (1) they have the same fixed and dependent dimensions, and (2) the applied library functions for constructing the arrays are the same. We define a rigid form of equality for the dimensions which requires for two dimensions to be equal that both the number of dimensions and the boundaries of each dimension are the same. For example, since b and h are declared by the same statement in line 5 and 6 in Figure 5, they have the same type. Therefore, the expression b[n+1] - dt*(h[n] + b[n+1]/tau) in line 12 is type correct. In contrast, the expression a + b[n] would cause a type error since a and b[n] do not have compatible types. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
187
Since we use library functions to construct array types when declaring array variables, we require that these library functions have the following two properties. (1) Library functions do not change the relative order of fixed or dependent dimensions. (2) Library functions do not change fixed or dependent dimensions, including the number of dimensions and the name or value of the boundaries of each dimension. These conditions guarantee that, after applying a library function, the newly constructed array type still has the same fixed and dependent dimensions as before. These two conditions restrict the effect of library functions essentially to merging dependent and fixed indices in their given order. Unfortunately, these properties of library functions cannot be checked by the compiler. Therefore, only carefully checked, “hand-certified” library functions will be made available to guarantee the soundness of the type checker. Since library functions are, like the type system itself, implemented by the Forge developers and cannot be changed by the IOM developers or ocean modelers, they have the same sensitive status as the implementation of the type checker itself which could also principally contain errors. A careful selection and implementation of library functions together with a careful implementation of the type checker, therefore, can guarantee the soundness of results reported by the type checker. 3.3 Statement Typing The type system also checks the validity of all statements. For example, an assignment statement is valid only if the type of the left-hand side is upward compatible with the type of the right-hand side. The upward compatibility is defined by a relation ≺. If a type t1 is upward compatible with a type t2 , then an expression of type t2 can be assigned to a variable or an array expression of type t1 . For example, in line 9 of Figure 5, the left-hand side of the assignment has the type of array of real numbers; the right-hand side has the type of real. Since a real array is upward compatible with real, this assignment is valid. Similar reasoning shows that all the assignments in Figure 5 are valid. For a Fortran subroutine call, we need to check if the types of the arguments match the types of the subroutine’s parameters. Unlike all other typing constraints, we cannot perform this test independently of a particular model, that is, without knowing the values of the model parameters for that model, because we have to know the subroutine’s parameter definitions to judge whether or not the call is correct. Therefore, we have to defer this test to a time when a Fortran subroutine is generated from the tool specification for a particular model. For example, in line 13 of Figure 6, a Fortran subroutine computeRHS is called. At this point, all we know is that this user-provided subroutine must have 2*dim integer parameters (for the array boundaries) and two more array parameters of the type specified in the local declaration. However, the correctness of the generated subroutine spaceConv cannot be decided at this point and depends critically on the availability of a user-provided Fortran subroutine computeRHS ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
188
•
M. Erwig and Z. Fu
of the corresponding type. Thus, along with the generation of the subroutine spaceConv, we check whether this condition is fulfilled. The formal definition can be found in Figure 16 in Appendix B in the typing rule SUB. Finally, the library function calls for program transformation have to be type checked. When checking a library function call statement, we first obtain the type of the corresponding Haskell function from the type environment Ŵ. For example, the type of the library function genLoops is integer->fortran->fortran, where the type fortran represents Fortran programs. Looking at the application of genLoops in line 8 of Figure 5, we can observe that the first parameter dim is a model parameter of type integer, and the second parameter is a sequence of statements which is translated to Fortran statements. Therefore, the library function application in line 8 is valid. The typing rule for checking library function call statements is defined in Figure 16 in Appendix B in the rule LIB⊢ . 4. RELATED WORK The Earth System Modeling Framework (ESMF) defines an architecture that allows the composition of applications using a component-based approach [Dickenson et al. 2002]. The focus of the ESMF is to define standardized programming interfaces and to collect and provide data structures and utilities for developing model components. Forge is a program generator which is a special kind of metaprogramming tool [Sheard 2001]. The approach for implementing Forge can be considered as single-stage programming since Forge programs are compiled to Fortran programs directly, and program generation only happens at compile time. Program generators also exist as multistage programming languages, such as MetaML [Taha and Sheard 2000] or MetaOCaml [Calcagno et al. 2003], where code can be generated at run-time. Program generators implemented in multistage programming languages are all embedded languages [Elliott et al. 2000] which means that the new language is both syntactically and semantically a subset of an existing language. Forge is implemented in Haskell, but it is not a language embedded in Haskell since the syntax and semantics of Forge are not a subset Haskell. Scientific computing is a popular domain for the application of program generation/program synthesis. Several program synthesis systems are being used in different scientific areas. SciNapse [Akers et al. 1997] is a system for solving partial differential equations (PDEs). It generates Fortran or C programs from a PDE specification. SciNapse is built on top of a general purpose knowledge-based system that contains transformation rules. The generated programs are constructed by instantiating predefined selected algorithm templates. SciFinance [Akers et al. 2001] applies a similar approach to financial modeling—it generates C programs from financial model specifications written in ASPEN (Algorithm SPEcification Notation). CTADEL [van Engelen et al. 1997] is a software environment for generating multiplatform high-performance Fortran code for PDE-based problems from abstract problem specifications. A CTADEL specification is first transformed to intermediate code. Optimizations will be applied to this intermediate code, and ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
189
the refined intermediate code will be translated to Fortran. Planware [Blaine et al. 1998] generates Lisp programs for high-performance scheduler software. Planware first refines an abstract problem specification to a particular scheduling problem, then generates Lisp code by applying a predefined codegeneration tactic. The Amphion system [Lowry and Baalen 1995] guides users in developing a formal specification of a problem and then implements this specification as a Fortran program consisting of calls to subroutines from a library. The program generation is based on intuitionistic propositional logic. AutoBayes [Fischer et al. 2000] is a program synthesis system implemented in SWI-Prolog for statistical data analysis. It generates optimized C/C++ code from the description of a data analysis problem in the form of a statistical model. The generated programs are documented; assumptions and proof obligations that have not been discharged during the program generation process are presented in the documentations or are converted into run-time assertions. A system for generating numerical programs for simulation of rigid mechanical systems in physics-based animation is introduced in Ellman et al. [2003]. It generates a numerical C++ simulation program that drives a real-time animation of a specified scenario. The program generation is implemented by instantiating a generic parameterized program scheme. All these systems have a similar goal to Forge which is to generate programs automatically for a specific scientific application from abstract specifications. However, there are three main differences between these applications and our system. First, the described systems work on more abstract specifications, for example, partial differential equations or scheduling problem descriptions while Forge works with discrete equations. Generating programs from a more abstract specification may save users work, for example, deriving discrete equations from a continuous equation. However, this approach also limits the applicability of the systems since they often have more constraints on the problems they are solving. Since discrete equations can be derived from almost all scientific formulas, Forge can be used more broadly. Second, most of the above systems focus on generating efficient code for a specific problem instead of reusing existing user code. In contrast, we are aiming at generating model-dependent programs which require the existing user code to be reused as much as possible. Finally, in our system, guaranteeing the type correctness of the generated program is a major goal. However, the described systems do not guarantee the type correctness of the generated programs. In metaprogramming systems like MetaML [Taha and Sheard 2000] or Template Haskell [Sheard and Peyton Jones 2002], the metaprogramming language is an extension of the object language. In our system, metaprogramming happens in three different languages: (1) the specifications are defined in Forge, (2) the library functions are written in Haskell, and (3) the generated programs are Fortran. Existing Fortran metaprogramming tools include Foresys [Simulog, SA 1996], whose focus is on the refactoring of existing Fortran code, for example, transforming a Fortran77 program into Fortran90 program. Sage++ [Bodin et al. 1994] is a tool for building Fortran/C metaprogramming tools. However, to express applications as the ones shown here, a user has to write metaprograms in Sage++ for transforming Fortran which is quite difficult ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
190
•
M. Erwig and Z. Fu
and error prone and probably beyond the capabilities of scientists who otherwise just use Fortran. In contrast, Forge allows users to work mostly in Fortran and express generic parts by parameters; most of the metaprogramming issues are hidden inside the compiler and parameter definitions. Macrofort [Gomez and Capolsini 1996] can generate Fortran code from Maple programs but does not provide the mechanism to deal with generic, model-dependent code. Recently, we have investigated an alternative approach to Fortran program generation through a language called Parametric Fortran [Erwig and Fu 2004] that allows the definition of Fortran extensions by parameter structures that can be referred to in Fortran programs to specify the dependency of program parts on these parameters. By providing parameter values, a parameterized Fortran program can be translated into a regular Fortran program. These parameters are very different from the model parameters of Forge. The behavior of these parameters has to be specified explicitly through Haskell definitions for each parameter type, whereas this behavior is essentially predefined in Forge and can be adjusted through library functions. With Parametric Fortran we can create complete Fortran programs, whereas Forge is limited to the specification and generation of subroutines that will be part of larger simulation programs. Since Parametric Fortran is a more general approach than Forge, it lacks most of the safety guards provided by the Forge type system. To summarize, our approach can be considered as the combination of generative programming [Czarnecki and Eisenecker 2000] and template metaprogramming [Veldhuizen 1995; Sheard and Peyton Jones 2002]. Forge is a generative programming language because the Forge programs are used to generate Fortran programs. Forge also supports template definitions, for example, the array types parameterized by model parameters. 5. CONCLUSIONS Using generic descriptions for inverse ocean modeling tools enables the developers of the IOM system to specify tools once and let a program generator create Fortran implementations automatically for different ocean models. The mix of a declarative language for a mathematical specification of tools by discrete equations and the availability of library functions to incorporate model-specific aspects into the translation process makes the language Forge a high-level language that also provides a well-defined, flexible path for extensions. A sophisticated type system facilitates the consistency checking of specifications independently of particular models, that is, tools can be checked before they are released and used by scientists. Preventing the generation of erroneous Fortran programs increases the reliability and helps to promote the acceptance of the approach. The design of Forge supports the collaboration of ocean scientists, software developers, and computer scientists and provides, at the same time, a high degree of independence that facilitates the further development of tools and the specification language. The IOM tools generated by Forge are currently intensively used with the ocean model PEZ at Oregon State University and the National Center for ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
191
Fig. 7. Syntax of specifications.
Fig. 8. Syntax of interfaces.
Atmospheric Research and with the model KDV at Arizona State University. Other ocean modeling groups are currently in the process of adapting the IOM system so that the graphical user interface and the Forge compiler will soon be also used for models, such as ROMS (developed at Rutgers and University of Colorado), ADCIRC (developed at Arizona State University and University of North Carolina), and SEOM (also developed at Rutgers). One main goal for future versions of Forge is to improve the support for parallel computing. To cope with huge data sets, modelers typically prefer to run the IOM tools in parallel. To support this goal, Forge needs to be able to generate parallel code for different parallel infrastructures, for example, data decomposition for distributed memory supercomputers, the class of sharedmemory vector supercomputers, or NUMA scalar supercomputers, depending on what infrastructure the modelers use. To express parallelism within tools requires the extension of Forge to support parameterizing tool specifications with different parallel infrastructures and generating parallel code. APPENDIX A: THE SYNTAX OF FORGE A specification (Spec) has a name followed by a list of model parameter declarations (MPList) and consists of an interface part (Interface) and a body which is given by a statement (Stmt), see Figure 7. The binary operators * and / in Figure 7 can be used on two values or a value and an array, but not on two arrays. The syntax of interfaces is summarized in Figure 8 which builds on the syntax for dependent-index declarations which are ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
192
•
M. Erwig and Z. Fu
Fig. 9. Syntax of dependent-index declarations.
Fig. 10. Forge types.
Fig. 11. Syntax of parameter definitions.
shown in Figure 9. Dependent index expressions are a special form of dependent types [Xi and Pfenning 1999]. The syntax of types is shown in Figure 10. The type fortran is used in the types of library functions that are used as program transformations. Function types are used to represent the types of library functions and external Fortran subroutines. Finally, the syntax of model specifications is defined in Figure 11. B: THE TYPING RULES OF FORGE In the following rules, we use metavariables e, f , vd , p, r, s, and v to range over Expr, FName, VarDecl, PName, Range, Stmt and VName, respectively. We use t to range over the Forge types. For convenient use in the typing rules, we represent array types by quadruples ( f , FixInd, DepInd, Bty). The judgment Aty ⇓ t used in the rule AVS⊢ expresses that t is the quadruple corresponding to the array type Aty. The judgment Aty ⇓ t is defined in Figure 13 by inference rules. This style of defining typing judgments by rules is explained in detail, for example, in Benjamin Pierce’s book [Pierce 2002]. Simply said, a rule consists of zero or more premises, P1 , . . . , Pn , written above the bar and one conclusion, C, and has the meaning that the conclusion is true if all the premises are fulfilled. If n = 0, that is, if no premises are given, the conclusion is always true and the corresponding rule just states a fact. All the rules in Figure 13 are facts, but the rules in Figure 12 contain premises. Premises and conclusions are expressed in form of judgments which are essentially relations between the participating objects. For example, the judgment Aty ⇓ t expresses the relationship between an array type Aty and its quadruple representation. The rules in Figure 12 define how to construct two typing environments, and Ŵ, from the interface part of a specification. A typing environment is a set ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
193
Fig. 12. Rules for environment judgments.
Fig. 13. Array representations. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
194
•
M. Erwig and Z. Fu
of pairs (v,)t, expressing that variable v has the type t. The typing environment contains the type information for all model parameters including external Fortran subroutines to be called, whereas Ŵ contains the type information for constants, variables, and library functions. Ŵ0 is the initial typing environment which contains the type information of constants and library functions. The judgment ; Ŵ ⊢ d ≻ ′ ; Ŵ ′ expresses that the declaration d changes the current typing environments from and Ŵ to ′ and Ŵ ′ . The judgment ; Ŵ ⊢ t expresses that t is a valid array type under the typing environments. The judgment ; Ŵ ⊢ e : t expresses that the expression e has the type t under the typing environments. We maintain two separate typing environments, Ŵ and , because model parameters can only be used in expressions for dependent indices, and the parameters of library functions can only be model parameters. The rule MP⊢ and MPS⊢ show how is constructed from model parameter declarations. If a model parameter declaration t :: p appears in the parameter list of a specification, the pair ( p, t) will be added into the typing environment . DIXE⊢ says that a dependent-index expression is valid only if the two expressions specifying the number of dependent dimensions have integer types and only contain model parameters and constants. Fortran variables must not appear in the expressions because the number of dependent dimensions has to be known at compile time. Therefore, we use and Ŵ0 , which do not contain type information for Fortran variables, to infer the type of the two expressions in the rule DIXE⊢ . The presence of Fortran subroutine names in causes no problem since their result type is subroutine, which means that they can never successfully contribute to a well-typed integer expression. The rule DIX⊢ shows that if a dependent-index expression is valid and is bound to a name, then the name has the type depix in the typing environment Ŵ. We do not have to distinguish different dependentindex types in the type system because the type depix is only used to check if a library function call for constructing a dependent array type is type correct by the rule ATY⊢ and DATY⊢ . As long as a dependent index is type correct, library functions can be applied to it—the exact type does not matter. Therefore, all dependent-index expressions and names have the same type depix. The rules BVS⊢ and AVS⊢ check variable declarations. If a variable has a base type, the rule BVS⊢ adds the pair (v, t) into Ŵ. If a variable has an array type, the rule AVS⊢ first checks if the array type is valid in which case the name and the quadruple representing the array type is added into Ŵ. The rule RANGE⊢ expresses that a range consists of two integer expressions. Since the two expressions of a range can only contain Fortran variables, we use ∅ instead of in the premises of the rules RANGE⊢ and FIX⊢ . The rules FATY⊢ and DATY⊢ check if an array type is valid when there is no library function involved. FATY⊢ says that if an array type only contains fixed indices, the fixed indices must have the type range. DATY⊢ says that if an array type only contains dependent indices, the dependent indices must have the type depix. When an array type is constructed by a library function, the rule ATY⊢ needs to check if the library function call is type correct. Every library function is a Haskell function whose type signature is contained in Ŵ0 . A library function used for merging array indices must have the type t1 -> · · · ->tk -> range -> depix -> range. The type of every parameter of the library function has to match the type signature. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
195
Fig. 14. Typing rules for expressions.
Fig. 15. Partial order on types.
The rules PS⊢ and LS⊢ add the typing information of all the parameter variables and local variables into the typing environment Ŵ. The rule ENV⊢ shows how the type environments are constructed from the interface part of a specification. We start from the initial typing environments ∅ and Ŵ0 . The result typing environment contains the type information for all model parameters. The type information for all the dependent-index names, parameter variables, and local variables will be subsequently added, and the result typing environment is Ŵ ′′ . The rules in Figure 14 define the typing rules of Forge expressions. The judgment ; Ŵ ⊢ e : t means the expression e has the type t under the typing assumptions and Ŵ. The rule ARRAY⊢ shows that we only allow referencing fixed indices in Forge. This restriction is necessary because the number of dimensions of dependent indices is different in different models, it might even be 0 in some models. The rule UOP⊢ is trivial since we currently have negation as the only unary operator in our abstract syntax, see Figure 7. The notation t1 ∼ t2 is used to express that t1 and t2 are compatible in the sense that binary operations can operate well on arguments of both types. The relation ∼ is defined as follows. t1 ∼ t2 iff t1 ≺ t2 or t2 ≺ t1 . In the definition, we use a partial order relation on types, ≺ which is defined in Figure 15. The rule BA≺ essentially allows the initialization of an array with a constant or the addition of a constant to every element of an array, see rule ASSGN⊢ in Figure 16. This rule overloads constants of base types with array types. The inclusion of the ordering ≺ may not seem necessary since we currently have only two base types, integer and real, but this relation will be very useful when we extend the type system to include more base types. The function max returns the larger of two types with respect to ≺ if the two types are comparable, ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
196
•
M. Erwig and Z. Fu
Fig. 16. Type rules for Forge statements.
that is max(t1 , t2 ) returns t1 if t2 ≺ t1 , otherwise it returns t2 . Note that the application of max in rule BOP⊢ is always well defined since max will be applied only if its argument are compatible. The typing rules in Figure 16 define the typing of Forge statements. The judgment ; Ŵ ⊢ s means that the statement s is valid under the typing environments and Ŵ. The rule ASSGN⊢ says that the assignment statement is valid if the type of the left-hand side is upward compatible with the type of the right-hand side. For example, we can assign a real number to a real array which has the effect that all the elements in the array will be initialized to the same value. The use of ∅ in the two premises ensures that v and all variables used in e are not confused with model parameters and that they have valid types defined in Ŵ. The rule SEQU⊢ expresses that a sequence of two statements is valid only if both statements in the sequence are valid. In the rule SUB⊢ we can only check whether the called Fortran subroutine SubName has been declared as a model parameter. We cannot check the type consistency of the arguments because we do not have access to the code of the called subroutine at this time. The rule LIB⊢ checks a library function call in a similar way as the rule ATY⊢ in Figure 12. The typing rule SPEC⊢ expresses that if the body of a specification is type correct under the typing environments constructed from its interface, the whole specification is type correct. C: THE RESULT OF COMPILING timeConv FOR PEZ subroutine timeConv(X1, Y1, X2, Y2, X3, Y3, L, U, dt, tau, a, b) integer :: dim3i integer :: X3 integer :: Y3 integer :: dim2i integer :: X2 integer :: Y2 ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Software Reuse for Scientific Computing Through Program Generation
•
197
integer :: dim1i integer :: X1 integer :: Y1 real :: dt real :: tau integer :: L integer :: U real , dimension (L:U, X1:Y1, X2:Y2, X3:Y3) :: a real , dimension (L:U, X1:Y1, X2:Y2, X3:Y3) :: b real , dimension (L:U, X1:Y1, X2:Y2, X3:Y3) :: h integer :: n do dim3i = X3, Y3, 1 do dim2i = X2, Y2, 1 do dim1i = X1, Y1, 1 h(L,dim1i,dim2i,dim3i) = 0.0 do n = L+1, U, 1 h(n,dim1i,dim2i,dim3i) = h(n-1,dim1i,dim2i,dim3i) & & -dt*(h(n-1,dim1i,dim2i,dim3i)/tau+2.0*a(n,dim1i,dim2i,dim3i)/tau) end do b(U,dim1i,dim2i,dim3i) = -0.5*h(U,dim1i,dim2i,dim3i)/tau do n = U-1, L, -1 b(n,dim1i,dim2i,dim3i) = & & b(n+1,dim1i,dim2i,dim3i)-dt*(h(n,dim1i,dim2i,dim3i) & & +b(n+1,dim1i,dim2i,dim3i)/tau) end do end do end do end do end subroutine timeConv ACKNOWLEDGMENT
The authors would like to thank the anonymous reviewers for the comments and many detailed suggestions that helped to improve this article. REFERENCES AKERS, R. L., BICA, I., KANT, E., RANDALL, C., AND YOUNG, R. L. 2001. SciFinance: A program synthesis tool for financial modeling. AI Magazine 22, 2, 27–42. AKERS, R. L., KANT, E., RANDALL, C. J., STEINBERG, S., AND YOUNG, R. L. 1997. SciNapse: A problemsolving environment for partial differential equations. IEEE Computa. Sci. Eng. 4, 3, 32–42. BLAINE, L., GILHAM, L., LIU, J., SMITH, D. R., AND WESTFOLD, S. J. 1998. Planware—Domain-specific synthesis of high-performance schedulers. In IEEE Proceedings of Automated Software Engineering. 270–280. BODIN, F., BECKMAN, P., GANNON, D., GOTWALS, J., AND SRINIVAS, S. 1994. Sage++: A class library for building fortran 90 and C++ restructuring tools. In Second Object-Oriented Numerics Conference (OON-SKI’94). 122–138. CALCAGNO, C., TAHA, W., HUANG, L., AND LEROY, X. 2003. Implementing multi-stage languages using ASTs, Gensym, and Reflection. In Generative Programming and Component Engineering (GPCE). Lecture Notes in Computer Science, vol. 2830, 57–76. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
198
•
M. Erwig and Z. Fu
CASTLEMAN, K. R. 1996. Digital Image Processing. Prentice-Hall, Englewood Cliffs, NJ. CHUA, B. AND BENNETT, A. F. 2001. An Inverse Ocean modeling system. Ocean Model. 3, 137–165. CZARNECKI, K. AND EISENECKER, U. W. 2000. Generative Programming: Methods, Tools, and Applications. Addison-Wesley, Reading, MA. DICKENSON, R. E., ZEBIAK, S. E., ANDERSON, J. L., BLACKMON, M. L., DELUCA, C., HOGAN, T. F., IREDELL, M., JI, M., ROOD, R., SUAREZ, M. J., AND TAYLOR, K. E. 2002. How can we advance our weather and climate models as a community? Bull. Amer. Meteorol. Soc. 83, 3, 431–434. DORNAN, C. 1997. Alex: A Lex for Haskell Programmers. Available at http://haskell.org/libraries/ alex.tar.gz. ELLIOTT, C., FINNE, S., AND DE MOOR, O. 2000. Compiling embedded languages. In Semantics, Applications, and Implementation of Program Generation (SAIG). 9–27. ELLMAN, T., DEAK, R., AND FOTINATOS, J. 2003. Automated synthesis of numerical programs for simulation of rigid mechanical systems in physics-based animation. Autom. Softw. Eng. 10, 367– 398. ERWIG, M. AND FU, Z. 2004. Parametric Fortran—A program generator for customized generic fortran extensions. In 6th International Symposium on Practical Aspects of Declarative Languages. Lecture Notes in Computer Science, vol. 3057, 209–223. ESMF. Available at http://www.esmf.ucar.edu/. FISCHER, B., SCHUMANN, J., AND PRESSBURGER, T. 2000. Generating data analysis programs from statistical models. In Semantics, Applications, and Implementation of Program Generation (SAIG). 212–229. GOMEZ, C. AND CAPOLSINI, P. 1996. Macroc and Macrofort, C and Fortran Code generation within Maple. Maple Technical Newsletter 3, 1. IOM. Available at http://iom.asu.edu/. IVERSON, K. E. 1984. Introduction to APL. APL Press. IVERSON, K. E. 1995. J Introduction and Dictionary. Iverson Software Inc. Toronto, Canada. LOWRY, M. AND BAALEN, J. V. 1995. Meta-Amphion: Synthesis of efficient domain-specific program synthesis systems. In 10th Conference on Knowledge-Based Software Engineering. 2–10. MARLOW, S. AND GILL, A. 2000. Happy User Guide. Available at http://www.haskell.org/happy/doc/ html/happy.html. MILI, H., MILI, A., YACOUB, S., AND ADDY, E. 2002. Reuse-Based Software Engineering. John Wiley & Sons, New York, NY. MYERS, B., HUDSON, S., AND PAUSCH, R. 2000. Past, present, and future of user interface software tools. ACM Trans. Comput.-Hum. Intera. 7, 1, 3–28. PACANOWSKI, R. C. AND GRIFFIES, S. M. 1999. MOM 3.0 Manual. NOAA/GFDL. PEYTON JONES, S. L. 2003. Haskell 98 Language and Libraries: The Revised Report. Cambridge University Press, Cambridge, UK. PIERCE, B. C. 2002. Types and Programming Languages. MIT Press, Cambridge, MA. SHEARD, T. 2001. Accomplishments and research challenges in meta-programming. In 2nd International Workshop on Semantics, Applications, and Implementation of Program Generation. Lecture Notes in Computer Science, vol. 2196, 2–44. SHEARD, T. AND PEYTON JONES, S. L. 2002. Template metaprogramming for Haskell. In Haskell Workshop. Simulog, S. A. 1996. FORESYS, FORtran Engineering SYStem, Reference Manual vol. 5. Simulog, SA, Guyancourt, France. Available at http://www.cs.vassar.edu/˜ellman/ause-689-03revised.pdf. TAHA, W. AND SHEARD, T. 2000. MetaML and multi-stage programming with explicit annotations. Theor. Comput. Sci. 248, 1-2, 211–242. VAN ENGELEN, R., WOLTERS, L., AND CATS, G. 1997. The CTADEL application driver for numerical weather forecast systems. In Proceedings of the 15th IMACS World Congress. 4. 571–576. VELDHUIZEN, T. L. 1995. Template metaprograms. C++ Rep. 7, 4, 36–43. XI, H. AND PFENNING, F. 1999. Dependent Types in Practical Programming. In 26th ACM Symposium on Principles of Programming Languages. 214–227. Received July 2003; revised December 2003, May 2004; accepted October 2004
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
A Comprehensive Approach for the Development of Modular Software Architecture Description Languages ´ VAN DER HOEK, and RICHARD N. TAYLOR ERIC M. DASHOFY, ANDRE University of California, Irvine
Research over the past decade has revealed that modeling software architecture at the level of components and connectors is useful in a growing variety of contexts. This has led to the development of a plethora of notations for representing software architectures, each focusing on different aspects of the systems being modeled. In general, these notations have been developed without regard to reuse or extension. This makes the effort in adapting an existing notation to a new purpose commensurate with developing a new notation from scratch. To address this problem, we have developed an approach that allows for the rapid construction of new architecture description languages (ADLs). Our approach is unique because it encapsulates ADL features in modules that are composed to form ADLs. We achieve this by leveraging the extension mechanisms provided by XML and XML schemas. We have defined a set of generic, reusable ADL modules called xADL 2.0, useful as an ADL by itself, but also extensible to support new applications and domains. To support this extensibility, we have developed a set of reflective syntax-based tools that adapt to language changes automatically, as well as several semantically-aware tools that provide support for advanced features of xADL 2.0. We demonstrate the effectiveness, scalability, and flexibility of our approach through a diverse set of experiences. First, our approach has been applied in industrial contexts, modeling software architectures for aircraft software and spacecraft systems. Second, we show how xADL 2.0 can be extended to support the modeling features found in two different representations for modeling product-line architectures. Finally, we show how our infrastructure has been used to support its own development. The technical contribution of our infrastructure is augmented by several research contributions: the first decomposition of an architecture description language into modules, insights about how to develop new language modules and a process for integrating them, and insights about the roles of different kinds of tools in a modular ADL-based infrastructure.
This work was sponsored by the Defense Advanced Research Projects Agency (DARPA) and Air Force Research Laboratory, Air Force Materiel Command, USAF, under agreement number F3060200-2-0599. The work was also partially funded by the National Science Foundation under Grant Nos. CCR-0093489 and IIS-0205724. The U.S. Government is authorized to reproduce and distribute reprints for Governmental purposes notwithstanding any copyright annotation thereon. The views and conclusions contained herein are those of the authors and should not be interpreted as necessarily representing the official policies or endorsements, either expressed or implied, of the National Science Foundation, the Defense Advanced Research Projects Agency (DARPA), the Air Force Laboratory, or the U.S. Government. Authors’ address: Institute for Software Research, University of California, Irvine, CA. 92697; email: {edashofy,andre,taylor}@ics.uci.edu. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or direct commercial advantage and that copies show this notice on the first page or initial screen of a display along with the full citation. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, to redistribute to lists, or to use any component of this work in other works requires prior specific permission and/or a fee. Permissions may be requested from Publications Dept., ACM, Inc., 1515 Broadway, New York, NY 10036 USA, fax: +1 (212) 869-0481, or [email protected]. C 2005 ACM 1049-331X/05/0400-0199 $5.00 ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005, Pages 199–245.
200
•
E. M. Dashofy et al.
Categories and Subject Descriptors: D.2.11 [Software Engineering]: Software Architectures; D.2.2 [Software Engineering]: Design Tools and Techniques General Terms: Design, Languages Additional Key Words and Phrases: Architecture description languages, XML, xADL 2.0, ArchStudio 3
1. INTRODUCTION Software architecture-based development addresses software at a higher-level of abstraction than objects or lines of code [Perry and Wolf 1992]. At a minimum, software architecture deals with software systems consisting of components (loci of computation), connectors (loci of communication), and configurations (arrangements of components and connectors, and properties of that arrangement). At this level of abstraction, many aspects of a software system can be modeled: its topology, behavior, usage scenarios, deployment profile, and so on. Each of these aspects may also be modeled at different levels of detail or in different ways. Each way of modeling can bring its own advantages, perhaps providing a new way to analyze or simulate the system or to explain the system’s structure to other developers. Despite these advantages, software architecture research has yet to make a significant impact on software engineering in practice. We believe that this can be partially attributed to the fact that current techniques and tools for modeling software architectures (and leveraging the information contained in those models) have failed to meet the needs of software engineering practitioners. Making software architecture cost-effective requires that the notations, tools, and techniques used model the important aspects of a system at the right level of detail. The result of a decade of research has been a plethora of notations for representing software architectures, usually in the form of architecture description languages (ADLs) [Medvidovic and Taylor 2000]. In general, the notations developed to date each support a single research goal. However, to be useful in a real-world context, software architecture research must move beyond single-purpose notations. Architectures must capture many aspects of a software system simultaneously. Furthermore, the set of aspects that are important enough to model varies from domain to domain. For example, embedded systems projects may require extensive, detailed modeling capabilities for timing and power consumption, while distributed systems may require modeling aspects of fault tolerance and bandwidth usage. Despite this wide spectrum of needs across domains, however, many projects will also share some modeling needs. For example, both embedded and distributed system architects may be concerned with tracking and managing the evolution of their architectures across product releases. Projects within a domain will typically exhibit even larger sets of common concerns. The wide differences in modeling priorities and needs across domains indicates that a satisfactory “one-size-fits-all” ADL is unlikely to emerge. However, the significant commonalities that exist, even among disparate domains, ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
201
indicate that developing new notations for each domain (or project) from scratch means consistently reinventing the wheel. Therefore, a middle ground is necessary: one that allows architects to choose from the common architecture-level aspects of the software system those aspects they want to model and to easily add to those their own concerns. We hypothesize that such a middle ground exists in the form of an infrastructure in which ADLs can be quickly constructed, combining compatible modeling features and allowing explorative integration of new features as necessary. These ADLs would be modular rather than monolithic: modeling features would be encapsulated in modules and modules would be composed into ADLs. This will reduce the amount of effort it takes for architects to obtain a notation that helps them to model the “right” aspects of their systems at the “right” level of detail. This raises many interesting research questions. What is an effective set of technologies to create a modular notation? How can ADL features be effectively modularized and later composed? How can feature modules be developed so as to maximize reusability and compatibility with other modules that may be independently developed? What is the process by which architects can develop new features (or new ADLs), and how can tools support this process? How can tools be constructed in this context to maximize their reusability and applicability? To answer these questions, we have taken an empirical approach. First, we have created an infrastructure for the creation and use of modular ADLs. This infrastructure provides: (1) an XML-based modular extension mechanism for defining ADLs; (2) a base set of features that can be reused in ADL development, supporting design-time and run-time modeling, implementation mappings, and product lines; and (3) a flexible set of tools to support ADL development and use. Second, we followed up the creation of this infrastructure with four evaluation cases in different domains, both to test the infrastructure and to give us additional insights regarding the research questions at hand. The results of these experiences indicate that our infrastructure is generic, extensible, scalable, capable of modeling advanced features from other ADLs, and capable of supporting its own development. The primary research contributions of our approach are the first decomposition of an architecture description language into modules, insights about how to develop new language modules and a process for integrating them, and insights about the roles of different kinds of syntactic and semantic tools in a modular infrastructure. In addition, the infrastructure itself represents a technical contribution in the form of modeling features and tools that can be used in practice. Use of this infrastructure results in a significant overall reduction in effort compared to developing ADLs and supporting tools from scratch. Tool support for extensible ADLs is especially important. While it may be relatively easy to change the definition of a language, adapting tools to support a modified language has been costly. We take this into account by using a two-tiered approach. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
202
•
E. M. Dashofy et al.
A first layer of tools is primarily syntactic: these tools generate their behaviors and interfaces from XML schemas directly, adapting to language changes and new modules automatically. A second layer of tools is primarily semantic: these tools leverage the syntactic tools, but also make assumptions about the meanings of elements specified in language modules. Because of this, the semantic tools are generally more capable and user-friendly than the syntactic tools at the cost of changes and updates when the underlying language changes. A research question we chose not to address is how to ensure semantic compatibility among ADL features. Our approach primarily addresses syntactic compatibility and extensibility. Semantics are a more complex issue. The feature interaction problem [Zave 1999] has been described as the primary problem in extensible language development [Berners-Lee and Connolly 1998; Peake and Salzman 1997]. In our approach, ensuring semantic compatibility among language features is the responsibility of the ADL developer. This is not unique to our approach; developers who create new ADLs from scratch must also address feature interactions. The remainder of this article is organized as follows. Section 2 provides background material about software architectures, ADLs in general, and XML. Section 3 provides a high-level introduction to our approach. Section 4 discusses our set of reusable ADL features. Section 5 details the tools we have developed to support ADL development. Section 6 discusses how our infrastructure has been applied in several domains. Section 7 summarizes our main research results and describes the insights we developed while building and using our infrastructure. Section 8 compares our work to related projects. Finally, Section 9 concludes the article and discusses future work. 2. BACKGROUND Understanding our approach requires a background in software architecture research, the large body of previous work in developing software architecture description languages (ADLs), and some information on XML itself. 2.1 Software Architecture Since the development of abstraction and modularization in software development, abstract models (formal or otherwise) of a system’s structure have played a key role in the development of large software systems. As the complexity of systems has increased, support for more and more abstract concepts in programming languages and environments has also increased. Object- oriented development, for example, provides a useful abstraction above the level of program statements by encapsulating related functionality and state in a single construct: the object. Software architecture research has resulted in a level of abstraction above that of simple objects, modules, or lines of code [Perry and Wolf 1992]. Architecture descriptions of software systems are generally composed of at least three key entities: components, connectors, and configurations [Medvidovic and Taylor 2000]. Components are the loci of computation in an architecture, and may be stateful. In this way, they resemble objects, but components and objects differ in ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
203
several ways. Components tend to be larger than objects, often encapsulating an entire off-the-shelf library or tool. Components are rarely created and destroyed in the life of a software system, objects are created and destroyed constantly [Szyperski 1997]. Connectors are the loci of communication in an architecture. Connectors may be implicit, like a procedure call, or explicit, resembling a component. Simple connectors may be implemented as a basic message queue or API entrypoint, complex connectors may encapsulate middleware or cross process boundaries. This can blur the distinction between components and connectors; a good rule of thumb is that connectors may change the form or syntax of the data they convey but generally do not affect application-level semantics; that is, they do not change the meaning of the data [Mehta et al. 2000]. Configurations describe how components and connectors are arranged, as well as the properties of that particular arrangement. Most commonly, this is expressed through a set of explicit component-to-connector links that define an architectural topology. Alternatively, it may include constraints or patterns on arrangements of components and connectors, or how they behave. 2.2 Architecture Description Languages Beyond components, connectors, and configurations, a description of a software system at the architectural level can contain almost any kind of information. The kinds of information present in an architecture description are influenced by the domain in which the software is being developed and how the architecture description is being used. The proliferation of specialized architecture description languages over the past decade confirms this. Wright [Allen and Garlan 1997] extends component and connector specifications with behavioral information in the language of communicating sequential processes (CSP) [Hoare 1978] so that architectures can be analyzed. Rapide [Luckham et al. 1995] describes components with partially ordered event sets called POSETs so that their behavior can be simulated. Darwin [Magee et al. 1995] describes configurations of systems that are distributed across multiple processes and machines. Despite the fact that these notations share many common conceptual elements (components, connectors, interfaces, links, and so on), they do not share even a syntactic basis. This renders each notation’s tools incompatible with the others. Other ADLs such as Weaves [Gorlick and Razouk 1991] and MetaH [Binns et al. 1996] are similarly incompatible. To compound the problem, all these languages lack support for extensibility, so adding features to any of them would require significant changes to all its supporting tools. The most notable exception to this from the architecture community is Acme [Garlan et al. 2000] which was developed as an architectural interchange language. The Acme core consists of basic types of constructs that occur in practically every architecture notation: components, connectors, interfaces (called ports and roles), links (called connections), and so on. Each of these core entities is decorated with a set of arbitrary name-value pair properties. This strategy allows some extensibility, but its usefulness is hampered by several constraints. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
204
•
E. M. Dashofy et al.
Fig. 1. Sample marked-up text in XML.
(1) It is not possible to extend the core set of elements (components, connectors, ports, roles) to add new first-class entities. This prohibits architectural constructs that are not naturally represented as decorations on one of the core elements such as component version trees. (2) It is difficult to encode and manage complex data structures as sets of namevalue pair properties. (3) Acme is not supported by a metalanguage that allows description of allowable properties and their format. Thus, Acme’s ability to serve as a general-purpose interchange language or extensible ADL is diminished. 2.3 XML as a Basis for an Extensible Modeling Language Constructing an extensible modeling language for software systems requires a way to define allowable constructs in the language and a way to extend or change constructs in the language to add or modify features. Many metalanguages and environments exist in which an extensible, modular language can be created, among them XML [Bray et al. 1998], Lisp [Steele 1990], GME [Ledeczi et al. 2000], and DOME [Honeywell Inc. 1999]. From a technical and theoretical perspective, we could have used any of these environments to develop our infrastructure (although they are not all equivalent; technical differences between these approaches are discussed further in Section 8.2). From a practical perspective, however, XML has far more support from standards committees, tool vendors, and practitioners than any other alternative. XML is platformneutral, unbound to any particular hardware or network architecture. Many ancillary standards support XML, such as XLink [DeRose et al. 2001], which allows linking within and between XML documents, and XPath [Clark and DeRose 1999], which allows indexing of specific elements and attributes within a document. A plethora of off-the-shelf tools for constructing, visualizing, storing, and manipulating XML documents are available. This is not to say that XML is by any means perfect even for our application. Specific drawbacks of using XML are detailed in Section 7.3. We believe, however, that XML’s support for modular extensibility and extrinsic benefits far outweigh its technical drawbacks. XML documents are text documents in which some of the text is marked up using specially formatted tags that define the beginning and end of a segment of marked-up text. Data delimited by a start and end tag is known as an element; start tags can contain additional annotations called attributes. Data marked up with elements and attributes is shown in Figure 1. It is possible to introduce a grammar of elements and attributes over XML documents using one of several available metalanguages. Several ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
205
metalanguages for defining XML grammars are available, two of which have been standardized by the World Wide Web Consortium (W3C): DTDs and XML schemas [Fallside 2001]. DTDs offer limited mechanisms for supporting modular extensibility as evidenced in the Modularization of XHTML standard [Altheim et al. 2001]. However, XML schemas are much more capable in this regard, offering an easy way to define constructs in one schema and extend them in another through a mechanism very similar to object-oriented subtyping. A subtype can add new elements and attributes to the content model of its supertype. Unlike in object-oriented types, however, XML schema subtypes can also be more restrictive than their supertypes in certain ways. Specifically, they can restrict the cardinality of elements in their supertype. For example, if an element in the supertype has cardinality 0-n, the cardinality of the element in a restricted subtype could be 0-0, eliminating the element entirely. 3. APPROACH Existing architecture description languages are either too specific (e.g., singlepurpose ADLs like Rapide, Darwin, or Koala) or too general (e.g., Acme). Furthermore, the cost to adapt a notation and its tools to support a new feature— even when that feature only slightly extends the capabilities of the target ADL—is prohibitively expensive. To remedy this, we have developed an infrastructure supporting modular extensibility. Our objectives in building this infrastructure were: — It must place as few limits on what can be expressed at the architecture level as possible; —It should allow new modeling features to be added and existing features to be modified over time; —It should allow experimentation with new features and combinations of features; —It should provide a library of generically useful modules applicable to a wide variety of domains; —It should allow modeling features, once defined, to be reused in other projects; and — It should provide tool-builders with support for creating and manipulating architecture models, even when the underlying notation can and will change. The core elements of our infrastructure are shown in Figure 2. At the base of the infrastructure is a collection of language modules, realized in our implementation as XML schemas. These schemas define modeling constructs and extend modeling constructs from other schemas. Some of these schemas are relatively generic, containing modeling features applicable to many domains. In our infrastructure, these generic schemas are collectively called xADL 2.0 and are described in Section 4. Other schemas may be more domain-specific such as those described in Section 6.2. Decomposing features into individual schemas is nontrivial and is (we believe) the key contributor to maintaining the flexibility of this infrastructure. Above this language layer is a layer of syntax-oriented tools. These tools leverage the syntax defined in the schemas to automatically ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
206
•
E. M. Dashofy et al.
Fig. 2. Approach overview depicting the relationship between language modules as realized in XML schemas, syntactic tools that work on any schemas, and schema-specific semantic tools.
provide services that are generically useful regardless of the contents of any particular schema—these include parsers, serializers, data bindings, and syntaxdirected editors. The primary advantage of these tools is that they do not need to be changed when new schemas are added to the language layer. Finally, the infrastructure contains a layer of semantic tools. These tools are built to support features of specific schemas in the language layer and generally use the syntax-oriented tools to read and write architecture descriptions. These tools may include visual editors, analysis tools, code generators, and so on. Because these tools are bound to specific schemas and schema features, they may need to be changed when the schemas in the language layer change. This infrastructure promotes a straightforward process for software architecture-based development. First, the architect looks for an ADL (in this case, a composition of schemas) that has already been developed that meets the needs of the current project. If no such ADL exists, then the closest ADL (the one with the most features/modules applicable to the current project) is chosen. Unneeded modules can be removed. Additional features required can come from one of three sources: by reusing modules from other ADLs, by extending existing modules, or by developing new modules if no suitable basis exists. Obviously, reusing or extending existing modules is preferable to developing new ones because of the potential to also reuse the accompanying engineering knowledge and, more importantly, semantic tools that were developed along with the original modules. 4. XADL 2.0: A GENERIC BASE FEATURE SET Architecture description languages must minimally provide methods for describing components, connectors, interfaces, and links. Beyond this core, each ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
207
Fig. 3. xADL 2.0 XML schemas and their relationships.
domain will have unique modeling needs. However, there are some ADL features that are generally applicable and desirable across many diverse domains. We believe that well-designed implementations of these features that are syntactically and semantically compatible with each other and the core constructs are a key part of a successful ADL development infrastructure. Accordingly, we have used XML schemas to define a set of generic constructs that are useful for modeling software architectures across many domains. These constructs can be used as is, or they can be extended to support additional modeling features. Instead of defining all these generic constructs in one large, monolithic XML schema, we have elected to group them in schemas based on their intended purpose. The result is a set of reusable “modules” that together comprise a generic ADL, known as xADL 2.0 [Dashofy et al. 2001]. The current set of xADL 2.0 schemas and their dependency relationships are shown in Figure 31 . Cognizant that these schemas will be used in many domains, we have attempted to keep them as generic as possible. For example, xADL 2.0 defines basic constructs like components and connectors but does not dictate how they must behave or how they can be linked together. These characteristics vary 1 Figure
3 shows the conceptual dependencies between xADL 2.0 schemas. Because the current XML schema standard does not support multiple inheritance of elements, we have occasionally needed to introduce some syntactic dependencies between schemas; however, we have attempted to minimize or eliminate the semantic impact of these artificial dependencies. This is discussed in detail in Section 7.3. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
208
•
E. M. Dashofy et al. Table I. xADL 2.0 Schemas and Features
Purpose Design-time and Run-time Modeling
Schema INSTANCES
STRUCTURE & TYPES
Implementation Mappings
ABSTRACT IMPLEMENTATION
JAVA IMPLEMENTATION
Architecture Evolution VERSIONS Management and Product-Line Architectures OPTIONS VARIANTS
Features Run-time component, connector, interface, and link instances; subarchitectures, general groups. Design-time components, connectors, interfaces, links, subarchitectures, general groups. Placeholder for implementation data on components, connectors, and interfaces. Concrete implementation data for Java components, connectors, and interfaces. Version graphs for component, connector, and interface types. Optional design-time components, connectors, interfaces, and links. Variant design-time component and connector types.
from ADL to ADL so they can be specified in extension schemas. Depending on the situation and the requirements of the model, however, these generic features can be sufficient on their own as is evidenced in our experiences with them (see Section 6). xADL 2.0’s core, generic features are: (1) separation of run-time and design-time models of a software system; (2) implementation mappings that map the ADL specification of an architecture onto executable code; and (3) the ability to model aspects of architectural evolution and product-line architectures. The breakdown of these high-level features into individual schemas is shown in Table I. We discuss each schema in detail in this section. To illustrate how these schemas are applied to describe a software system’s architecture, we will use xADL 2.0 to describe a hypothetical software system for a consumer electronics product. 4.1 Separation of Design-Time and Run-Time Views Traditional ADLs have viewed software architecture as a design-time artifact, focusing their modeling capabilities on the design phase of development. However, research into run-time software evolution and dynamism has shown that it is useful to maintain an architectural model of the system at run-time as well [Oreizy et al. 1999; Schmerl and Garlan 2002]. The design-time and run-time models of a system will be similar but not identical. At design time, a system model may contain basic metadata about elements (author, size, textual descriptions), specification of intended (not observed) behavior, and constraints ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
209
on the arrangements of elements. In contrast, run-time aspects of a system that might be captured in an ADL include the physical distribution of the software system across machines, the process ID in which each component runs, or the current state of a particular connector (e.g., running, processing messages, blocked). Two schemas support the design-time/run-time separation in xADL 2.0. These are called the Structure & Types and INSTANCES schemas, respectively. Both schemas support the following features. — Components: Components are the loci of computation in the architecture. In these schemas, components are defined generically; that is, they have only a unique identifier and a short textual description, along with a set of interfaces (described in the following). — Connectors: Connectors are the loci of communication in the architecture. Similar to components, connectors also have only a unique identifier, a textual description, and a set of interfaces. — Interfaces: Interfaces are components’ and connectors’ portals to the outside world; what we term “interfaces” are also known as “ports” in other ADLs. For example, if a component implements a particular API, it would likely contain an interface indicating that other components can make calls to that API on the target component. In these schemas, interfaces have a unique identifier, a textual description, and a direction (an indicator of whether the interface is provided, required, or both). Specific interface semantics are not specified in xADL 2.0 but in extensions, see Section 6.2 for an example of this. — Links: Links are connections between elements that define the topology of the architecture. In most architecture notations, links connect interfaces, but this constraint is not mandated. — Subarchitectures: Components and connectors may be atomic (not broken down further at the architectural level) or composite. Composite components and connectors have internal architectures, called subarchitectures. — General Groups: Groups are simply collections of pointers to elements in the architecture description. In these schemas, a group has no semantics. Groups with specific meanings (e.g., common authorship, common platform, similar functionality) can be specified in extension schemas. Because the INSTANCES and STRUCTURE & TYPES schemas have definitions for the basic architectural constructs (components, connectors, etc.), they are the core of xADL 2.0. By maintaining definitions of these elements in both schemas, they can be extended separately: the INSTANCES schema should be extended to provide additional run-time data, and the STRUCTURE & TYPES schema should be extended to provide additional design-time data. To provide traceability, XLinks link run-time elements to their design-time counterparts. To see how these schemas can be used to model the core of a software architecture, consider a software system that might be used to drive a low-end television set. Such a device might have only two software components, one to interface with the TV tuner, and one to drive the infrared detector used to pick up signals from the remote control. These two components are connected by a ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
210
•
E. M. Dashofy et al.
Fig. 4. Diagram of an example architecture for a television accompanied by its xADL 2.0 designtime structural description (in abbreviated, non-XML notation).
software connector that allows the infrared receiver component to send signals to the TV tuner to change the channel. A graphical depiction of this architecture, accompanied by its xADL 2.0 description (with ancillary mark up elided) is shown in Figure 4. 4.2 Design-Time Type System Typing is an important construct in most ADLs. xADL 2.0 incorporates the base structures of a typing system that supports type equality and composition. In xADL 2.0, the use of types is optional. Each component, connector, or interface ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
211
can optionally contain an XML link to a type; multiple elements can share a type. The type serves as a construct where common properties of elements can be specified once (in the type) instead of in each element declaration. In the STRUCTURE & TYPES schema, these types consist of a unique identifier and a textual description along with a set of signatures. Signatures are prescribed interfaces; two components or connectors of the same type should have the same types of interfaces. To demonstrate this, we will add types to our television example. We will also add another component to our television, a picture-in-picture tuner. Televisions with picture-in-picture require two tuners to support the display of both channels simultaneously, but since the main tuner and the picture-in- picture tuner are basically identical, they will share a type. The additions to our existing architecture and its description are shown in Figure 5. Types are also used in xADL 2.0 to support design-time subarchitectures (that is, components or connectors that have internal architectures also specified in xADL 2.0). Thus, two components or connectors that share a type also share an internal architecture. Specifically, types can have an optional XLink to another ArchStructure element describing the internal architecture, as well as a set of mappings between signatures on the type and interfaces on components and connectors in the subarchitecture. These mappings serve to link the outer architecture with the inner one. A full xADL 2.0 depiction of subarchitectures is beyond the scope of this paper, but several are available on our websites, see Section 10 for the URLs. Some of our intended semantic constraints for types (for example, that a component’s type link point to a component type or that interfaces match their prescriptions as expressed in signatures) cannot be expressed directly in the XML schemas. However, we have built checking tools and environments that help to guide users into following and maintaining these constraints in their own architectures. These are discussed further in Section 5.2. 4.3 Implementation Mappings A second important feature of xADL 2.0 is its support for mapping designtime architectural elements onto executable code. Several ADLs such as MetaH [Binns et al. 1996] support or require a mapping between an architecture specification and its implementation. This is essential if a software system is to be automatically instantiated from its architecture description and can help to manage the transition from system design to implementation. Since xADL 2.0 is not bound to a particular implementation platform or language, it is impossible to know a priori exactly what kinds of implementations will be used. Obvious possibilities include Java classes and archives, Windows DLLs, UNIX shared libraries, and CORBA components [Object Management Group 2001], but making a comprehensive list is infeasible. To address this, xADL 2.0 adopts a two-level approach. The first level of specification is abstract and defines where implementation data should go in an architecture description but not what the data should be. This indicates to future developers how to extend the xADL 2.0 schemas ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
212
•
E. M. Dashofy et al.
Fig. 5. Diagram for an expanded version of the example television architecture, adding a picture-in picture component, accompanied by additions to our earlier xADL 2.0 description.
to add data for a new implementation platform. The xADL 2.0 ABSTRACT IMschema extends the STRUCTURE & TYPES schema and defines a placeholder for implementation data. This placeholder is present on component, connector, and interface types. As such, two elements of the same type share an implementation. The second level of specification is concrete, defining what the implementation data is for a particular platform or programming language. Concrete implementation schemas extend the ABSTRACT IMPLEMENTATION
PLEMENTATION
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
213
Fig. 6. Expanded description of one of the television component types, adding implementation details.
schema. xADL 2.0 includes a JAVA IMPLEMENTATION schema that concretely defines a mapping from components, connectors, and interface types to Java classes; we are currently working on additional implementation schemas for mapping to source code as well. With this setup, determining the concrete implementation for a given element is straight-forward. For a design-time element like a component or a connector, the user simply follows the element’s type XLink and gets the implementation data from the type. Run-time elements like component instances and connector instances require an additional step, following the XLink from the run-time element to the design-time element, and then following the designtime element’s XLink to its type. We can add implementation data to component and connector types in our television example, as shown in Figure 6. Here, we show that the television tuner component is implemented by two Java classes residing in the same JAR archive. The main class takes an initialization parameter of the television’s model, which is useful if the component’s implementation is multipurpose or reusable in multiple contexts (e.g., for many television models). 4.4 Modeling Architecture Evolution and Product Lines Many first-generation ADLs focused on modeling the architecture of a single software system or product. This is inadequate for two reasons. First, ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
214
•
E. M. Dashofy et al.
architectures evolve over time. As a product evolves, so does its architecture. Second, software products are often part of a larger product line. A product line is a family of related software products that share significant portions of their architectures with specific points of variation [Bosch 1999; Ommering 2002; Tracz and Coglianese 1993]. A single product line may contain products that are localized for specific regions or represent different feature sets for marketing purposes (e.g., Standard, Professional, Enterprise). From a modeling perspective, both architectural evolution and product lines can be addressed by applying traditional concepts from configuration management to software architectures. Inspired by previous research in modeling architectural product lines [Bosch 2000; Clements and Northrop 2001; Ommering et al. 2000], xADL 2.0 integrates these concepts in the form of three schemas: the VERSIONS, OPTIONS, and VARIANTS schemas. Versions record information about the evolution of architectures and elements like components, connectors, and interfaces. Options indicate points of variation in an architecture where the structure may vary by the inclusion or exclusion of a group of elements (components, connectors, links, and so on). Variants indicate points in an architecture where one of several alternatives may be substituted for an element or group of elements. We developed these three schemas to be compatible such that modelers can choose to use only the VERSIONS, OPTIONS, or VARIANTS schema, or any combination of the three. 4.4.1 Versions. The VERSIONS schema adds versioning constructs to xADL 2.0. It defines version graphs for component, connector, and interface types. In xADL 2.0, architecture element types are the versioned entities. The decision to version types rather than elements such as components and connectors was made because we feel that it best matches the semantics of the type system. For example, by versioning types, it is possible to have multiple instances of the same version of a component, connector, or interface by simply creating multiple instances of a type. Different versions of a component, connector, or interface can coexist in an architecture as well simply by creating instances of type that share a version tree. We believe this makes sense because, as architectures evolve, newer versions of element (types) may have different characteristics than older versions (e.g., additional signatures). The relationship between concrete elements (e.g., components), their types, and version graphs is depicted in Figure 7. Here, the TV Tuner Type and the HDTV Tuner Type share a common lineage. The HDTV Tuner Type is a later version of the TV Tuner Type, but both versions may be included in the same architecture if necessary. In this example, the version graph describes the evolution of a single element. However, using the type-based subarchitecture mechanism defined in the STRUCTURE & TYPES schema, a version graph can capture the evolution of groups of elements or whole architectures. This is another reason why we chose to version types. In keeping with the generic nature of xADL 2.0 schemas, version graphs do not constrain the relationship between different versions of individual elements, for instance, that they must share some behavioral characteristics or ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
215
Fig. 7. Relationships between concrete elements, their types, and version graphs.
interfaces. Such constraints may be specified in extension schemas and checked with external tools. 4.4.2 Options. The OPTIONS schema allows design-time components, connectors, and links to be labeled as optional in an architecture. Optional elements are accompanied by a “guard condition” whose format can be specified in an extension. xADL 2.0 provides a default schema for guards, the BOOLEAN GUARD schema, that allows guards to be specified as Boolean expressions similar to those found in modern programming languages. If the guard condition is satisfied when evaluated, then the optional element is included in the architecture; otherwise it is excluded. In our television example, we may wish to turn our single product architecture into a product line by adding optionality. By making the picture-in-picture tuner optional along with its link to the TV connector, we can create a product line that describes two products: a television with picture-in-picture and a television without it. The changes that we must make to our existing product description are shown in Figure 8. Here, we add an element to both the picture-in-picture tuner and its link to the connector. The guard condition for both elements is hasP in P == true, so these elements will only be included in the architecture if the target product has picture-in-picture (i.e., the variable hasP in P is bound to the value true). Variable-value bindings are established in a selector tool, see Section 5.2.3. Note that it is possible to express architectures with guards that could result in incomplete or incorrect architectures (e.g., if the link’s guard in the example ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
216
•
E. M. Dashofy et al.
Fig. 8. Diagram for a television product-line where the picture-in-picture elements are optional, accompanied by xADL 2.0 description.
above were missing or different than the guard on the P-in-P tuner). When the product line is sculpted down to a single product via use of our selector tool, these inconsistencies will become apparent and many of them (such as a dangling link) will be caught by our design critics (see Section 5.2.1). 4.4.3 Variants. The VARIANTS schema allows the types of certain designtime constructs to vary in an architecture. In particular, it defines variant component and connector types. Variant types contain a set of possible alternatives. Each alternative is a component or connector type accompanied by a guard condition, similar to the one used in the OPTIONS schema. Guards for variants must be mutually exclusive. When a guard condition is met, its associated component or connector type is used in place of the variant type. Let us diversify our television product line more by expanding it to multiple international markets. Televisions distributed to North America or Japan will need NTSC tuners, while televisions distributed to most of Europe will need PAL tuners. We can express this by replacing the existing tuner type with a variant type that links to two possible concrete types: an NTSC tuner type and a PAL tuner type. This is shown in Figure 9. In this example, the structural description of the architecture does not change at all: both the main and picturein-picture tuners retain the link to the same type (tuner type). Now, however, their type has become variant: they may be an NTSC or PAL tuner, depending on the situation. 5. TOOL SUPPORT An ADL’s usefulness is closely tied to the amount of tool support available for that ADL. Tools are needed to create architecture descriptions, to edit them, to analyze them, to map them to system implementations, and so on. Tools can ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
217
Fig. 9. Expansion of a formerly concrete type (tuner type) into a variant type.
also help to insulate the architect from unpleasant syntactic details (such as XML mark up and namespaces). We partition the tools available in our infrastructure into two groups: syntaxbased and semantics-based tools. Syntax-based tools are generic, and their interfaces (graphical, textual, or programmatic) are based on the syntax of the ADL as specified in XML schemas. Because ADLs created in our infrastructure are extensible and easy to change, syntax-based tools are important since they adapt themselves as the language evolves and changes. Semantic-based tools make some assumptions about the meanings of particular constructs in the constructed ADLs and may require or support the use of specific schemas. These tools provide additional value for users of our infrastructure who adopt some or all of the xADL 2.0 schemas and for whom the semantic assumptions are valid. The relationships among the tools in our infrastructure are depicted in Figure 10. Each tool in our infrastructure is described in this section. 5.1 Syntax-Based Tools One of the advantages of using XML is its support of off-the-shelf syntax- based tools for manipulating documents and schemas. Additionally, we have leveraged ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
218
•
E. M. Dashofy et al.
Fig. 10. Relationships among tools in our infrastructure.
these off-the-shelf tools to create additional syntax-based tools specific to our infrastructure. 5.1.1 Off-the-Shelf XML Tools: Sun’s Crimson Parser, XSV, and XML Spy. Because ADLs created in our infrastructure are defined in XML schemas, and because architecture descriptions are XML documents that conform to these schemas, many off-the-shelf tools for working with XML in general are available to users. Three such tools are particularly important as they form the basis for all our other tools. Sun’s Crimson parser [Apache Group 2003] is a Java implementation of the DOM [Le Hors et al. 2003] and SAX [SAX Project 2003] APIs for parsing and manipulating XML documents. Crimson provides the ability to programmatically access the structures in XML documents (both architecture descriptions and schemas) at the level of XML syntactic constructs (elements, tags, attributes, comments, etc.) This API forms the foundation for more powerful syntax-based tools as will be described later in this section. XSV [Thompson and Tobin 2003] is an open-source XML schema and instance document validator. It provides two main functions: to verify the syntactic correctness of XML schemas that are part of an ADL and to verify that an architecture description conforms to a set of schemas. While XSV cannot ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
219
verify complex architectural properties such as type consistency, it can provide some rudimentary syntactic checking of consistency at the level of XML constructs. Altova’s XML Spy [Altova GmbH 2003] is a commercial development environment for XML. XML Spy can be used to design and validate new schemas. Most importantly, it provides a way of exploring and designing schema constructs graphically which is a valuable tool for schema designers to inspect and communicate the modeling features in their schemas without having to read the raw schemas. The reuse of off-the-shelf XML tools is a subtle but important benefit to our approach. While these tools do not work at the level of architectural constructs (e.g., components and connectors), they do allow us to avoid mundane tasks such as the creation of parsers, serializers, syntax checkers, graphical schema editors, and so on. Our approach also benefits automatically from improvements in these technologies: performance improvements in the underlying DOM implementation translate into faster applications. 5.1.2 Data Binding Library. Off-the-shelf XML tools tend to support manipulation of documents in terms of low-level XML concepts like elements, attributes, and text segments. Building tools that work with these low-level constructs directly is cumbersome and error prone as it requires the tools themselves to manage elements like namespaces directly and to ensure that documents conform to XML schemas. When schemas are available, a more friendly programmatic interface to XML documents can be created based on the language prescribed by the schemas. In our infrastructure, this interface is provided through a data binding library [Sun Microsystems 2003a]. Our data binding library provides a set of Java classes corresponding to elements and attributes specified in the xADL 2.0 schemas. These classes hide XML details such as namespaces, header tags, sequence ordering, and so forth. Whereas a generic XML API like DOM exposes functions like addElement(...) and getChildElements(...), classes in our data binding library expose functions like addComponentInstance(...) and getAllInterfaces(...). Internally, the library uses the DOM implementation provided with Crimson to manipulate the underlying XML document. The Data Binding Library is automatically generated by another tool in our infrastructure, Apigen, described in the next section. Consider the following XML definition of a component, excerpted from the xADL 2.0 STRUCTURE & TYPES Schema:
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
220
•
E. M. Dashofy et al.
For this type, the data binding library includes a Java class that exposes the following interface: void void IDescription void void void IInterface Collection Collection void void void IXMLLink void String void
setDescription(IDescription value); clearDescription(); getDescription(); addInterface(IInterface newInterface); addInterfaces(Collection interfaces); clearInterfaces(); getInterface(String id); getInterfaces(Collection ids); getAllInterfaces(); removeInterface(IInterface interface); setType(IXMLLink link); clearType(); getType(); setId(String id); getId(); clearId();
This demonstrates that, despite having no knowledge of the semantics of the ADL, the data binding library exposes functions that are closer (in terms of their level of abstraction) to the concepts relevant to a software architect. This makes building architecture tools with the data binding library more intuitive than building them with an XML tool like Crimson. Furthermore, it reduces the number of lines of code necessary to manipulate an XML-based architecture description significantly, by a ratio of approximately 5:1. That is, each call to the data binding library (e.g., addInterface) encapsulates about 5 lines of DOM code. 5.1.3 Apigen. If the data binding library must be rewritten every time a schema is added to, changed, or removed from an ADL, then the benefit of having it is negated. Fortunately, the syntax information present in the ADL schemas is enough to generate the data binding library automatically. We built a tool called “Apigen” (short for API generator) [Dashofy 2001] that can automatically generate the Java data binding library, described previously, for xADL 2.0 and extension schemas.2 When an ADL’s schemas are changed, tool builders simply rerun Apigen over the modified set of schemas to generate a new data binding library. Of course, bindings for elements that did not change will remain the same, minimizing the impact on existing tools that use the library. Because of the complexity of the XML schema language, Apigen is not a generic data binding generator it does not support the full gamut of constructs available in XML schemas (to our knowledge, no XML schema binding 2 When
we built Apigen, no adequate data binding generator existed that supported XML scemas. Several promising alternatives have since emerged’ (e.g., Sun Microsystems’ JAXB [Sun Microsystems 2003a] and XML Spy 5’s proprietary generator [Altova GmbH 2003]). ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
221
Fig. 11. Example of a data binding library call and an equivalent xArchADT message.
generator currently does). However, it supports a large set of schema features and so far has been sufficient to generate data bindings for all the xADL 2.0 schemas as well as schemas written by third parties. A comprehensive list of supported and nonsupported constructs in Apigen is beyond the scope of this article but is included with the Apigen tool’s documentation. 5.1.4 xArchADT. The data binding library provides a traditional objectoriented interface to edit architecture descriptions. This requires the library’s callers to maintain many direct object references. In general, distributed and event-based systems assume that components do not share an address space and, therefore, cannot maintain object references across components. Because of this, using such a library as an independent component in a distributed or event-based system is difficult. To address this, we have built a wrapper, called “xArchADT,” for the data binding library that provides an event-based interface instead of an object-oriented one. Instead of procedure calls, xArchADT is accessed via asynchronous events. An example of how a data binding library call is expressed as an event data structure is shown in Figure 11. It uses firstclass indirect object references rather than direct pointers to refer to elements in xADL 2.0 documents. That is, xArchADT assigns identifiers to xADL 2.0 elements, and those identifiers are used to refer to the elements. When the underlying architecture description is modified by one tool, xArchADT emits an event, informing all listening tools of the change. This gives the data binding library the added property of loose coupling. xArchADT, like Apigen and the data binding library, is reflective. It uses Java’s built-in reflection capabilities to adapt to changes in the data binding library automatically. That is, if the library is regenerated by Apigen, xArchADT will work without modification. xArchADT’s biggest contribution to our tool suite, however, is that it increases the range of contexts in which the data binding library can be used. The library alone is well-suited for use in tightlycoupled object-oriented system development, but the xArchADT wrapper gives it an interface suitable for remote access across process boundaries (facilitated by middleware) and inclusion in an event-based environment. 5.1.5 ArchEdit. The data binding library and xArchADT expose different programmatic interfaces for manipulating architecture descriptions. Our ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
222
•
E. M. Dashofy et al.
Fig. 12. ArchEdit Screenshot.
infrastructure also includes a syntax-driven tool with a graphical user interface called “ArchEdit”. A screenshot of this tool is shown in Figure 12. ArchEdit depicts an architecture description graphically in a tree format, where each node can be expanded, collapsed, or edited. This is similar to many visual XML editors except ArchEdit hides the XML details of the document from the user. The ADL’s XML schemas direct the structure of the displayed tree view, making the structure of the XML document and the structure of the displayed tree identical. This gives architects direct access to architecture descriptions without abstracting away details. ArchEdit is an event-based software component and accesses architecture descriptions through xArchADT. Changes to the architecture description made via xArchADT by ArchEdit or other tools are immediately reflected in the ArchEdit user interface. ArchEdit is another reflective tool in our infrastructure. ArchEdit is syntaxdriven: it does not understand the semantics of the displayed elements. It builds its view and interface dynamically from the XML schemas used to define the ADL. Therefore, it does not need to be modified when schemas are added, modified, or removed. This flexibility is valuable because it gives architects a simple graphical editor for ADL documents automatically even if the new ADL features have recently been added. There are two disadvantages to ArchEdit’s reflectiveness. First, it does not enforce stylistic constraints or other rules on the architecture description that cannot be specified in XML. Second, ArchEdit cannot display the structure of the software architecture in an intuitive way—as a box-and-arrow diagram, for instance. These disadvantages are inherent in any syntax-based tool, but the benefits of having a free editor for new ADL features outweighs these disadvantages. More semantically-aware editors can be built to augment ArchEdit and integrated using xArchADT as we will show in the next section. 5.2 Semantics-Based Tools Semantics-based tools differ from syntax-based tools in that they carry with them some notion of the semantics of the underlying notation. This necessarily ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
223
means that the use of certain semantics-based tools will be predicated on the inclusion of certain specific XML schemas in their target ADLs, as well as some assumptions about semantics associated with those schemas. Unlike syntax-based tools, semantics-based tools cannot necessarily update their interfaces and behavior automatically to support new schemas. This makes extensibility a paramount concern when developing new semantics-based tools. We have, therefore, endeavored to make our existing tools as tolerant of new schemas as possible, for example, by ignoring unknown information rather than failing. In this section, we will profile three mature semantic tools that we developed for our infrastructure: the critics framework, used for developing and integrating analysis components; M´enage, a graphical editor for architecture descriptions; and the Selector, a tool for sculpting product lines down to smaller product lines or individual products. Additionally, we will provide a brief overview at the end of the section of current, in-progress projects we are undertaking to build more semantic tools. 5.2.1 Critics Framework. Consistency checking and analysis tools are important parts of any ADL’s tool suite. In fact, many other ADLs were constructed specifically for the purpose of experimenting with new analysis techniques. In an extensible ADL, a single analysis tool is impractical. Having a modular critic framework [Robbins and Redmiles 1998] is a preferable alternative. Critics are software components that check properties of architecture descriptions, identify faults and potential flaws, and report them to other components. Critics differ from traditional analysis tools because they can update their analysis as the document changes, allowing continual revalidation to occur. The architecture of the critics framework, expressed in the C2 architectural style [Taylor et al. 1996], is shown in Figure 13. In the C2 style, components can make requests of components above them, but are not allowed to make assumptions about the components below them. As such, events requesting service are emitted upwards, and state changes are emitted downwards. For example, whenever the CriticADT’s internal data store of open issues changes, it emits a notification to all components below it. Design critics are independent components that can be included in the framework and activated if their analysis is relevant to the underlying ADL. Critics in our framework either perform fine-grained analysis, checking only a single property or a set of related properties, or build upon other critics to perform more complex analyses. For example, the Link Critic checks that all link endpoints are anchored on interfaces, while the Architecture Evolution Manager critic uses the Link Critic (and others) to decide whether the architecture description is complete enough to instantiate the specified system. The CriticManager allows users to choose which critics to activate and deactivate, and several artist and GUI components render open issues for examination by end users. Users can use GUI elements (in our current framework, a “Focus Open Editors” button) to notify open architecture editors to focus on the particular element(s) that are involved in an issue. Screenshots of sample ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
224
•
E. M. Dashofy et al.
Fig. 13. Architecture of critics framework.
outputs from these critics and their visualization in the critic manager are shown in Figure 14. Our framework includes a growing set of critics for basic consistency checking of xADL 2.0 documents. Current critics in our framework are listed in Table II. The particular set of critics we have constructed to date check some of the most common errors that can occur when defining a xADL 2.0 architecture. While our focus thus far has been on the creation of the framework, we intend to use this as a jumping-off point for future investigation of techniques for building and composing critics, for example, leveraging off-the-shelf XML-based analysis tools like xlinkit [Nentwich et al. 2002]. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
225
Fig. 14. Screenshots of critic manager and critic issues.
5.2.2 M´enage. M´enage [Garg et al. 2003] is a graphical design environment for single-product and product-line architectures. M´enage requires its target ADL to include the STRUCTURE & TYPES, VERSIONS, OPTIONS, VARIANTS, and BOOLEAN GUARD schemas from xADL 2.0. M´enage allows architectures to be visualized and expressed in a graph structure. Optional and variant constructs are depicted distinctively. Optional constructs have a dotted border. Variant components and connectors are tagged as variants; double-clicking on a variant element shows the set of possible variants. Each variant or optional element is associated with an editable Boolean guard condition to determine whether it is included in the architecture or not. A screenshot of M´enage is shown in Figure 15. M´enage works well in combination with ArchEdit and our other syntaxdirected tools. Architecture descriptions created in M´enage can be finetuned in ArchEdit if necessary, or ArchEdit can be used to access schema elements not supported directly by M´enage. 5.2.3 Architecture Selector. A product-line architecture represents a set of possible product architectures. As design parameters become fixed, the number of points of variation in a product-line architecture are reduced. When all points of variation have been removed, the result is a single product. Our infrastructure includes a tool called the “Selector” that allows the reduction of a product line to be done automatically for product-line architecture descriptions that use the STRUCTURE & TYPES, OPTIONS, VARIANTS, and BOOLEAN GUARD schemas. Recall that each optional or variant element is accompanied by a Boolean guard expression that defines when it is included in the architecture. This ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
226
•
E. M. Dashofy et al. Table II. Critics and Their Descriptions
Critic
Description
Checks validity of ArchStructure elements. Checks validity of Java implementation annotations on component, connector, and interface types. Link Critic Checks validity of architectural links—that they have two valid endpoints, etc. Type Link Critic Checks to ensure that each component, connector, and interface has a valid link to a type. XML Link Critic Checks that XML links found in architecture descriptions are valid. Version Graph Critic Checks that all component, connector, and interface types have valid links to a node in an appropriate version graph. Signature Critic Checks that components and connectors have the correct number and types of interfaces as specified by their types’ signatures. Guard Critic Checks that all optional and variant elements are accompanied by a guard. Signature-Interface Mapping Critic Checks that components and connectors with sub-architectures are properly connected to internal components and connectors. Interface Direction Critic Checks that the directions of connected interfaces are compatible (‘in’ interfaces connect only to ‘out’ interfaces, etc.) Variant Type Critic Checks that all possible variants are consistent with their variant type. Floating Elements Critic Checks for components and connectors not connected to the rest of the architecture. Duplicates Critic Checks for elements with duplicate identifiers. Architecture Evolution Manager Critic Determines whether the architecture description contains enough information for it to be instantiated. ArchStructure Critic Java Implementation Critic
Boolean expression includes variables, just as Boolean expressions do in a programming language, but these variables are not bound to values in the architecture description. The Selector tool presents users with a graphical user interface in which they can specify a set of values that will be bound to variables in the Boolean expressions in the product-line architecture. Then, the user clicks a button to start the selection process. The selector evaluates all Boolean guards for optional and variant elements in the architecture using variable values provided by the user. For expressions that can be resolved, optional components are either made permanent (included) or removed (excluded) and chosen variants are made permanent. For expressions that cannot be fully resolved (due to an unbound variable, for example), the expression is reduced as far as possible, and the element remains optional or variant. When all options and variants have been resolved, the result is a single product architecture. If some options and variants remain, the result is a subset of the original product line. 5.2.4 Additional Projects. In addition to those listed in this section, we are constantly developing new semantic tools to augment our framework and ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
227
Fig. 15. M´enage screenshot.
provide more comprehensive support for the xADL 2.0 schemas. These projects are in various states of development, and more information on all of them can be found on our websites (see Section 10). A partial list follows: Architecture Differencing and Merging. Tools to automatically generate documents describing the difference between two architectures, and merge the difference documents into existing architectures [Westhuizen and Hoek 2002]. This is useful for evolution management and feature propagation. Product-Line Differencing and Merging. The application of differencing and merging techniques to product-line members, allowing differencing of individual members of a product line and propagation of features from one member product to another. Eclipse Integration. An effort to provide and maintain mappings from xADL 2.0 components to their source-code implementations in the Eclipse [Eclipse Foundation 2004] Java development environment. Archipelago. A second-generation graphical xADL 2.0 editor focusing on supporting exploratory design and new user-interface metaphors for architecture design. Archipelago is built on a highly-flexible plug-in framework that makes it a good fit with an extensible language infrastructure. Type Wrangler. A tool to assist users in making sure components and connectors are matched properly to their types (e.g. interfaces match signatures, interface types are consistent, and so on). ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
228
•
E. M. Dashofy et al.
6. EXPERIENCES Our infrastructure has been applied to problems in a number of domains. In this section, we highlight four experiences that each demonstrate a different strength of the infrastructure. First, we show how our infrastructure supported the modeling and simulation of the architecture of a large military system, demonstrating the scalability of the infrastructure. Second, we show how our infrastructure supported the development of an ADL now used in architectural modeling experiments for spacecraft systems, demonstrating the adaptability of the infrastructure to new architectural domains with unique modeling requirements. Third, we show how our infrastructure supported the development of ADLs for Koala and Mae, two representations used to model product-line architectures, demonstrating the extensibility of the XML schemas and tools in our infrastructure. Finally, we show how the infrastructure has been used to develop its own software development environment—demonstrating its ability to describe and support itself. Two of these examples demonstrate how the xADL 2.0 schemas can already support architecture-based development on their own, and two of them describe experiences where a new ADL was created in our infrastructure, leveraging our base schemas and tools. Overall, these experiences demonstrate how the different aspects of our infrastructure (XML-based extensibility, a base set of schemas, and flexible tool support) contribute to its effective use. 6.1 AWACS The U.S. Airborne Warning and Control System (AWACS) aircraft [Air Combat Command Public Affairs Office 2000] is supported by a large, distributed message-passing software architecture [Milligan 2000]. However, no formal architectural model of this software exists. To remedy this, and to help evaluate the scalability of our infrastructure, we modeled the architecture of the AWACS aircraft’s software systems in xADL 2.0 and used this model as the basis for an architecture-based simulation of AWACS. The model of AWACS was created based on available documentation and a proprietary simulator of AWACS component behavior provided to us by an industrial partner. The AWACS description consists of more than 10,000 lines (almost one megabyte) of XML. The AWACS description describes 125 components and 206 connectors, distributed across 28 processors, along with component, connector, and interface types. The description was validated against the xADL 2.0 schemas using XSV and visualized with ArchEdit. We used ArchEdit to inspect the architecture and make further improvements until the model was accurate and ran critics against the architecture to verify various aspects of it. The various tools we used were relatively efficient given AWACS’ large size. XSV can analyze an XML document of AWACS’s size in a few seconds. ArchEdit amortizes the amount of time it takes to visualize an architecture by only reading data from the DOM tree when it is viewed; expanding the most populous node in the AWACS description for the first time takes about 5–8 seconds on a state-of-the-art PC. The performance of critics largely depended on how much data the critics were required to analyze. Critics that check a large portion of ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
229
Fig. 16. AWACS simulator screenshot.
the architecture (for example, the Link Critic) took about 2 seconds to check AWACS on the PC. We believe that these times are reasonable given the size of the architecture being checked. Along with the initial architecture description, we developed an architecturebased simulation of the communication among the components on the aircraft. The simulator consists of implementations of each component and connector type in the architecture in Java. Implementation mappings between types in the architecture description and these Java classes were added to the architecture description. A bootstrapping program reads the architecture description into xArchADT and instantiates and links the components and connectors automatically. To visualize the simulation, a separate project created an extension to Microsoft Visio that can render a xADL 2.0 architecture as a graph of components, connectors, and links [Ren and Taylor 2003]. Messages sent among AWACS components and connectors are animated on this graph. A screenshot of this simulator is shown in Figure 16. Beyond scalability, our experience with AWACS demonstrates several additional positive characteristics of our infrastructure. First, it shows that our base schemas have effective modeling capabilities by themselves as no extensions were needed to model the AWACS architecture. Second, it shows the flexibility of the infrastructure’s tool support as we were able to use xArchADT (and, by ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
230
•
E. M. Dashofy et al.
extension, our data binding library) to create the architecture description and use it as the basis for our simulator. Finally, it shows the value of the COTS and user-interface based tools in our infrastructure as we were able to use XSV to validate our description and ArchEdit to refine it. 6.2 JPL As a demonstration of the adaptability of the infrastructure to a new domain with its own unique architectural requirements, we describe our experience with NASA’s Jet Propulsion Laboratory (JPL). JPL develops software systems for space probes and ground systems. This domain induces unique modeling needs; specifically, these architectures are modeled as state-based systems. To accommodate these modeling constraints, JPL’s Mission Data Systems group [Rouquette and Reinholtz 2002] and their research partners at the University of Southern California (USC) created extensions to xADL 2.0 [Roshandel et al. 2004]. While the specific contents of these schemas cannot be shared due to their proprietary and confidential nature, they are roughly characterized as follows: Static Behavior Schema. This schema extends the core xADL 2.0 schemas to capture static behavioral properties of the system. These behaviors add preconditions, postconditions, and invariants to xADL 2.0 component types, using a set of variables also defined in the extension. Additionally, xADL 2.0 signatures are extended with input and output parameters, allowing them to specify programming-language-like functions. MDS Types Schema. This schema extends the static behavior schema to capture namespaces and complex inheritance information for components. MDS Implementation Schema. This schema links architectural artifacts to implementation-level counterparts as expressed in the JPL-proprietary MDS framework. It is used primarily for code generation. JPL integrated their extended version of xADL 2.0 into their development process by creating translators to and from existing notations such as UML and proprietary text-based notations. They also adopted our tools to visualize and manipulate architecture descriptions. Additionally, researchers at USC used the extended version of xADL 2.0 to model the architecture of the SCrover, a mobile robot based on JPL’s MDS framework. They modified an existing architecture analysis tool, DRADEL [Medvidovic et al. 1999], to use JPL-extended xADL descriptions rather than its own proprietary models and used DRADEL to analyze the SCrover architecture. The DRADEL analysis found 21 errors in the SCrover architecture, 6 of which were not also detected by a peer review process. The ultimate aim of these efforts is to use xADL 2.0 as part of a largescale effort to foster model-driven code generation. Additionally, the success of this effort recently prompted JPL to enter into a second project leveraging our infrastructure, this time focusing on space mission modeling and systems architecture. This experience verifies that our infrastructure’s genericity and its extensibility mechanisms are useful in previously unexplored domains, especially with regard to the xADL 2.0 base schemas. JPL was able to reuse the xADL 2.0 ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
231
base schemas, creating relatively small new schemas to model domain-specific details of spacecraft software. JPL’s use of Apigen and the associated data binding library to manipulate architecture descriptions further shows the value of our infrastructure’s tool support. Finally, their mapping of architecture descriptions to other representations shows the adaptability of our approach to other, nonpreplanned situations. 6.3 Mappings to Koala and Mae To demonstrate our infrastructure’s ability to capture concepts from an emerging research area and add tool support for those concepts efficiently, we created schemas that add the unique modeling constructs of Koala and Mae to our base xADL 2.0 schemas. Koala [Ommering et al. 2000] and Mae [Hoek et al. 2001] are two representation formats for capturing product-line architectures. As described earlier in Section 4.4, the xADL 2.0 schemas already provide basic support for product-line architectures with the VERSIONS, OPTIONS, and VARIANTS schemas. However, both Koala and Mae have unique modeling characteristics that differ from those in the xADL 2.0 schemas and from each other. There are several differences between Koala and xADL 2.0. First, Koala does not support the notion of explicit connectors or versioning. Next, Koala has two constructs not present in xADL 2.0: diversity interfaces and switches. A diversity interface, representing a point of variation in an architecture, is required to be present on variant components and must be an “out” interface. A switch is an explicit construct applied at a variation point that creates the connection to the variant component that will be used. The Mae representation is somewhat closer to xADL 2.0. Two key differences exist between xADL 2.0 and Mae. First, component types in Mae are augmented with a string describing their architectural style. Second, component types in Mae also have a subtype relation and a reference to their supertype. We addressed these differences by extending the definition of a component type with a new schema. xADL 2.0’s flexibility at the level of individual elements was useful several times. For instance, Koala lacks support for explicit connectors, so we simply excluded connectors from our ADL since xADL 2.0 does not require them, demonstrating the modularity of the xADL 2.0 schemas at the level of individual elements. When new constructs were required, like Koala’s diversity interfaces and Mae’s subtypes, we created simple schemas that added these entities to xADL 2.0. This experience further demonstrates the effectiveness of the XML-based extensibility mechanism we have chosen for our infrastructure. Consider the schema shown in Figure 17 used to add Koala-style diversity interfaces to xADL 2.0. This schema subtypes the definition of an interface to create a diversity interface and extends the definition of a component to add such an interface. Note the relative simplicity of this schema; other schemas, shown in full in [Dashofy and Hoek 2001], are also simple and straightforward. For the Koala and Mae mappings, we successfully exercised the full gamut of XML schema-based extensibility techniques (creation of new elements, extension of existing elements, restriction of elements, etc.) This experience also ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
232
•
E. M. Dashofy et al.
Fig. 17. xADL 2.0 extension schema for Koala-style diversity interfaces.
reinforces the effectiveness of the infrastructure tools. We used XML Spy to verify and create our extension schemas and Apigen to create a new data binding library that supports them. ArchEdit was able to support these schemas automatically. As such, after writing the short extension schemas required to map Koala and Mae into our infrastructure, our tools provided parsing, syntax checking, and GUI editing abilities automatically. 6.4 ArchStudio 3 Finally, we have used our infrastructure to support its own development and evolution. As discussed above, our infrastructure includes a number of interacting tools that manipulate, analyze, and otherwise work with architecture descriptions. Most of these tools rely on a basic set of services for interacting with architecture descriptions (parse, read, modify, save) that are provided by the xArchADT component. Some tools rely on the services provided by other tools; for example, M´enage relies on design critics to perform consistency checking of architecture descriptions before it manipulates them. We have created ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
233
an architecture-based development environment called ArchStudio 3 that integrates most of our tools as components [Institute for Software Research]. Like the AWACS simulator, ArchStudio’s architecture is described in xADL 2.0. ArchStudio’s bootstrapper reads the xADL 2.0 description of ArchStudio and instantiates and connects all the components and connectors. ArchStudio 3’s toolset currently includes xArchADT, the critics framework (and all critics), ArchEdit, M´enage, Selector, and many other tools. It is comprised of approximately 80,000 lines of Java code, not including code generated by Apigen. Our experience in building, maintaining, and evolving ArchStudio 3 demonstrates that our infrastructure can support a nontrivial product’s development and design and is capable of describing and supporting itself. 7. LESSONS LEARNED In building and evolving our infrastructure, we learned several important lessons about modular architecture description language development, both in general and in the specific context of our XML-based infrastructure. 7.1 Guidance for Developing Modular ADL Features As we have stated, our infrastructure does not attempt to automatically resolve the feature interaction problem [Zave 1999] in ADL development. That is, it does not provide tool support for ensuring semantic compatibility among ADL features. Nonetheless, in an infrastructure such as ours, feature interactions must be resolved in creating new ADL modules. We gained significant experience in solving feature interactions and preventing future difficulties when we developed the xADL 2.0 schemas and worked with our partners to extend the language further for specific domains. Our insights about developing new ADL features, some of which reflects conventional wisdom, are summarized here. Separate core concepts from details. In developing ADL modules, concepts are more important than the specific implementation of those concepts. For example, our ABSTRACT IMPLEMENTATION schema captures the concept of an implementation mapping and indicates where such data should go but does not specify the details of what data should be included. Concrete schemas like the JAVA IMPLEMENTATION schema perform that function. Similarly, the STRUCTURE & TYPES schema defines the core architecture elements (components, connectors, interfaces, and links) but leaves out details to be specified in extensions. Keep the dependency tree shallow. Every time a semantic dependency is introduced between schemas, it means that adopters of the dependent schemas must also implicitly adopt the parent schemas. Sometimes this is desirable: the xADL 2.0 type system provides a convenient place to specify variants. However, by maintaining compatibility without dependencies among the OPTIONS, VARIANTS, and VERSIONS schemas, we ease the adoption of these schemas individually. Build domain-specific features atop generic ones. Each additional schema must be carefully compared semantically with all other schemas in the target ADL to determine compatibility. To maximize reusability of schemas, it is better to build and incorporate domain-generic schemas (schemas whose features are useful across many domains) first, and then build domain-specific schemas. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
234
•
E. M. Dashofy et al.
For example, we built features like product-line support and implementation mappings into xADL 2.0 first. Because the domain-generic schemas are not dependent on domain-specific ones, they can be more easily ported to other projects or ADLs because they will not require the porting or adoption of more specific schemas. Eliminate redundancy where possible. Data that must be specified or copied in multiple places puts an undue burden on the tools that support the ADL to maintain consistency between the copies. Eliminating or minimizing redundancy can reduce this burden. In the xADL 2.0 schemas, types are provided as a way to keep common data about similar components, connectors, and interfaces in a single place. Use first-class data elements instead of decorating existing elements. While it is natural to extend the definition of existing elements with additional data, it is often better in terms of extensibility to model the data as a set of firstclass entities and provide links from the existing elements to the data. For example, rather than including version data and links among related versions inside component and connector types, we instead created first-class version trees and linked types to nodes in the tree. This allows for partial specifications (indicating that a version exists without necessarily having a fully-defined type to represent it). This also helps to disentangle version data and information from other elements that do decorate types such as information about variants. Finally, using first class elements allows many entities to link to the same information, helping to minimize redundancy. Beyond these general guidelines, it is difficult to offer insight into the best way to integrate any given new feature. In the end, only experience can bear out whether a particular feature was integrated well or poorly. For example, we believe that our modularization of xADL 2.0 is a relatively good and manageable separation of concerns. We cannot credibly assert that our breakdown of features is best, or that there is no refactoring of the schemas that would lead to a more elegant, extensible, or modular notation. Nonetheless, our experiences using the notation increase our confidence that our modularization is an effective one. Our infrastructure offers some means to alleviate this difficulty. First, it encourages experimentation with new refactorings and changes to existing notations more easily than a monolithic language would. So, while it cannot guide users in how to best integrate a new feature, it can at least help them to experiment with different alternatives. Second, it encourages the dissemination and reuse of existing feature integrations as we have done with xADL 2.0. xADL 2.0 carries with it the engineering knowledge and experiences we (and others) have had in integrating many useful features; the ability to reuse this particular well-worn modularization of features is far preferable to reinventing it. 7.2 The Usefulness of Syntax-Based and Other Reflective Tools In the continual development of an extensible language, or any language that changes over time, the importance of reflective and syntax-based tools cannot be underestimated. Experience has shown that, in the absence of a reasonable ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
235
method to extend a language and its tool support, extensions will usually appear in the form of hacks [Luckham et al. 1987; Sun Microsystems 2003b]. For programming languages, extensions usually come in the form of speciallyformatted comments, misusing this feature of the language simply because it is ignored by existing language tools like compilers and environments. For other design notations such as UML [Booch et al. 1998], existing concepts are overloaded to support new features to avoid extending the language definition and tools. Sometimes, when new features are too different from an existing language to be integrated, users will attempt to use multiple notations in tandem, or worse, develop an entirely new, competing notation. Reflective tools allow language elements to be extended and new first-class elements to be added to a language without resorting to hacks or excessive overloading. Our experiences with our infrastructure, described in Section 6, have demonstrated that the availability of syntax-based and reflective tools like Apigen, xArchADT, and ArchEdit help make extending an existing notation and its tools tolerable. They provide the ability to experiment with new modeling features before taking on an extended investment in building and adapting semanticsbased tools. They encourage users to extend the notation in a rational, principled way instead of hacking it. When extensions are eventually supported by more powerful, semantics-based tools, the syntax-based tools can assume a secondary role and augment the semantics-based tools. 7.3 XML Schemas as a Basis for Extensible Language Development We have been relatively pleased with XML schemas, as they provide an expressive but not overly-complex metalanguage supported by a significant set of off-the-shelf tools that freed us from having to write parsers, serializers, and syntax checkers. For us, the most problematic restriction of XML schemas is that they only allow single inheritance of data types for elements and attributes, that is, a subtype can have only a single supertype. Therefore, subtypes that mix the content model of several supertypes are not permitted in XML schemabased languages. Several alternative metalanguages exist that alleviate this difficulty such as XInterfaces [N¨olle 2002] and RDF [Lassila and Swick 1999], but none has the support from available tools and standards committees of XML schemas. In our experience, the benefits of XML schemas outweigh the severity of the single-inheritance limitation. To examine how single inheritance affects the development of modeling languages for software, consider a base type “Component” that describes a software component. Now, consider two independent extensions to Component. Feature 1 adds implementation information to the component’s description to describe how it is implemented in a particular programming language. Feature 2 adds administrative data to the component’s description to describe who is responsible for the component, and who has worked on it in the past. This situation is depicted in Figure 18. Semantically, neither feature depends on the other. Therefore, it should ideally be possible to model a plain component, a component with implementation details, a component with administrative details, and a component with both implementation and administrative details. In XML ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
236
•
E. M. Dashofy et al.
Fig. 18. Depiction of multiple inheritance issue in XML schemas and potential solutions.
schemas, there are several ways to accomplish this. First, it would be possible to create individual, independent types for each of the four variants of a component. This works, but it causes a combinatorial explosion of types as new, orthogonal features proliferate. Also, it breaks expected type relationships (a component-with-administrative-details is not a subtype of component). A preferable solution is to introduce an artificial dependency between the two extensions. For example, component-with-administrativeand-implementation-details extends component-with-implementation-details which, in turn, extends component. To accommodate components that have implementation details only, administrative details are made optional in the extension. This preserves expected type relationships (a component-withadministrative-and-implementation-details is-a component) and is able to model all four kinds of components. A final alternative is to use substitution groups and abstract base types for extensions. This is analogous to adding a list of void* to each object class in C++ or a vector of objects to the end of each object class in Java. This does not adequately preserve type relationships and weakens the ability to validate architecture documents via XML type checking. Artificial dependencies are an imperfect solution but are workable and do not suffer from combinatorial explosion. If and when the W3C decides to add multiple-inheritance support to XML schemas in the future, schemas and instance documents that use artificial dependencies should be fairly easy to refactor. 8. RELATED WORK The notion of an extensible architecture description language is not new, nor is our infrastructure the first to support XML-based architecture descriptions. However, our approach provides the first modular architecture description ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
237
language with useful generic features broken down into modules and accompanied by a process and tools that explicitly support new language extensions. Our approach has been inspired by several other research areas. First, there is a large body of work on extensible and modular languages spanning three decades which continues today in projects like ArchJava, AspectJ, and LXWB. Second, many meta and generic modeling environments have emerged that technically could support many of the syntactic capabilities of our XML-based infrastructure. Third, previous ADL research has yielded XML-based ADLs such as ADML and xADL 1.0, two first-generation ADLs with limited extensibility. Finally, it is important to compare our approach with that of the Unified Modeling Language (UML) which has been touted as an architecture description language. 8.1 Extensible and Modular Language Research The 1970s spawned significant research into extensible programming languages [Christensen and Shaw 1969]. These programming languages allowed additions to their syntax, usually through new BNF production rules, and to their semantics, through semantic modules at run-time. Programming languages continue to be extended today. ArchJava [Aldrich et al. 2002] extends a programming language with architectural constructs and semantics such as components and connectors. AspectJ [Lopes et al. 1997] allows cross-cutting concerns to be specified for Java programs that are “woven” into existing Java classes. In these cases, the semantic capabilities provided by the tools could be achieved in the target programming language (Java) without language extensions. However, the amount of (largely manual) work to do so would be prohibitively difficult. ArchJava provides a compact way to specify and check constraints on Java programs that would be nearly impossible to check by hand for a system of any significant size. AspectJ adds significant value to Java by providing a single place where widely distributed concerns can be specified; previously, implementing such cross-cutting concerns would be done by copyand-paste coding or ad hoc preprocessors. The difference between these tools and simple preprocessors is that tools like ArchJava and AspectJ add (and check) semantics beyond those available in the target language (here, Java) but conveniently output Java bytecode for compatibility with the existing run-time environment. More complex semantics (e.g., the addition of concurrency to a programming language that lacks it) may require more significant modification to the language and tools. Other research has focused on modular domain-specific languages. The Language eXtension Work Bench (LXWB) [Peake et al. 2000] was developed in the mid-1990s to allow for modular language description using BNF-like production rules. The LXWB allows language modules to be defined and automatically generates parsers and other tools for compositions of modules much like our infrastructure. In fact, the extensibility aspects of the metalanguage supported by LXWB are very similar to those found in XML schemas. LXWB’s metalanguage defines a type system over language elements and uses inheritance to extend existing constructs. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
238
•
E. M. Dashofy et al.
8.2 Meta and Generic Modeling Environments As an alternative implementation route for our research contributions, we could have chosen any one of a number of alternative metamodeling languages and environments. Examples of these environments include Lisp [Steele 1990], DOME [Honeywell Inc. 1999] and GME [Ledeczi et al. 2000]. Lisp has been proposed as an alternative to using XML since XML’s inception. In particular, the argument has been made that Lisp s-expressions are a better way of encoding hierarchical data than XML [Cunningham & Cunningham Inc. 2004] and that incorporation of additional Lisp elements could mean building semantics and semantic checks directly into the language itself. DOME, the Domain Modeling Environment, is a tool for creating environments for model-based software engineering. DOME allows users to define visual grammars and then develop models which are instances of those grammars. The packaged version of DOME has special support for modeling in several popular modeling notations such as Coad-Yourdon Object Oriented Analysis and Data Flow diagrams. The ability for DOME users to create their own graphical grammars is roughly on par with editing the MOF specification for UML. Code can be added in DOME-specific languages (called Projector and Alter) to analyze models in user-defined grammars. GME, the Generic Modeling Environment, is similar to DOME. Like DOME, users can edit a graphical metamodel and later create instances of that model. Like XML schemas, GME uses a types-and-instances paradigm: metamodels are types, and models are instances of those types. Both GME and DOME support notions of inheritance at the metamodel level, DOME supporting single inheritance of nodes and GME supporting virtual multiple inheritance. All these environments are effectively viable alternatives to XML and XML schemas, offering different advantages and disadvantages, particularly in terms of the capabilities the off-the-shelf tools can provide such as vendor support, and so on. We do not assert that our specific choice and use of XML as the metamodeling environment for our infrastructure is a research contribution per se (though we did learn several valuable lessons about creating modular languages in XML such as those described in Section 7.3); rather, our research contributions come in the form of the particular decomposition of ADL features found in xADL 2.0, insights about how to create and compose ADL modules, and the roles of different kinds of tools in supporting modular ADL development and use. 8.3 Domain-Specific Software Architectures Domain-specific ADLs and Domain Specific Software Architectures (DSSAs) [Coglianese 1992; Tracz and Coglianese 1992; Tracz 1996] are tangentially related to our infrastructure. Because of the amount of domain knowledge infused in a DSSA and its associated modeling language, a measure of compactness and reuse is possible that is not present in traditional, all-purpose ADLs. Because of the modularity of our infrastructure and the ability to make arbitrary extensions to ADLs, our infrastructure is ideal for constructing and experimenting ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
239
with domain-specific architecture description languages. Additionally, productline architecture modeling techniques supported in our infrastructure provide intuitive ways of specifying points of variation in a reference architecture. 8.4 Other XML-Based ADLs Early XML-based ADLs explored the possibility of encoding software architecture descriptions in XML but did not leverage its extensibility. Examples include xADL 1.0 [Khare 2001] and ADML [Spencer 2000]. xADL 1.0 is an intellectual predecessor of xADL 2.0 and included novel features for an ADL such as the ability to specify run-time change and detailed interface specifications. xADL 1.0’s syntax was defined in a DTD and, therefore, it was extensible via XML namespaces, but its tools did not support extensibility. Moreover, its set of supported features was much smaller than xADL 2.0’s. ADML is basically an XML translation of the Acme core, also defined in a DTD. ADML improved marginally on Acme by introducing a notion of metaproperties and property types but also failed to leverage XML’s extensibility. In fact, ADML still uses name-value pair properties as its extensibility mechanism with the names and values simply encoded in XML. Our approach is the first to leverage XML’s extensibility mechanisms fully and does not require the creation or use of a proprietary metalanguage such as ADML’s metaproperties. Beyond better extensibility, our existing support for features such as product-line architectures and implementation mappings exceeds ADML’s capabilities. 8.5 Relationship to UML The Unified Modeling Language [Booch et al. 1998] is an effort to create a standard, generic, graphical modeling language for software systems. There is some amount of disagreement on whether UML is an ADL or not [Booch et al. 1999; Robbins et al. 1997]. From our perspective, UML 1.x can be used as an ADL but it must be extended to some degree to model the core constructs of software architecture such as components and connectors. To address this deficiency, UML 2.0 added a new diagram type called a composite structure diagram. Composite structure diagrams include notions of parts, connectors, ports, and links which map onto xADL 2.0 components, connectors, interfaces, and links, respectively. Our approach improves on the UML approach in two significant ways: features and extensibility. With respect to features, xADL 2.0’s type system and product-line support represent abilities not present in UML, including UML 2.0. More importantly, our infrastructure’s extensibility mechanisms and ability to add features like these are far more flexible than UML’s. UML has two levels of extensibility: built-in extensibility mechanisms (stereotypes, tagged values, and constraints) and MOF editing. UML’s built-in mechanisms allow UML to be extended through overloading of existing constructs. That is, an existing construct like a UML class or part can be stereotyped to serve as a software architecture component or component type. This approach has been used in ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
240
•
E. M. Dashofy et al.
several efforts to adapt UML into an ADL [Hofmeister et al. 1999; Robbins et al. 1997]. Overloading can become problematic if constructs are needed that do not naturally fit one of the existing UML diagram types. For example, consider a construct like xADL 2.0’s version graphs. It would be possible to create a graph of nodes using an existing UML diagram type like a class diagram, but the intent of the class diagram is to show relationships between software artifacts in the design of a system rather than track the evolution of a component over time. An alternative to using the built-in extensibility mechanisms is to redefine UML in its own metalanguage, the metaobject framework (MOF). This allows arbitrary extensibility, but the resulting language is not UML, and, therefore, UML tools will generally not support this new language. In contrast, our approach provides extensibility analogous to editing at the MOF level but provides tools that expect and support this level of extensibility. UML’s relationship to XML is maintained through the XMI format, an XMLbased interchange format in which UML diagrams can be saved and loaded. XMI eases interoperability among UML tools by providing them a common text-based lingua franca (UML’s graphical format does not have a standard method of serialization), but does not contribute to UML’s modeling capabilities or extensibility. 9. CONCLUSIONS AND FUTURE WORK This article describes both research and technical contributions. Research contributions include the first decomposition of an architecture description language into modules, insights about how to develop new language modules and a process for integrating them, and insights about the roles of different kinds of tools in a modular ADL-based infrastructure. This is accompanied by the technical contribution of a viable infrastructure for creating and extending XMLbased architecture description languages. The infrastructure dramatically reduces the amount of effort involved in experimenting with and developing new architectural concepts. This reduction results from the three parts of our infrastructure: an XML-based extensibility mechanism, a set of generic base schemas, and a set of flexible tools. It provides critical tools like parsers, editors, syntax checkers, and data bindings for ADLs, allowing developers to spend more time on building high-value tools that focus on addressing open issues. We believe that our infrastructure has fulfilled all the goals set forth in Section 3. Table III recalls these goals and describes the specific infrastructure mechanisms used to meet the goals. Additionally, the experiences that we and others have had in applying our approach have indicated many positive qualitative aspects of the approach. We have demonstrated the scalability of our infrastructure and the flexibility of our tools by modeling and simulating the AWACS software architecture. The adaptability of our infrastructure to a new, previously unexplored domain (spacecraft software) and the effectiveness of our generic xADL 2.0 schemas have been demonstrated by work done at JPL. We have demonstrated that our infrastructure can be used to capture aspects of an emerging research area (product-line architectures) with Koala [Ommering et al. 2000] and Mae [Hoek ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
241
Table III. Goals Achieved by Our Infrastructure Goal
Infrastructure Characteristics
Place as few limits on what can be expressed at the architecture level as possible.
Allow new modeling features to be added and existing features to be modified over time. Allow experimentation with new features and combinations of features. Provide tool-builders with support for creating and manipulating architecture models, even when the underlying notation can and will change.
Our XML-based extension mechanism allows users to define arbitrary new constructs and extend any existing construct. Our experiences with JPL and the Koala/MAE extensions confirm the effectiveness of this mechanism.
New ADLs can be created simply by composing a set of schemas.
Our syntax-based tools provide instant parsers, data bindings, and editors for new schemas automatically with no new code; our semantic tools and environments are componentized and relatively easy to extend, as confirmed by the integration of DRADEL into our environment. Provide a library of generically useful The xADL 2.0 schemas are these modules. Some or modules applicable to a wide variety all of these schemas were reused in each of our of domains. evaluation efforts. Allow modeling features, once defined, Along with the reuse of the xADL 2.0 schemas, the to be reused in other projects. MDS extension schemas developed by JPL have been used in both code-generation and architecture analysis efforts.
et al. 2001]. Our infrastructure supports its own development and evolution within the ArchStudio 3 design environment. In the future, we plan to experiment with integrating more tools into our infrastructure via the ArchStudio 3 environment to add useful features. Some of these are described in Section 5.2.4. Beyond these, we believe the xlinkit tool [Nentwich et al. 2002] can potentially be used to express and check constraints on XML links in xADL 2.0 documents. Also, the SmartTools toolset [Attali et al. 2001] can potentially provide an XML-based language like xADL 2.0 with alternative editors and semantic analysis tools. For our longterm research goals, we plan to expand the xADL 2.0 schemas to include new modeling constructs, particularly those that will support the specification of distributed and dynamic architectures. We also want to investigate the application of our existing tools to new problems. For example, we believe that our product-line tools can be applied to support architectural tradeoff specification and analysis, where product variants represent points in the space of available trade-offs instead of actual product descriptions. 10. ONLINE RESOURCES For more information about xADL 2.0, please see http://www.isr.uci.edu/ projects/xarchuci/. For more information about the ArchStudio 3 suite of tools, please see http:// www.isr.uci.edu/projects/archstudio/. ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
242
•
E. M. Dashofy et al.
ACKNOWLEDGMENTS
The authors would first like to acknowledge and thank the anonymous reviewers for their invaluable insights about this article which greatly assisted us in shaping and scoping this work and its presentation. We would also like to thank Ping Chen, Tina Cheng, Matthew Critchlow, Rob Egelink, Justin Erenkrantz, Joachim “Joe” Feise, Akash Garg, John Georgas, Scott Hendrickson, Fei Hoffman, Jesse Hsia, Arick Ma, Roshni Malani, Kari Nies, Jie Ren, Jane Tran, and Christopher Van der Westhuizen for their valuable contributions to ArchStudio 3 and the other xADL 2.0 tools. Additionally, we would like to thank the researchers and practitioners who contributed significantly to our evaluation efforts, especially Will Tracz, Nicolas Rouquette, Vanessa Carson, Peter Shames, Neno Medvidovic and Roshanak Roshandel.
REFERENCES APACHE GROUP. 2003. Crimson. Available at . AIR COMBAT COMMAND PUBLIC AFFAIRS OFFICE. 2000. Fact Sheet: E-3 Sentry (AWACS). U.S. Air Force (July). Available at . ALDRICH, J., CHAMBERS, C., AND NOTKIN, D. 2002. ArchJava: Connecting software architecture to implementation. In Proceedings of the 24th International Conference on Software Engineering. (Orlando, FL.) ACM, 187–197. ALLEN, R. AND GARLAN, D. 1997. A formal basis for architectural connection. ACM Trans. Softw. Eng. Method. 6, 3 (July), 213–249. Available at . ALTHEIM, M., BOUMPHREY, F., DOOLEY, S., MCCARRON, S., SCHNITZENBAUMER, S., AND WUGOFSKI, T. 2001. Modularization of XHTML. World Wide Web Consortium, W3C Recommendation Report (April). Available at . Altova GmbH. 2003. XML spy website. Available at . ATTALI, I., COURBIS, C., DEGENNE, P., FAU, A., PARIGOT, D., AND PASQUIER, C. 2001. SmartTools: A generator of interactive environments tools. In Proceedings of the the International Conference on Compiler Construction (CC’01) (April). Genova, Italy. BERNERS-LEE, T. AND CONNOLLY, D. 1998. Web architecture: Extensible languages. W3C Note Report (Feb.) 10. Available at . BINNS, P., ENGLEHART, M., JACKSON, M., AND VESTAL, S. 1996. Domain-specific software architectures for guidance, navigation and control. Int. J. Softw. Eng. Knowl. Eng. 6, 2 (June), 201–227. BOOCH, G., RUMBAUGH, J., AND JACOBSON, I. 1998. The Unified Modeling Language User Guide. Object Technology Series. Addison Wesley, Reading, MA. BOOCH, G., GARLAN, D., IYENGAR, S., KOBRYN, C., AND STAVRIDOU, V. 1999. Is UML an architectural description language? Available at . (OOPSLA ’99). BOSCH, J. 1999. Product-line architectures in industry: A case study. In Proceedings of the 21st International Conference on Software Engineering. IEEE Computer Society Press. Los Angeles, CA. 544–554. BOSCH, J. 2000. Design and Use of Software Architectures: Adopting and Evolving a Product-Line Approach. Wesley, A. Ed. ACM Press. BRAY, T., PAOLI, J., AND SPERBERG-MCQUEEN, C. M. 1998. Extensible markup language (XML): Part I. Syntax. World Wide Web Consortium, Recommendation Report (Feb.). Available at . CHRISTENSEN, C. AND SHAW, C. 1969. Proceedings of the Extensible Languages Symposium. Boston, MA. CLARK, J. AND DEROSE, S. 1999. XML path language (XPath) version 1.0. World Wide Web Consortium, W3C Recommendation Report REC-xpath-19991116 (Nov.). Available at . ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
243
CLEMENTS, P. AND NORTHROP, L. 2001. Software Product Lines—Practices and Patterns. Pearson Education, (Addison-Wesley). COGLIANESE, L., SMITH, R., AND TRACZ, W. 1992. DSSA case study: Navigation, guidance, and flight director design and development. In Proceedings of the IEEE Symposium on Computer-Aided Control System Design. (March), 102–109. CUNNINGHAM & CUNNINGHAM, INS. 2004. Xml isa poor copy of ess expressions. Available at . DASHOFY, E. M. 2001. Issues in generating data bindings for an XML schema-based language. In Proceedings of the Workshop on XML Technologies in Software Engineering (XSE’01) (May). Toronto, Canada. DASHOFY, E. M. AND HOEK, A. V. D. 2001. Representing product family architectures in an extensible architecture description language. In Proceedings of the International Workshop on Product Family Engineering (PFE-4) (Oct.), 330–341. DASHOFY, E. M., HOEK, A. V. D., AND TAYLOR, R. N. 2001. A highly-extensible, XML-based architecture description language. In Proceedings of the Working IEEE/IFIP Conference on Software Architecture (WICSA’01) (Aug.). Amsterdam, The Netherlands. DEROSE, S., MALER, E., AND ORCHARD, D. 2001. XML linking language (XLink) version 1.0. World Wide Web Consortium, W3C Recommendation Report (June). Available at . Eclipse Foundation. 2004. Eclipse. Available at . FALLSIDE, D. C. 2001. XML schema part 0: Primer. World Wide Web Consortium, W3C Recommendation Report (May). Available at . GARG, A., CRITCHLOW, M., CHEN, P., VAN DER WESTHUIZEN, C., AND HOEK, A. V .D. 2003. An environment for managing evolving product line architectures. In Proceedings of the IEEE International Conference on Software Maintenance (ICSM’03) (Sept.). Amsterdam, The Netherlands. GARLAN, D., MONROE, R. T., AND WILE, D. 2000. ACME: Architectural description of componentbased systems. In Foundations of Component-Based Systems, Leavens, G.T. and Sitaraman, M. Eds. Cambridge University Press, 47–48. GORLICK, M. M. AND RAZOUK, R. R. 1991. Using weaves for software construction and analysis. In Proceedings of the 13th International Conference on Software Engineering. (May), 23–34. HOARE, C. A. R. 1978. Communicating sequential processes. Comm. ACM. 21, 8 (Aug.), 666– 677. HOEK, A. V. D., MIKIC-RAKIC, M., ROSHANDEL, R., AND MEDVIDOVIC, N. 2001. Taming architectural evolution. In Proceedings of the 6th European Software Engineering Conference (ESEC) and the 9th ACM SIGSOFT Symposium on the Foundations of Software Engineering (FSE-9) (Sept.). Vienna, Austria. 10–14. HOFMEISTER, C., NORD, R. L., AND SONI, D. 1999. Describing software architecture with UML. In Proceedings of the 1st IFIP Working Conference on Software Architecture. (Feb.). San Antonio, TX. Available at . HONEYWELL INC. 1999. DOME Guide. INSTITUTE FOR SOFTWARE RESEARCH. ArchStudio, an architecture-based development environment. University of California, Irvine. Available at . KHARE, R., GUNTERSDORFER, M., OREIZY, P., MEDVIDOVIC, N., AND TAYLOR, R. N. 2001. xADL: Enabling architecture-centric tool integration with XML. In Proceedings of the 34th International Conference on System Sciences (HICSS-34), Software mini-track (Jan.). Maui, Hawaii. LASSILA, O. AND SWICK, R. 1999. Resource Description Framework (RDF) Model and Syntax Specification. World Wide Web Consortium, W3C Recommendation Report (Feb.). Available at . LE HORS, A., LE H´EGARET, P., WOOD, L., NICOL, G., ROBIE, J., CHAMPION, M., AND BYRNE, S. 2003. Document object model (DOM) level 3 core specification. World Wide Web Consortium, W3C Working Draft Report (June). Available at . LEDECZI, A., MAROTI, M., BAKAY, A., KARSAI, G., GARRETT, J., THOMASON, C., NORDSTROM, G., SPRINKLE, J., AND VOLGYESI, P. 2000. The generic modeling environment. Vanderbilt University, 6. Tech. Rep. Available at . ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
244
•
E. M. Dashofy et al.
LOPES, C. V., KICZALES, G., MENDHEKAR, A., MAEDA, C., LOINGTIER, J.-M., AND IRWIN, J. 1997. Aspectoriented programming. In Proceedings of the European Conference on Object-Oriented Programming. Finland. ¨ , B., AND OWE, O. 1987. Anna—A Language for LUCKHAM, D. C., HENKE, F. W. V., KRIEG-BRUCKNER Annotating Ada Programs. Springer-Verlag, 260. LUCKHAM, D. C., KENNEY, J. J., AUGUSTIN, L. M., VERA, J., BRYAN, D., AND MANN, W. 1995. Specification and analysis of system architecture using rapide. IEEE Trans. Softw. Eng. 21, 4 (April), 336–355. Available at . MAGEE, J., DULAY, N., EISENBACH, S., AND KRAMER, J. 1995. Specifying distributed software architectures. In Proceedings of the 5th European Software Engineering Conference (ESEC’95). Springer-Verlag, Berlin. 137–153. Available at . MEDVIDOVIC, N., ROSENBLUM, D. S., AND TAYLOR, R. N. 1999. A language and environment for architecture-based software development and evolution. In Proceedings of the 21st International Conference on Software Engineering (ICSE ’99) (May). IEEE Computer Society. Los Angeles, CA. 44–53. Available at . MEDVIDOVIC, N. AND TAYLOR, R. N. 2000. A classification and comparison framework for software architecture description languages. IEEE Trans. Softw. Eng. 26, 1 (Jan.), 70–93. Reprinted in Rational Developer Network: Seminal Papers on Software Architecture. Rational Software Corporation. Available at . MEHTA, N. R., MEDVIDOVIC, N., AND PHADKE, S. 2000. Towards a taxonomy of software connectors. In Proceedings of the 2000 International Conference on Software Engineering (June). Limerick, Ireland. 178–187. Available at . MILLIGAN, M. K. J. 2000. Implementing COTS open systems technology on AWACS. CrossTalk: J. Defense Softw. Eng. (Sept.). Available at . NENTWICH, C., CAPRA, L., EMMERICH, W., AND FINKELSTEIN, A. 2002. Xlinkit: A consistency checking and smart link generation service. ACM Trans. Internet Tech. 2, 2 (May), 151–185. Available at . ¨ , O. 2002. XInterfaces: A new schema language for XML. BS Thesis. Institute for Computer NOLLE Science, University of Freiburg. Available at . OBJECT MANAGEMENT GROUP. 2001. The Common Object Request Broker: Architecture and Specification. OMMERING, R. V., LINDEN, F. V. D., KRAMER, J., AND MAGEE, J. 2000. The Koala component model for consumer electronics software. IEEE Comput. 33, 3 (March), 78–85. OMMERING, R. V. 2002. Building product populations with software components. In Proceedings of the 24th International Conference on Software Engineering. 255–265. OREIZY, P., GORLICK, M. M., TAYLOR, R. N., HEIMBIGNER, D., JOHNSON, G., MEDVIDOVIC, N., QUILICI, A., ROSENBLUM, D. S., AND WOLF, A. L. 1999. An architecture-based approach to self-adaptive software. IEEE Intell. Syst. 14, 3 (May-June), 54–62. PEAKE, I. AND SALZMAN, E. 1997. Support for modular parsing in software reengineering. In Proceedings of the Conference on Software Technology and Engineering Practice’97 (July) London, UK. 58–66. PEAKE, I. 2000. LXWB User’s Guide. Centre for Software Maintenance. Queensland. PERRY, D. E. AND WOLF, A. L. 1992. Foundations for the study of software architecture. ACM SIGSOFT Soft. Eng. Notes. 17, 4 (Oct.), 40–52. Available at . REN, J. AND TAYLOR, R. N. 2003. Visualizing software architecture with off-the-shelf components. In Proceedings of the 15th International Conference on Software Engineering and Knowledge Engineering (July) San Francisco, CA. 132–141. ROBBINS, J., REDMILES, D., AND ROSENBLUM, D. 1997. Integrating C2 with the unified modeling language. In Proceedings of the California Software Symposium (CSS’97) (Nov.). Irvine, CA. 11–18. Available at . ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Development of Modular Software Architecture Description Languages
•
245
ROBBINS, J. AND REDMILES, D. 1998. Software architecture critics in the Argo design environment. In Proceedings of the International Conference on Intelligent User Interfaces (UIST’98) (Jan.) San Francisco, CA. 47–60. ROSHANDEL, R., SCHMERL, B., MEDVIDOVIC, N., GARLAN, D., AND ZHANG, D. 2004. Understanding tradeoffs among different architectural modeling approaches. In Proceedings of the 4th Working IEEE/IFIP Conference on Software Architecture (WICSA’04) (June) Oslo, Norway. ROUQUETTE, N. AND REINHOLTZ, K. 2002. The mission data system’s software architecture framework. International Conference on Software Engineering (ICSE’02). Orlando, FL. Available at . SAX PROJECT. 2003. SAX: Simple API for XML. Available at . SCHMERL, B. AND GARLAN, D. 2002. Exploiting architectural design knowledge to support selfrepairing systems. In Proceedings of the 14th International Conference on Software Engineering and Knowledge Engineering. (July), 241–248. Ischia, Italy. Available at . SPENCER, J. 2000. Architecture description markup language (ADML): Creating an open market for IT architecture tools. The Open Group, White Paper Report (Sept.). Available at . STEELE, G. 1990. Common Lisp: the Language. 2nd Ed., Digital Press, Woburn, MA. SUN MICROSYSTEMS. 2003a. Java architecture for XML binding (JAXB). Available at . SUN MICROSYSTEMS. 2003. Javadoc tool home page. Available at . SZYPERSKI, C. 1997. Component Software: Beyond Object-Oriented Programming. ACM Press, New York, NY. TAYLOR, R. N., MEDVIDOVIC, N., ANDERSON, K. M. E., JAMES WHITEHEAD, J., ROBBINS, J. E., NIES, K. A., OREIZY, P., AND DUBROW, D. L. 1996. A component- and message-based architectural style for GUI software. IEEE Trans. Softw. Eng. 22, 6 (June), 390–406. THOMPSON, H. S. AND TOBIN, R. 2003. Current status of XSV. Tech. Rep. University of Edinburgh (July). Available at . TRACZ, W. AND COGLIANESE, L. 1992. A case for domain-specific software architectures. In Proceedings of the WISR-5. TRACZ, W. AND COGLIANESE, L. 1993. An adaptable software architecture for integrated avionics. In Proceedings of the IEEE National Aerospace and Electronics Conference. (May), 1161–1168. TRACZ, W. 1996. Domain-specific software architectures, frequently asked questions. Tech. Rep. Loral Federal Systems Company. WESTHUIZEN, C. V. D. AND HOEK, A. V. D. 2002. Understanding and propagating architectural change. In Proceedings of the Working IEEE/IFIP Conference on Software Architecture (WICSA 3) (Aug.). Montreal, Canada. ZAVE, P. 1999. FAQ sheet on feature interaction. Available at , AT&T, HTML. Received August 2003; revised July 2004; accepted October 2004
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005.
Acknowledgement of Referees 2004 TOSEM acknowledges the cooperation of the referees who helped in reviewing the contributions submitted in 2004. The quality of the published papers also depends on their scholarly contribution. Gailjoon AHN, Johnathan ALDRICH, Thomas ALSPAUGH, Klaus-Dieter ALTHOFF, Paul AMMANN, Myla ARCHER, Uwe ASSMANN, Colin ATKINSON, Darren ATKINSON, Mikio AYOYAMAM, Brenda BAKER, Richard BANACH, Leonor BARROCA, Don BATORY, Daniel BERRY, Antonia BERTOLINO, James BIEMAN, Jan BOSCH, Lionel BRIAND, Nadia BUSI, Ugo BUY, Gerardo CANFORA, Licia CAPRA, Jeff CARVER, Antonio CARZANIGA, David CHAYS, Marsha CHECHIK, Guanling CHEN, Shing-Chi CHEUNG, Christine CHOPPY, Betsy CLARK, John CLARK, Paul CLOUGH, Jim CORDY, Nancy DAY, Premkumar DEVANBU, Schahram DUSTDAR, Christof EBERT, Alexander EGYED, Sebastian ELBAUM, Wolfgang EMMERICH, Albert ENDRES, Paul EZHILCHELVAN, Bernd FISCHER, Robert FRANCE, Harold GALL, Gerald GANNOD, Angelo GARGANTINI, Vincenzo GERVASI, Martin GLINZ, Stefania GNESI, Ian GORTON, Orlena GOTEL, Mark GRECHANIK, Bill GRISWOLD, Thomas GSCHWIND, Nicolas GUELFI, Kevin HAMMOND, Mary Jean HARROLD, Will HEAVEN, Reiko HECKEL, Mats HEIMDAHL, George HEINEMAN, Maritta HEISEL, Brian HENDERSON–SELLERS, Rob HIERONS, Ellis HOROWITZ, Valerie ISSARNY, Daniel JACKSON, Jens H. JAHNKE, Matthias JARKE, Stan JARZABEK, Ross JEFFERY, Ralph JEFFORDS, Jan JUERJENS, Gregory KAPFHAMMER, Christos KARAMANOLIS, Gabor KARSAI, Scott KOHN, Kai KOSKIMIES, Jeff KRAMER, Richard KUHN, David KUNG, Shinji KUSUMOTO, Julio Cesar LEITE, Michel LEMOINE, Elizabeth LEONARD, Timothy LETHBRIDGE, Emmanuel LETIER, Karl LIEBERHERR, Jeffrey MAGEE, Neil MAIDEN, Johnathan I. MALETIC, Brian MALLOY, Mieke MASSINK, Nenad MEDVIDOVIC, Atif MEMON, Tom MENS, Amit MIDHA, Tommi MIKKONEN, Ali MILI, Raffaella MIRANDOLA, Roland MITTERMEIR, Carlo MONTANGERO, Sandro MORASCA, Gail MURPHY, John MURPHY, Oscar NIERSTRASZ, Jeff OFFUTT, Alex ORSO, Thomas OSTRAND, Linda OTT, Barbara PAECH, Dennis K. PETERS, Marco PISTORE, Rodon PODOROZHNY, Adam PORTER, Matteo PRADELLA, Lutz PRECHELT, Wolfgang PREE, Christian PREHOFER, Lucia RAPANOTTI, Anders P. RAVN, Joy REED, Gianna REGGIO, Steven REISS, David ROSENBLUM, Peter ROSENTHAL, Atanas ROUNTEV, Barbara RYDER, Sriram SANKAR, Andre SCHIPER, Wolfram SCHULTE, Michael SCHWARTZBACH, Timothy SHIMEALL, Yannis SMARAGDAKIS, Graeme SMITH, Mary Lou SOFFA, Don SOFGE, Neelam SOUNDARAJAN, Scott STOLLER, David STOTTS, Walid TAHA, Stefan TAI, Anand TRIPATHI, T.H. TSE, Sebastian UCHITEL, Michael USCHOLD, Steve VESTAL, Alan WASSYNG, Westley WEIMER, David WEISS, Bernhard WESTFECHTEL, Geoff WHALE, Jim WHITEHEAD, Eric WOHLSTADTER, Tao XIE, Eric YU, Gian Luigi ZAVATTARO, Andreas ZELLER, Andrea ZISMAN ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 2, April 2005, Page 246.