You are on page 1of 8

The Third International Conference on Software Engineering Advances

Dynamic Software Architectures: Formally Modelling Structure and Behaviour with -ADL
Flavio Oquendo University of South Brittany VALORIA BP 573 56017 Vannes Cedex France flavio.oquendo@univ-ubs.fr Abstract
A key aspect of the design of any software system is its architecture. From the perspective of dependability, an effective architecture aims to build fault-free systems, i.e. ensuring fault avoidance. At the architecture level, fault avoidance is achieved by formally describing the structure and behaviour of software systems enabling to check their correctness. Therefore, a software architecture description should provide a formal specification of the architecture in terms of components and connectors and how they behave and are composed together. Further, a dynamic software architecture must provide a specification of how the architecture of the software system can change at runtime. Enabling specification of dynamic architectures is a large challenge for an Architecture Description Language (ADL). This paper presents how -ADL, a novel ADL that has been designed in the ArchWare European Project, can be used for specifying dynamic architectures through a case study. architecture level, fault avoidance is achieved by formally describing the structure and behaviour of software systems enabling to check their correctness [4]. A software architecture can be characterised according to its evolution at runtime [10]: static architectures: the architecture does not evolve during the execution of the system; dynamic architectures: the architecture may evolve during the execution of the system, e.g. components are created, deleted, or reconfigured at runtime. An architecture description specifies an architecture. An architecture can be described according to different viewpoints. Two viewpoints are frequently used in software architecture [7]: the structural viewpoint and the behavioural viewpoint. The structural viewpoint may be specified in terms of: components (units of computation of a system), connectors (interconnections among components for supporting their interactions), configurations of components and connectors. Thereby, from a structural viewpoint, an architecture description should provide a formal specification of the architecture in terms of components and connectors and how they are composed together. Further, in the case of a dynamic architecture, it must provide a specification of how its components and connectors can change at runtime. The behavioural viewpoint may be specified in terms of: actions a system executes or participates in, relations among actions to specify behaviours, behaviours of components and connectors, and how they interact. A large challenge for an Architecture Description Language (ADL) is the ability to describe static but also dynamic software architectures from structural and behavioural viewpoints [13]. Indeed, for describing dynamic architectures, an ADL must be

1. Introduction
Software architecture has emerged as an important subdiscipline of software engineering. A key aspect of the design of any software system is its architecture, i.e. the fundamental organisation of the system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution [7]. Formal methods are increasingly used for modelling software architectures. Their potential advantages for dependability assurance have been widely recognized. Indeed, formal methods continue to have a major impact on software engineering, especially in areas where dependability and trust matter. From the perspective of dependability, formal architecture descriptions aim to build fault-free systems, i.e. ensuring fault avoidance. At the

978-0-7695-3372-8/08 $25.00 2008 IEEE DOI 10.1109/ICSEA.2008.47

352

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

able to describe changing structures and behaviours of components and connectors (including creation/deletion/reconfiguration) at runtime. Ten years after the first generation ADLs ADLs that only enable the description of static architectures, this paper presents through a case study how the Architecture Description Language (-ADL) [12] enables specification of dynamic architectures. -ADL, a novel ADL that has been designed in the ArchWare1 European Project, is a formal yet practical executable specification language: formality: it is a formal, well-founded theoretically language based on the higher-order typed calculus [9]; practicality: it provides different user-friendly concrete syntaxes textual and graphical (via UML 2.0 profile) hiding the complexity of its formal underpinnings to ease its use by architects and engineers; in addition, it is automated by tools, i.e. a verification toolset is provided for automated checking of architectural properties; executability: an architecture description specifies how the system behaves in terms of abstract architectural concepts; its virtual machine runs software architecture descriptions step by step or randomly. Besides specifying static and dynamic architectures, -ADL also supports specification of mobile architectures (see [12] for further details and case studies). -ADL takes its roots in previous work concerning the use of -calculus as semantic foundation for architecture description languages [2]. Indeed, a natural candidate for expressing (runtime) behaviour would be the -calculus as it is [9], which provides a general model of computation and is Turing-complete. This means that in -calculus every computation is possible but not necessarily easy to express. In fact, the classical -calculus is not suitable as an ADL since it does not provide architecture-centric constructs to easily express architectures in particular with respect to architectural structures. Therefore, a language encompassing both structural and behavioural architecture-centric constructs is needed. -ADL is this encompassing language, defined as a domain-specific extension of the higher-order typed -calculus. It achieves Turing completeness and high architecture expressiveness with a simple formal notation. But why do software engineers need a formal ADL? Of course, ADLs that provide a semi-formal
1

notation helps as the state of the practice today is mainly to use semi-formal notations for documenting software architectures [3]. It helps but it is not enough. Indeed, in order to check correctness, and thereby enforce dependability assurance, a formal ADL encompassing both structural and behavioural constructs is mandatory. -ADL is this formal yet practical ADL. It supports automated verification of structural and behavioural properties. Beyond that, it is executable: it is very practical to run the architecture descriptions in order to validate its dynamic semantics. For UMLers, it provides a UML 2.0 profile that eases its use and fully automates its translation to executable specifications. The remainder of this paper is organised as follows. Section 2 introduces -ADL core concepts. Section 3 illustrates through a case study how -ADL can be used for specifying a dynamic architecture. In section 4, we compare -ADL with related work. To conclude we summarise, in section 5, the main contributions of this paper and briefly outlines the -ADL toolset for supporting architecture specification and verification.

2. Core Concepts
-ADL supports description of software architectures from a runtime perspective. In -ADL, an architecture is described in terms of components, connectors, and their composition. Figure 1 depicts its main constituents.
<<component>> <<connection>> <<connection>> <<connector>>

<<unification>> <<port>> <<port>> <<port>>

<<unification>>

<<port>>

<<component>>

Figure 1. Architectural concepts in -ADL

The ArchWare European Project has been partially funded by the European Commission under contract No. IST-32360 in the IST Framework Program.

Components are described in terms of external ports and an internal behaviour. Their architectural role is to specify computational elements of a software system. The focus is on computation to deliver system functionalities. Ports are described in terms of connections between a component and its environment. Their

353

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

architectural role is to put together connections providing an interface between the component and its environment. Protocols may be enforced by ports and among ports. Connections are basic interaction points. Their architectural role is to provide communication channels between two architectural elements. Connections may be unified to enable communication. A component can send or receive values via connections. They can be declared as output connections (values can only be sent), input connections (values can only be received), or inputoutput connections (values can be sent or received). Connectors are special-purpose components. They are described as components in terms of external ports and an internal behaviour. However, their architectural role is to connect together components. They specify interactions among components. Therefore, components provide the locus of computation, while connectors manage interaction among components. A component cannot be directly connected to another component. In order to have actual communication between two components, there must be a connector between them. Both components and connectors comprise ports and behaviour. In order to attach a port of a component to a port of a connector, at least a connection of the former port must be attached with a connection of the later port. A connection provided by a port of a component is attached to a connection provided by a port of a connector by unification or value passing. Thereby, attached connections can transport values (that can be data, connections, or even architectural elements). From a black-box perspective, only ports (with their connections) of components and connectors and values passing through connections are observable. From a white-box perspective, internal behaviours are also observable. Components and connectors can be composed to construct composite elements (see Figure 2), which may themselves be components or connectors. Composite elements can be decomposed and recomposed in different ways or with different components in order to construct different compositions. Composite components and connectors comprise external ports (i.e. observable from the outside) and a composition of internal architectural elements. These external ports receive values coming from either side, incoming or outgoing, and simply relay it to the other side keeping the mode of the connection. Ports can also be declared to be restricted. In that case, constituents of composite elements can use

connections of restricted ports to interact with one another but not with external elements.

<<composite>>

Figure 2. Architectural composition in -ADL

Architectures are composite elements representing systems. An architecture can itself be a composite component in another architecture, i.e. a subarchitecture. -ADL provides primitive constructs for supporting the description of all these architectural concepts. In -ADL, architectures, components, and connectors are formally specified in terms of typed abstractions over behaviours. -ADL is formally defined by a formal transition and type system.

3. Case Study
We present hereafter a case study to illustrate how -ADL can be used to formally describe a dynamic software architecture. We describe a client-server architecture of a login system. The architecture is dynamic: new clients can be created during the execution of the system. First we will present a black-box description of the architecture focusing on interface (i.e. ports and their connections) of components and connectors. Then we will add the internal behaviour of components and connectors in a white-box description. Finally the encompassing structure (i.e. binding among components and connectors using connection unifications) is described. The login system supports the creation of new logins by receiving a new userId and a password to be stored under this userId. Concurrently, it supports checking of existing logins by answering requests for the password of a certain existing userId by sending the password stored under this userId. Figure 3 depicts the login system as a whole. It is represented as a composite component, named LoginManager, having ports2 update and request.
2

By syntactic convention, ports that are not explicitly declared as restricted are external free ports.

354

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

These ports represent the interaction LoginManager system with its environment.

of

the

received from the environment first undergoes some processing (e.g. encrypting the password) in the login IU and is then forwarded to the remote database manager that stores its data. Figure 5 outlines the abstract architecture of the system in terms of its components and connectors.

update LoginManager

request

upd ate L og inMana ge r

req uest

Figure 3. The system as a whole

i ncoming NewL ogi nUI

o utg oin g

i ncomi ng Li nk

outgoi ng

inc oming Lo gi nDB

sel ect

Using -ADL, the LoginManager system abstraction can be formally described as shown in Figure 4.
architecture LoginManager is abstraction() { type UserId is Any. type Password is Any. type Login is tuple[UserId, Password]. port update is { port request is { connection upd is in(Login) }. connection log is in(UserId). connection pwd is out(Password) } assuming { protocol is { ( via log receive any. true*. via pwd send any )* } }

Figure 5: Outline of the architecture

The architecture consists of a login IU component NewLoginIU, a database manager component LoginDB, and a connector Link to connect them together. These components and connector can be formally described in -ADL as follows.
component NewLoginUI is abstraction() { type UserId is Any. type Password is Any. type Login is tuple[UserId, Password]. port incoming is { connection in is in(Login) }. port outgoin g is { connection toLink is out(Login) }. } assuming {

Figure 4. Ports of the architecture

protocol is { (

via incoming::in receive any. true*. via outgoing::toLink send any )* }

In this interface description of the login system, type UserId is the set of all possible userIds and type Password is the set of all possible passwords. Login is the tuple type tuple[UserId, Password], i.e. the set of all possible logins associating userId and password. Two ports are declared: update that comprises the connection in for receiving new login entries and request that comprises the connections log and pwd for answering requests of passwords. The protocol enforced by this port is that requests for the password of a certain userId, which are received via the connection log, are answered by sending (after processing) a password via the connection pwd. For each userId received there must be a password sent before accepting the next userId. The login system is composed of login user interfaces (UI) and a login database manager. A login IU acts as a client of the database manager that acts as a server managing the login data. A new login entry

Figure 6. Ports of the component NewLoginIU

In component NewLoginIU (see Figure 6), two ports are declared: incoming that comprises the connection in for receiving new login entries and outgoing that comprises the connection toLink for forwarding these logins. The protocol enforced by the two ports is that a value received via the connection in is (after processing) forward by sending some (possibly processed) value via the connection toLink. For each new login entry received there must be a login sent before accepting the next new login.

355

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

component LoginDB is abstraction() { type UserId is Any. type Password is Any. type Login is tuple[UserId, Password]. port select is { connection log is in(UserId). connection pwd is out(Password) } assuming { protocol is { ( via log receive any. true*. via pwd send any )* } }. port incoming is { connection fromLink is in(Login) } }

component NewLoginUI is abstraction() { behaviour is { encrypt is function(p : Password) : Password { unobservable }. via incoming::in receive login : Login . project login as userId, password. via outgoing::toLink send tuple(userId, encrypt(password)). behaviour() } } assuming { }

Figure 7. Ports of the component Login Database

In component LoginDB (see Figure 7), two ports are declared: select that comprises the connection log for receiving userId values and the connection pwd for sending the password value stored under this userId, and incoming for receiving new login entries.
connector Link is abstraction() { type UserId is Any. type Password is Any. type Login is tuple[UserId, Password]. port incoming is { connection toLink is in(Login) }. port outgoing is { connection fromLink is out(Login) }. } assuming { protocol is { ( via incoming::toLink receive login : Login. via outgoing::fromLink send login )* } }

Figure 9. Behaviour of the component NewLoginIU

In component NewLoginIU (see Figure 9), a function encrypt : Password Password handles the encryption for a single password in the login IU. The behaviour specifies that once a new login is received via connection in, it is sent containing the same userId and an encrypted password via connection toLink. The behaviour is recursively defined. Once a login entry is handled, it continues with the same (recursive) behaviour for the next one.
component LoginDB is abstraction() { database is location(Set(Login)). behaviour is { decrypt is function(p : Password) : Password { unobservable }. choose { via incoming::fromLink receive login : Login. project login as userId, password. database := database including( tuple(userId, decrypt(password))). behaviour() or via select::log receive query : Login. via select::pwd send (database selecting( lg | project lg as userId, password. userId=query )). behaviour() } } }

Figure 8. Ports of the connector Link

In connector Link (see Figure 8), two ports are declared: incoming that comprises the connection toLink for receiving login entries and outgoing that comprises the connection fromLink for forwarding these entries. The protocol enforced by the two ports is that login entries received via the connection toLink are immediately forward by sending it via the connection fromLink. This black-box description of the LoginManager architecture can be further detailed to achieve a whitebox description of the architecture that encompasses interface, behavioural and then structural aspects. The behaviour of the components NewLoginIU and LoginDB and the connector Link can be formally described in -ADL as follows.

Figure 10. Behaviour of the component Login Database

356

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

In component LoginDB (see Figure 10), the database is modelled as a location that stores a set of tuples of Login type. Given a userId, a password can be retrieved. If there is not yet an item stored under the given userId, then the database returns a null value. The behaviour specifies a choice: updating the database or handling requests. When a new login is received via connection fromLink, it is included, after decrypting it, in the database. A new password for the same userId overwrites the old one. When a query with a userId is received via connection log, its corresponding password (retrieved from the database) is sent via connection pwd. The behaviour is recursively defined. Once a new login entry or a request is handled, it continues with the same (recursive) behaviour for the next entry or request.
via incoming::toLink receive login : Login

in Figure 13, thereby providing the structure of the architecture in terms of attached components and connector.
architecture LoginManager is abstraction() { behaviour is compose { replicate ui is NewLoginUI() and and } where { and and and } } lk db is Link() is Login DB()

ui::incoming relays update ui::outgoing unifies lk::incoming lk::outgoing unifies db::incoming request relays db::select

Figure 13. Composition of the Architecture


via outgoing::fromLink send login

Figure 11. Behaviour of the connector Link in UML


connector Link is abstraction() { behaviour is { via incoming::toLink receive login : Login. via outgoing::fromLink send login. behaviour() } } assuming { } }

Figure 12. Behaviour of the connector Link

In connector Link (see Figure 11 for the description of its behaviour in UML 2.0 in terms of a state machine3 and Figure 12 or its translation in -ADL), the behaviour specifies that login entries received via the connection toLink are immediately forward by sending it via the connection fromLink. The behaviour is recursively defined. Once a login entry is handled, it continues with the same (recursive) behaviour for the next entry. Using the components NewLoginIU and LoginDB and the connector Link, the abstract architecture LoginManager can be composed in -ADL as shown
3

In the architecture, the component instances ui and db are connected using the connector lk. In order to actually connect them, connections must be unified4. Connection toLink of port outgoing of component iu is unified with connection toLink of port incoming of connector lk. Connection fromLink of port outgoing of connector lk is unified with connection fromLink of port incoming of component db. Besides connecting component instances together, the architecture must express the binding between external ports and ports of components. This binding is expressed by connection relay. Connection in of external port update is relayed to connection in of port incoming of component iu. Connection log of external port request is relayed to connection log of port select of component db. Connection pwd of port select of component db is relayed to connection pwd of external port request. The architecture is dynamic: there are as many replicated iu instances as needed (the actual number of instances is only known at runtime).

4. Related Work
Different ADLs have been proposed in the literature [8], including: ACME/Dynamic-ACME, AESOP, AML, ARMANI, CHAM-ADL, DARWIN, META-H, PADL, RAPIDE, SADL, -SPACE, UNICON-2, WRIGHT/Dynamic-WRIGHT, and ZETA. Most of these ADLs assume that architectures are
4

All behaviours and port protocols can be modelled as state machines using the UML 2.0 Profile for -ADL and then automatically translated in -ADL.

If connections have the same names in different ports, identifying ports is enough to express unifications (if connection names are different, then they must be explicitly unified).

357

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

static. Some however supports the description of dynamic aspects of architectures. They are DARWIN, Dynamic-ACME, Dynamic-WRIGHT, -SPACE, and RAPIDE. But this support is rather limited. The support provided by -ADL is complete with respect to expressiveness of dynamic architectures based on its underlying foundation, i.e. the typed higher-order calculus. An ADL is defined by both a syntax and a formal, or semi-formal, semantics. Typically, ADLs embody a conceptual framework reflecting characteristics of the domain for which the ADL is intended. The focus of -ADL is on the formal modelling of dynamic architectures, and for supporting the computer-aided formal verification and refinement of these models. Comparing ADLs objectively is a difficult task because their focuses are quite different. Most ADLs essentially provide constructs for a component-andconnector description including topological constraints from a structural viewpoint. The reason for this is probably that structure is certainly the most understandable and visible part of an architecture. But behavioural and qualities are not completely neglected. They are often taken into account (even if partially) in most ADLs. They are certainly an essential part of an architecture description. -ADL introduces the notion of architectural abstractions, which can be architectures, components and connectors from a runtime perspective. All abstractions are first-class citizens. In -ADL, architectures, components, and connectors are formally specified in terms of typed abstractions over behaviours. These abstractions can be enforced to comply with architectural styles. Furthermore, -ADL provides a notation to express assumptions as properties of architectures. It combines predicate logic with temporal logic in order to allow the specification of both structural properties and behavioural properties. Regarding structural properties, the property notation is based on predicate logic. Regarding behavioural properties, it is based on modal -calculus. The choice of modal -calculus as the underlying formalism provides a significant expressive power. Moreover, having a unified notation for expressing both structural and behavioural properties facilitates the specification task of architects, by allowing a more natural and concise description. The main limitation of most of the ADLs with regard to analysis support is that they address either structural or behavioural properties, but not both at the same time as in -ADL. No other ADL provides a

comprehensive set of features for describing dynamic (and evolvable [10]) architectures as -ADL. -ADL provides a novel ADL that is generalpurpose and Turing-complete. It can be seen as a second generation ADL: in first generation ADLs, languages focused mainly in structural aspects and were not complete; in second generation, languages must encompass both structure and behaviour specification and must be complete. Further details on the positioning of -ADL with respect to the state-ofart can be found in [5].

5. Concluding Remarks
This paper presents through a case study how ADL can be used for modelling the structure and behaviour of dynamic software architectures. It complements other publications on -ADL by providing a practical view on how to use its concepts and associated graphical (via UML 2.0 Profile) and textual notations instead of presenting its formal underpinnings and semantics. -ADL supports formal specification (and corresponding validation and verification) of dynamic software architectures. For that reason it differs from other existing ADLs. Its graphical notation defined as a UML 2.0 Profile in a model driven architecture framework [1] assists in filling the gap between semi-formal architecture diagrams and formal descriptions, which can be analysed and refined, by providing the ability to elaborate visually the architecture specification. A major impetus behind developing formal languages for architectural description is that their formality renders them suitable to be manipulated by software tools [14]. The usefulness of an ADL is thereby directly related to the kinds of tools it provides to support architectural description, but also analysis, refinement, code generation, and evolution [12]. Indeed, -ADL is supported by a comprehensive toolset for supporting architecture-centric formal development. It is composed of: a -ADL visual modelling tool, implemented as an extension of the Objecteering UML Modeller (see Figure 14), a -ADL callable compiler and a persistent virtual machine for running architecture descriptions, a -ADL verification tool based on CADP [6], and XSB for checking architectural properties, a -ADL refinement tool providing a processcentred refinement framework based on the Maude rewriting logic system, a -ADL-to-Code synthesizer, from which, among

358

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

others, a -ADL-to-Java code generation tool has been synthesized.

[5] Gallo F. (Ed.): Annual Report Survey of State-of-theArt and Typical Usage Scenario for ArchWare ADL and AAL. Deliverable D0.4.1, ArchWare European RTD Project No. IST-2001-32360, http://www.archware.org/, February 2003. [6] Garavel H., Lang F., Mateescu R.: An Overview of CADP 2001. European Association for Software Science and Technology (EASST) Newsletter, Vol. 4, August 2002. [7] IEEE Std 1471-2000: IEEE Recommended Practice for Architectural Description of Software-Intensive Systems. IEEE Press, October 2000. [8] Medvidovic N., Taylor R.: A Framework for Classifying and Comparing Architecture Description Languages. IEEE Transactions on Software Engineering, 2000.

Figure 14. Objecteering UML Modeller extended with the UML 2.0 Profile for -ADL

[9] Milner R.: Communicating and Mobile Systems: The Calculus. Cambridge University Press, 1999. [10] Morrison R., Balasubramaniam D., Oquendo F., Warboys B., Greenwood M.: An Active Architecture Approach to Dynamic Systems Co-evolution. Proceedings of the 1st European Conference on Software Architecture (ECSA07), Madrid, Spain, September 2007. [11] Morrison R., Graham K., Balasubramaniam D., Mickan K., Oquendo F., Cimpan S., Warboys B., Snowdon B., Greenwood M.: Support for Evolving Software Architectures in the ArchWare ADL. Proceedings of the 4th Working IEEE/IFIP International Conference on Software Architecture (WICSA04), Oslo, Norway, June 2004. [12] Oquendo F.: -ADL: An Architecture Description Language based on the Higher Order Typed -Calculus for Specifying Dynamic and Mobile Software Architectures. ACM Software Engineering Notes, Vol. 28, No. 8, USA, May 2004. [13] Oquendo F.: Les architectures logicielles. Encyclopdie de linformatique et des systmes dinformation, Editions Vuibert (In French), November 2006. [14] Oquendo F. (Ed.): Proceedings of the European Conference on Software Architecture (ECSA07). LNCS 4758, Springer, September 2007. [15] Oquendo F., Warboys B., Morrison R., Dindeleux R., Gallo F., Garavel H., Occhipinti C.: ArchWare: Architecting Evolvable Software. Proceedings of the 1st European Workshop on Software Architecture (EWSA05), LNCS 3047, Springer Verlag, May 2004.

All tools supporting -ADL are integrated using an XML-based interchange language and web services. This comprehensive toolset is available as Open Source Software. -ADL has been applied in practice in several software development projects, e.g. at Thsame (France), Engineering Ingegneria Informatica (Italy), and CERN (Switzerland). -ADL, and its toolset, has been used at Thsame for architecting and developing an agile industrial process management system. At Engineering Ingegneria Informatica, for architecting and developing a federated knowledge management system in Java/J2EE. At the CERN (Switzerland), for architecting and developing human computer interface software for monitoring particle accelerator restart.

6. References
[1] Brown A.W.: MDA and Todays Systems. The Rational Edge, February 2004. [2] Chaudet C., Greenwood M., Oquendo F., Warboys B.: Architecture-Driven Software Engineering: Specifying, Generating, and Evolving Component-Based Software Systems. IEE Journal: Software Engineering, Vol. 147, No. 6, UK, December 2000. [3] Clements P. et al.: Documenting Software Architectures: Views and Beyond. Addison Wesley, 2003. [4] Gacek C., de Lemos R.: Architectural Description of Dependable Software Systems. Structure for Dependability: Computer-Based Systems from an Interdisciplinary Perspective, Besnard D., Gacek C., Jones C.B. (Eds.), Springer, 2006.

359

Authorized licensed use limited to: Pontificia Universidad Javeriana. Downloaded on May 14,2010 at 17:16:50 UTC from IEEE Xplore. Restrictions apply.

You might also like