Damien Cassou
email: damien.cassou@hpi.uni-potsdam.de

Serge Stinckwich
email: serge.stinckwich@ird.fr

Pierrick Koch
email: pierrick.koch@unicaen.fr

Using the DiaSpec design language and compiler to develop robotics systems

A Sense/Compute/Control (SCC) application is one that interacts with the physical environment. Such applications are pervasive in domains such as building automation, assisted living, and autonomic computing. Developing an SCC application is complex because: (1) the implementation must address both the interaction with the environment and the application logic; (2) any evolution in the environment must be reflected in the implementation of the application; (3) correctness is essential, as effects on the physical environment can have irreversible consequences.

The SCC architectural pattern and the DiaSpec domainspecific design language propose a framework to guide the design of such applications. From a design description in DiaSpec, the DiaSpec compiler is capable of generating a programming framework that guides the developer in implementing the design and that provides runtime support. In this paper, we report on an experiment using DiaSpec (both the design language and compiler) to develop a standard robotics application. We discuss the benefits and problems of using DiaSpec in a robotics setting and present some changes that would make DiaSpec a better framework in this setting.

I. INTRODUCTION

A Sense/Compute/Control (SCC) application is one that interacts with the environment [START_REF] Taylor | Software Architecture: Foundations, Theory, and Practice[END_REF]. The SCC architectural pattern guides the description of SCC applications and involves four kinds of components, organized into layers [START_REF] Cassou | Leveraging software architectures to guide and verify the development of sense/compute/control applications[END_REF], [START_REF] Edwards | Architecturedriven self-adaptation and self-management in robotics systems[END_REF]: (1) sensors at the bottom, which obtain information about the environment; (2) then context operators, which process this information; (3) then control operators, which use this refined information to control (4) actuators at the top, which finally impact the environment. A robotics application is a kind of SCC application where the environment is composed of a robot (sensors/actuators/body, control architecture, etc) and the robot's neighborhood (the walls, ground, people, etc) [START_REF]Springer Handbook of Robotics[END_REF]. As noticed by Taylor et al. [START_REF] Taylor | Software Architecture: Foundations, Theory, and Practice[END_REF], the Sense/Plan/Act architecture [START_REF]Springer Handbook of Robotics[END_REF], widely used in robotics, closely resembles the SCC architectural pattern.

DiaSpec is a domain-specific design language dedicated to describing SCC applications [START_REF] Cassou | Leveraging software architectures to guide and verify the development of sense/compute/control applications[END_REF], [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF]. From such a design description, the DiaSpec compiler produces a dedicated Java programming framework that is both prescriptive and restrictive: it is prescriptive in the sense that it guides the developer, and it is restrictive in the sense that it limits the developer to what the design description allows. By separating application logic (implemented by the developers) and runtime support (generated in the programming framework), DiaSpec facilitates the design, implementation and evolution of SCC applications.

Contributions

Our contributions are as follows:

• A report on an experiment of designing and implementing a standard robotics application in the SCC architectural pattern with the DiaSpec domain-specific design language and framework (Sections II and III). This report includes detailed instructions and guidelines to allow further experiments.

• A discussion of the benefits and problems of using DiaSpec in a robotics setting (Section IV). This discussion includes a list of changes to DiaSpec that would make it a better framework for developing new robotics applications. We finally highlight some related works and conclude in sections V and VI.

II. DESIGNING A ROBOTICS APPLICATION

In this section we first explain how to decompose a robotics application in DiaSpec component types. Then we present a case study that we use as an example of how to describe a robotics application with DiaSpec.

In the rest of this paper we use ROS1 as the underlying middleware for our case study. We believe it is a good choice as ROS is becoming a standard within the robotics community. It is important to note however that our approach and DiaSpec are independent of any middleware.

A. Decomposing

Designing an application with DiaSpec requires a decomposition in layers. Each layer corresponds to a separate type of component:

• A sensor sends information sensed from the environment to the context operator layer through data sources.

A sensor can both push data to context operators and respond to context operator requests. We use the term "sensor" both for entities that actively retrieve information from the environment, such as system probes, and entities that store information previously collected from the environment, such as structured information coming from the middleware.

• A context operator refines (aggregates and interprets) the information given by the sensors. Context operators can push data to other context operators and to control operators. Context operators can also respond to requests from parent context operators.

• A control operator transforms the information given by the context operators into orders for the actuators.

• An actuator triggers actions on the environment.

The following details the steps to follow to decompose a robotics application into these component types.

Reusing existing components: In the presence of a previous application developed with DiaSpec, it is possible and advisable to reuse as much components as possible. Depending on the amount of reused components this can have a huge impact on the application of the other steps.

Listing capabilities: Each robot comes with its own set of capabilities (e.g., sensing motion and projecting light). A developer should map these capabilities to sensor sources and actuator actions. A developer should then group related sources and actions inside entity classes (e.g., a camera providing a picture source and zooming action). Beside sources and actions, an entity class may also have attributes to characterize its instances (e.g., resolution, accuracy and status). In the presence of a high-level middleware (such as ROS), it can be useful to also map capabilities of the middleware into sources and actions (e.g., a mapping or a localization capability).

Identifying main context operators: The next step of the decomposition in components is the identification of the main high-level pieces of information required by the application. A developer should map these pieces of information to context operators and use them as input to control operators.

Decomposing into lower-level pieces: Then, a developer must identify lower-level context operators that act as input sources for the higher-level ones. This decomposition is typically done in several steps, each step slightly lowering the level of previously identified context operators. This decomposition ends when each identified context operator can directly take its input from a set of sensor sources.

Identifying control operators: From the high-level context operators a developer has to derive a set of control operators that will send orders to actuators. Because a developer can not reuse the code of a control operator in another part of the application, it is important that this code is as simple as possible. If there is opportunity for reuse, the code should be moved to a new context operator.

Identifying data types: While proceeding with the above steps it is also necessary to define data types. A developer then use these types to describe entity sources, context operators, and parameters of actuator actions. A data type is either primitive (e.g., integer, boolean and float), an enumeration of names (e.g., a luminosity can either be low, normal or high), or a structure (e.g., a coordinate with x and y fields). An important question arises in the presence of a high-level middleware (such as ROS): should the types of the application be the types provided by the middleware or should the application define new types. The former solution is easier to use whereas the latter provides more decoupling. A general principle is to provide new types when their transcription in DiaSpec is straightforward (e.g., a coordinate) and to reuse the middleware types otherwise (e.g., ROS defines a "twist" data type that is complex enough to not be reimplemented).

B. Case Study

As a running example, we present an application that is typical of the robotics domain. In this application, a robot evolves in an unknown environment and has two modes: random and exploration. In the random mode, the robot goes straight and when an obstacle is close enough turns before going straight again. In the exploration mode, the robot goes to unvisited locations with the goal to visit as much as possible from the neighborhood. The current mode can be changed at anytime by an operator through a graphical interface. In both modes, the robot turns on an embedded projector and takes pictures when it is in a zone with obstacles.

Let us now discuss the above steps in the context of this case study (Figure 1 represents the result).

Reusing existing components: We assume no previous DiaSpec application and thus no DiaSpec component to reuse.

Listing capabilities: The Bosch robotics research group develops an exploration capability2 based on a well-known frontier-based exploration algorithm [START_REF] Yamauchi | Frontier-based exploration using multiple robots[END_REF]. In this algorithm the exploration is composed of two steps: a motion toward a location and a new observation of the environment at this location. The location is chosen among a set of candidate locations on the frontier between explored and unexplored space. This capability is exactly what we need for the exploration mode of the robot. Our robot comes with a rangefinder type laser scanner, a light projector, a camera, and a set of wheels. From all these capabilities, we identify:

• a LaserScan entity class with a ranges source providing laser ranges from the sensor;

• A ModeSelector entity that provides a graphical interface for the operator to choose the current mode of the robot;

• an Exploration entity that provides a source of twists for the robot;

• a Light and Camera entities that respectively enlighten the neighborhood and take pictures on request;

• a Wheel entity that can turn or roll on request;

Identifying main context operators: The most important activity of our robot is to move. Therefore we introduce a Motion context operator that produces a twist, representing the motion of the robot. Because our robot takes pictures and turns on its projector when it is in a zone with obstacles, we introduce an ObstacleZone context operator that indicates whether or not some obstacles are in the neighborhood.

Decomposing into lower-level pieces: The Motion context operator produces a twist based on which mode is selected and on the twist values coming from both modes. The selected mode is directly provided by the ModeSelector entity. We introduce a RandomMotion context operator that produces twists for the random mode. The twist for the exploration mode is directly provided by the Exploration entity. Both the ObstacleZone and RandomMotion context operators need the information about nearby obstacles. We thus introduce the ObstacleDetection context operator to indicate the proximity of an obstacle.

Identifying control operators: The Motion-Controller control operator takes information from the Motion context operator and transmits this information to the Wheel entity. The ObstacleManager control operator takes information from the ObstacleZone context operator and triggers the light and takes a picture with the camera.

Identifying data types: We have already seen that our application uses the notion of twist to indicate motion. A developer can define a twist as a pair of vectors which represent the linear and angular velocity. The robot current mode is represented as an enumeration of the RANDOM and EXPLORATION names. The ObstacleDetection context operator provides an Obstacle data type containing both a boolean to indicate if an obstacle is in front of the robot and a set of float numbers (the ranges) as provided by the laser scan giving details about the neighborhood.

C. Describing with DiaSpec

Once a developer decomposed the application using the different component types, the transcription to the DiaSpec design language is straightforward. Listing 1 gives an extract of the case study transcription.

In this listing, the entity, context, and controller keywords are respectively used to introduce In this section we saw how to design a robotics application using the SCC architectural pattern and the DiaSpec design language. Both the pattern and the language help decomposing an application in well defined components. Both make it easy to reuse as much as possible from the underlying middleware and existing applications. In the next section we discuss how to implement a robotics application with our approach.

III. IMPLEMENTING A ROBOTICS APPLICATION

The DiaSpec compiler generates a programming framework with respect to a set of declarations for entity classes, context operators and control operators (Figure 2). For each component declaration (entity or operator) the compiler generates an abstract class. The abstract methods in this class represent code to be provided by the developer (hole in Figure 2), to allow him to program the application logic (e.g., to trigger an entity action) (bump in Figure 2).

Implementing a DiaSpec component is done by subclassing the corresponding generated abstract class. In doing so, the developer is required to implement each abstract method. The developer writes the application code in subclasses, not in the generated abstract classes. This strategy contrasts with generating incomplete source code to be filled by the developer. As a result, in our approach, one can change the DiaSpec declarations and generate a new programming framework without overriding the developer's code. The mismatches between the existing code and the new programming framework are revealed by the Java compiler. To facilitate the implementation process, most Java IDEs are capable of generating class templates based on super abstract classes.

In this section, we give an overview of how to implement some parts of the case study. For a more detailed description, we refer to our previous works [START_REF] Cassou | Développement logiciel orienté paradigme de conception : la programmation dirigée par la spécification[END_REF]- [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF].

A. Implementing an operator

For each context or control operator a dedicated abstract class is generated in the programming framework. For each input source of this operator the generated abstract class contains an abstract method and a corresponding calling method. The abstract method is to be implemented by the developer while the calling method is used by the framework to call the implementation of the abstract method with the expected arguments.

Listing 2 presents a possible Java implementation of the RandomMotion context operator. The on-ObstacleDetection method is declared abstract in the AbstractRandomMotion generated super class.

Because an operator only manipulates input sources to produce a result, its implementation is independent of any robotics software framework. This facilitates operator reuse for different applications and robots.

B. Implementing an entity

Contrary to operators which are dedicated to the application logic, an entity is at the border between the application and its environment (e.g., the middleware and robot hardware). Implementing an entity thus requires some knowledge of the underlying middleware or hardware.

Listing 3 presents a possible Java implementation of the LaserScan entity class for the ROS middleware. When the middleware publishes a new laser scan message, this message is automatically received by the RosLaserScan instance through the ROS MessageListener interface.

Listing 4 presents a possible Java implementation of the Light entity class for the ROS middleware. The constructor receives a ROS publisher as a parameter which allows the entity implementation to send commands to the robot through the middleware.

C. Deploying an application

Deploying an application requires writing a deployment script in Java. To do this, a developer creates a new Java class by sub-classing the abstract class MainDeploy generated in the programming framework. By doing so the developer is required to implement one abstract method per component and to call the deployAll() method to trigger the deployment. The ROS middleware requires an implementation Listing 5. An extract of a developer-supplied Java deployment script for the case-study application IV. DISCUSSING DiaSpec decomposes the development of an application into two well defined stages: a design stage for which DiaSpec provides a domain-specific design language and an implementation stage for which DiaSpec provides a design-specific programming framework. With the design language and SCC architectural pattern, a developer is guided in creating components with a single responsibility each, thus enhancing reuse. An application design also explicits interactions between components making the runtime behavior easier to understand. With the programming framework dedicated to the design, a developer is guided in creating an implementation for each component. Indeed, the generated programming framework takes care of the control loop of the application as well as all interactions between the components. As a result, a developer can focus on implementing the high-level application logic, letting the framework handle the details. Moreover, the programming framework provides all necessary pieces of required information directly as parameters to the abstract methods. This reduces the amount of documentation required to start using the programming framework.

In the previous sections we saw that DiaSpec can be used to design, implement and deploy a robotics application for a widely used middleware. In the following we discuss various problems we have met while applying DiaSpec in a robotics setting.

A. DiaSpec Dynamicity

DiaSpec is capable of handling appearing and disappearing entities at runtime. For example the following code lets the Motion context operator subscribe to sources of information from the Exploration and ModeSelector entities:

@Override protected void postInitialize() {
discoverExplorationForSubscribe.all().subscribeTwist(); discoverModeSelectorForSubscribe.all().subscribeMode(); } This method has to be implemented in the Motion Java class (for the Motion context operator). The programming framework takes care of updating the subscription when a new entity appears or an existing entity becomes inaccessible. As a result, a new exploration mode or a new mode selector can be deployed at runtime. We believe that in a robotics settings where most, if not all, entities are known at deployment time this additional code is most of the time unnecessary. Indeed, this code could potentially be inferred automatically from the declaration of the Motion context operator and pushed inside the generated programming framework. However, in a multi-robots settings, where a robot can discover services provided by nearby robots, the DiaSpec entity discovery and subscription mechanisms could still be useful. The DiaSpec design language could be extended to let a developer declare which entities are known at deployment time and which ones should be discovered at runtime. The compiler could then leverage this additional information to generate the necessary code in the programming framework thus reducing the work required by the developers. We plan to investigate this issue in future works.

B. Data Type Reuse

DiaSpec allows the definition of new types (structures and enumerations) as well as the importation of existing Java types. Very often, a middleware such as ROS comes with its own data types. The developer must then choose to reuse the data types coming from the middleware or define new ones. Using the middleware data types can be particularly useful as these data types can be complex such as the ROS "twist" data type. This is the solution we use for the case study and the Twist data type as is illustrated by the use of the import keyword in Listing 1, line 1. However, choosing reuse of data types from a middleware tightly couples the application with this middleware and thus prevents potential for reuse of this application with other middleware. Another solution is to develop new data types in DiaSpec. This makes the application independent from any underlying middleware. However, this requires conversion code at the boundaries of the application where communication with the middleware is required. For example, it is possible to define the Twist data type within the design as follows: This solution makes the code harder to read and maintain. Moreover, similar code has to be duplicated everywhere in the application where a conversion is required. An intermediate solution is to develop new data types in Java. This solution can embed required conversions in the data type itself to avoid duplication. The resulting code is still harder to read than the first one however.

C. Decomposition grain

During the development of the case study we noticed that following the SCC architectural pattern and the steps proposed in Section II resulted in fine grained components, promoting reuse. It is however important that the developer pays attention not to create too fine grained components which would make the runtime behavior hard to understand and debug. Indeed, because the generated programming framework handles the interactions between the components, debugging very fine grained components requires stepping often into the generated programming framework. This is cumbersome and should not be needed. A possible addition to DiaSpec could involve a dedicated debugger which would let the developer debug his application without stepping into the generated programming framework.

Even with a dedicated development environment, too fine grained components make the system harder to understand. As a rule of thumb, a developer can start by creating a coarse grained component and can refine it when its implementation becomes complex, when the component requires a lot of interactions with other components, or when parts of its computation can be reused.

V. RELATED WORK

Several software engineering approaches have been proposed to lower the complexity of robotics systems [START_REF] Brugali | Software Engineering for Experimental Robotics[END_REF].

Middleware and Software Frameworks: Numerous middleware and software frameworks have been proposed to support the implementation of robotics applications (e.g., CLARATy [START_REF]CLARATy: robotic software framework[END_REF], ROS [START_REF]ROS: Robot Operating System[END_REF] and Player/Stage [START_REF] Toby | Player 2.0: Toward a practical robot programming framework[END_REF]). Such approaches attempt to cover as much of the robotics domain as possible in a single programming framework. This strategy often leads to large APIs, providing little guidance to the developer and requiring boilerplate code to customize the programming framework to the characteristics of the application. In contrast, a DiaSpec-generated programming framework specifically targets one application, limiting the API to methods of interest to the developers. Our code generator could potentially target these middleware thus leveraging existing work and hiding their intricacies from the developer.

Component-Based and Model-Driven Software Engineering: Component-Based Software Engineering for robotics (e.g., [START_REF] Brugali | Trends in component-based robotics[END_REF]) and Model-Driven Engineering for robotics (e.g., OMG RTC [START_REF]Omg rtc: Robotic technology component specification 1.0[END_REF], SmartSoft [START_REF] Schlegel | Robotic software systems: From code-driven to model-driven designs[END_REF]) relies on general-purpose notations such as UML to model domainspecific concerns. By using general-purpose and established notations, these approaches leverage existing knowledge from developers and existing tools. Even though such approaches propose a conceptual framework for developing robotics applications, they only provide the user with generic tools. For example, these approaches require developers to directly manipulate UML diagrams, which become "enormous, ambiguous and unwieldy" [START_REF] Picek | Model Driven Developmentfuture or failure of software development?[END_REF]. In contrast, DiaSpec abstracts away such technologies, limiting the amount of expertise required from the developers.

Domain-Specific Languages: Smach is a Python embedded DSL based on hierarchical concurrent state machines for building complex robot behavior from primitive ones [START_REF] Boren | The SMACH high-level executive [ROS News[END_REF]. Smach is tightly coupled with ROS, allows only static compositions of behavior and can not adapt compositions to new situations during execution. SmartTCL (Smart Task Coordination Language) is an extension of Common Lisp that is used to do on line dynamic reconfiguration of the software components involved in a robot [START_REF] Steck | Managing execution variants in task coordination by exploiting design-time models at run-time[END_REF]: knowledge bases, simulation engines, symbolic task planners, models and low-level hardware. At design time, the developer defines execution variants that robot operates at runtime. In order to lower robotics inherent complexity, analysis and simulation tools could also be used at runtime to determine pending execution steps with specific parametrisation before the robot effectively execute them. Unlike these DSLs, DiaSpec allows a natural decomposition of applications according to the SCC architectural pattern, guiding the work of the developer. Compared to SmartTCL DiaSpec lacks the ability to recompose the components at runtime.

VI. CONCLUSIONS AND FUTURE WORKS

In this paper, we have proposed to use DiaSpec, a domainspecific design language for Sense/Compute/Control applications, in a robotics setting. We have shown how this language allows a developer to structure an application in fine-grained and reusable components by following the SCC architectural pattern. Developing a complex application shows the benefits of such an approach regarding reuse of existing software components and diminution of complexity for the developer. We have also highlighted problems we have met during the development of a standard robotics application.

Being able to adapt a robotics system to different capabilities and resources is a key issue in software engineering for robotics. For example, a robot can perform two similar missions differently with different resources. Our approach facilitates changes to a robotics system by making explicit the software components and their interactions. However supporting static adaptation is insufficient in a robotics setting as robots need to dynamically adapt to resource evolutions (e.g., failures and environment) while performing their tasks. Resource-adaptive architectures address dynamic adaptations. However, such architectures are ad hoc solutions that developers can hardly reuse and scale. Therefore, an ideal robot control architecture should be resource-adapting, i.e., an architecture that explicitly manages and represents resources [START_REF] Bouraqadi | Towards an adaptive robot control architecture[END_REF]. The main perspective of this work is to introduce such dynamic variability inside DiaSpec.

Fig. 1 .

 1 Fig. 1. The case study decomposed into the different type of components of DiaSpec

Fig. 2 .

 2 Fig. 2. Overview of the DiaSpec development process

  Twist as org.ros.message.geometry_msgs.Twist; 2 structure Obstacle { isDetected as Boolean; } 10 entity Exploration { source twist as Twist; } 11 entity ModeSelector { source mode as RobotMode; } 12 context ObstacleDetection as Obstacle { Listing 1. An extract of the description of the robotics application with the DiaSpec design language

	3	ranges as Float[]; }
	4 enumeration RobotMode { RANDOM, EXPLORATION }
	5 action OnOff { on(); off(); }
	6 entity Light { action OnOff; }
	7 entity LaserScan {
	13	source ranges from LaserScan;
	14 }
	15 context ObstacleZone as Boolean {
	16	context ObstacleDetection;
	17 }
	18 context RandomMotion as Twist {
	19	context ObstacleDetection;
	20 }
	21 context Motion as Twist {
	22	source mode from ModeSelector;
	23	context RandomMotion;
	24	source twist from Exploration;
	25 }
	26 controller MotionController {
	27	context Motion;
	28	action TurnAndRoll on Wheel;
	29 }
				Developer's implementation
		DiaSpec declarations	Compiler	Programming Framework

1 import 8 source ranges as Float[]; 9

  Then, an implementation of the Wheel entity would have to convert from the DiaSpec Twist type to the ROS Twist type:

	structure Vector3 { x as Float; y as Float; z as Float; }
	structure Twist { linear as Vector3; angular as Vector3; }
	private org.ros.message.geometry_msgs.Twist
	convert(Twist twist) {
	org.ros.message.geometry_msgs.Twist rosTwist;
	rosTwist = new org.ros.message.geometry_msgs.Twist();
	rosTwist.angular = convert(twist.getAngular());
	rosTwist.linear = convert(twist.getLinear());
	return rosTwist;
	}
	private org.ros.message.geometry_msgs.Vector3
	convert(Vector3 vector) {...}

http://www.ros.org/wiki/

http://www.ros.org/wiki/explore

VII. ACKNOWLEDGMENTS

The authors gratefully acknowledge the INRIA Phoenix research group who granted the authors the authorization of use of DiaSuite, a tool suite which includes DiaSpec.

Figure 3 presents a running simulation of our case study. The code generated is integrated in the ROS middleware and the execution can be analyzed by the tools provided by ROS.

In this section we saw how to implement a robotics application on top of a programing framework generated by the DiaSpec compiler. This programming framework calls developer's code when necessary and make the development easy by passing everything the developer needs as a parameter to abstract methods. In the next section we discuss the benefits and problems of using DiaSpec in a robotics setting.


Damien Cassou

Emilie Balland

Charles Consel

Julia Lawall

Leveraging Software Architectures to Guide and Verify the Development of Sense/Compute/Control Applications

Keywords: D.2.11 [Software Engineering]: Software Architecturesdomain-specific architectures, languages, patterns Design, Languages, Verification Generative programming, architectural conformance

A software architecture describes the structure of a computing system by specifying software components and their interactions. Mapping a software architecture to an implementation is a well known challenge. A key element of this mapping is the architecture's description of the data and control-flow interactions between components. The characterization of these interactions can be rather abstract or very concrete, providing more or less implementation guidance, programming support, and static verification.

In this paper, we explore one point in the design space between abstract and concrete component interaction specifications. We introduce a notion of interaction contract that expresses allowed interactions between components, describing both data and control-flow constraints. This declaration is part of the architecture description, allows generation of extensive programming support, and enables various verifications. We instantiate our approach in an architecture description language for Sense/Compute/Control applications, and describe associated compilation and verification strategies.

INTRODUCTION

A Sense/Compute/Control (SCC) application is one that interacts with the physical environment [START_REF] Taylor | Software Architecture: Foundations, Theory, and Practice[END_REF]. Such applications are pervasive in domains such as building automation, assisted living, and autonomic computing. Developing an SCC application is complex because the implementation must address both the interaction with the environment and the application logic, because any evolution in the environment must be reflected in the implementation of the application, and because correctness is essential, as effects on the physical environment can have irreversible consequences.

We have observed that SCC applications can be defined according to an architectural pattern involving four kinds of components, organized into layers [START_REF] Edwards | Architecture-driven self-adaptation and self-management in robotics systems[END_REF]: (1) sensors at the bottom, which obtain information about the environment;

(2) then context operators, which process this information;

(3) then control operators, which use this refined information to control (4) actuators at the top, which finally impact the environment. Data and control-flow interactions between these layers are restricted. Sensors may be proactive and initiate data flows when they detect changes in the environment, while the other kinds of components are only reactive. Context operators may receive information from sensors or other context operators, and may interrogate the same, to obtain further information. Control operators can receive information only from context operators and actuators are only activated by orders, such as "turn on" or "send this email", sent by the control operator layer. While our experience shows that this SCC architectural pattern captures the architecture of many kinds of SCC applications, the question remains of how to exploit it to guide an implementation.

When a software architecture is expressed formally using an Architecture Description Language (ADL) [START_REF] Medvidovic | A classification and comparison framework for software architecture description languages[END_REF], and is sufficiently concrete, it may be possible to generate an implementation automatically. But this requires providing a complete description of the application behavior in the architecture, which mixes concerns, obscures the interaction constraints, and defeats reusability. In particular, the SCC architectural pattern describes application design at a more abstract level, in that it does not incorporate the application logic. Mapping such an abstract software architecture into an implementation and maintaining the relationship between the architecture and the implementation as they evolve are well known to be complex tasks [START_REF] Taylor | Software Architecture: Foundations, Theory, and Practice[END_REF].

Several recent approaches have considered the relation between architecture and implementation, focusing on the interaction between components. One such approach is Arch-Java that embeds an ADL into a programming language to allow architectural concerns to be part of the application code [START_REF] Aldrich | ArchJava: connecting software architecture to implementation[END_REF]. This approach however, entails a mixing of the architecture and implementation that may obscure both of them. To regain separation of concerns between architecture description and implementation, Archface proposes a new interface mechanism [START_REF] Ubayashi | Archface: A contract place where architectural design and code meet together[END_REF], leveraging concepts from Aspect-Oriented Programming (AOP) to describe component interactions. AOP pointcuts abstract the structure of implementations, providing constraints such as when a particular method must be called during a given control flow. Such approaches make it possible to verify that an implementation conforms to an architecture description. Still, both of these approaches blur the separation between architecture description and implementation, making the architectural design phase more difficult.

In this paper, we propose an approach to linking architecture and implementation that specifically targets SCC applications. Our approach balances the abstraction and concreteness of the architecture description by introducing a notion of interaction contract. An interaction contract declares what interactions a given component can perform, expressing in high-level terms both data and control-flow constraints. This declaration is part of the architecture description, keeping this phase separated from the implementation. Yet, our interaction contracts allow the architect to precisely specify the interactions between components, without simultaneously having to reason about code structure. Interaction contracts furthermore can be used to generate extensive programming support, ensuring the conformance between the architecture and the implementation and guiding the development phase. The architect can also use the constraints expressed by interaction contracts to verify a range of properties beyond implementation conformance.

Contributions.

In this paper, we introduce an architecturedriven generative methodology that improves the design, programming and verification of SCC applications. Our contributions are as follows.

• We introduce a language for interaction contracts dedicated to SCC applications (Section 2). • We show that interaction contracts can guide the implementation of SCC applications by enabling the generation of highly customized programming frameworks using a dedicated compiler (Section 3). This approach ensures that the architecture conforms to the implementation, while facilitating software evolution. • We show that such interaction contracts are precise enough to verify safety properties such as information flow reachability or interaction invariants (Section 4). • We extend our previously developed implementation of an ADL targeting SCC applications [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF] with interaction contracts, and use this implementation to assess the benefit of interaction contracts at a conceptual level and in terms of metrics on the resulting code (Section 5).

OUR APPROACH

We first present the SCC architectural pattern [START_REF] Edwards | Architecture-driven self-adaptation and self-management in robotics systems[END_REF] and then introduce the notion of interaction contract. The SCC architectural pattern is based on the sense/compute/control pattern presented by Taylor et al. [START_REF] Taylor | Software Architecture: Foundations, Theory, and Practice[END_REF] and on the pattern presented by Chen and Klotz [START_REF] Chen | Context aggregation and dissemination in ubiquitous computing systems[END_REF] for ubiquitous computing systems. Interaction contracts enrich the SCC architectural pattern to describe interactions among components.

SCC Architectural Pattern

We first introduce the terminology and concepts used throughout the paper. The data flow of the SCC architectural pattern is expressed by an oriented graph whose nodes are the architecture components and whose (solid) edges indicate data exchange between components (see Figure 1). We say that the children and parents of a component are respectively the sources of the incoming edges and targets of the outgoing edges connected to the component. There are two types of interactions a component can perform: pushing data to the parents or responding to a pull request from one of its parents. Pull requests are represented in the graph as dashed edges, and can be parameterized.

The SCC application pattern involves four layers: sensors, context operators, control operators, and actuators. Each layer corresponds to a separate class of components:

• Sensors send information sensed from the environment to the context operator layer through data sources.

Sensors can both push data to context operators and respond to context operator requests. We use the term "sensor" both for entities that actively retrieve information from the environment, such as system probes, and entities that store information previously collected from the environment, such as databases. Sensors are proactive or reactive components whereas context operators, control operators and actuators are always reactive. These properties ensure that SCC applications are reactive to the environment state. That is, all computation is initiated by a publish/subscribe interaction with a sensor.

As the underlying architecture is component-based, the application can be fully distributed. To prevent concurrent handling of events in a component, all interactions of a component are queued and executed one at a time, sequentially.

Example

As a running example, we define the architecture of a web server monitoring application. In this SCC application, the considered environment is a tier system, consisting of a web server and associated network tools. The two tasks that we want to implement are (1) updating a log containing profiles of the web server's clients (client name and IP address) and (2) sending an email to administrators in case of intrusions. Figure 1 illustrates the component layers and the data-flow interactions between the components of this application.

Sensors. The state of the environment is observed using three sensors. 1) The access log reader provides one information source named line. This information source is updated when a new line is added to the log for an access to the server. 2) The NSLookup tool returns the host name associated with an IP address via the information source named ip2host. 3) The LDAP server returns the profile of a host name via the information source named host2profile.

Context operators for profile identification. The Access-ingProfile context operator, in the middle of Figure 1, calculates which profile is accessing the web server. This context operator is activated by the AccessLogParser context operator, which is itself activated by the information source line of the AccessLogReader sensor. When a new line is added to the log, AccessLogParser parses the line to create a higher-level structure including the IP address of the person accessing the web server, and the requested page. This information is passed to AccessingProfile, which extracts the IP address from the structure, and then asks the IP2Profile context operator to compute a profile. This profile is obtained by querying the NSLookup and the LDAPServer sensors. Pull requests on IP2Profile and NSLookup are parameterized by an IP address. Pull requests on LDAPServer are parameterized by a host name.

Context operators for intrusion detection. The Intrusion-Detector context operator uses the context calculated by

AccessingProfile, including the information about the most recent access to the web server and the client profile associated with this access. IntrusionDetector only propagates accesses that are suspected to represent intruders.

Control operators and actuators. The monitoring tasks are implemented by the IntrusionInformer and ProfileLogger control operators, which respectively invoke the Mailer and Logger actuators using the send and log actions. To notify the administrator of an intrusion, IntrusionInformer only needs to be informed by the IntrusionDetector context operator of any new intrusion. To update the profile log, ProfileLogger only needs to be informed by the AccessingProfile context operator of which profile is accessing the server.

In this example, we can observe that the architecture description in Figure 1 is underspecified. While it may be intuitively obvious that the IP2Profile context operator reacts only to parent pull requests, as LDAPServer and NSLookup never push data by themselves, this information is not explicit in the architecture description. This underspecification may lead to different interpretations of the architecture description and incompatible implementations. To address these issues, we enrich the architecture description by annotating each context operator with an interaction contract.

Interaction Contracts

The goal of an interaction contract is to describe the interactions that are allowed by the context operators of an SCC application. In a reactive system, the most basic information is what makes a context operator react, i.e., a data pull request from one of its parents or a data push from its children. In this reaction, a context operator may need to pull data from its child context operators or child sensor sources. Finally, a reaction may or may not lead to the push of a new value. We group the information about these three kinds of interactions into a basic interaction contract.

Definition 1. A basic interaction contract A; U ; E is a tuple where A, U and E are named respectively the activation condition, the data requirements list and the emission. These elements are defined as follows: An interaction contract defines how a context operator interacts with its parents and children, and in this sense is related to interaction descriptions such as automata-based models [START_REF] Alfaro | Interface automata[END_REF][START_REF] Lynch | Hierarchical correctness proofs for distributed algorithms[END_REF], as analyzed in Section 6. Table 1 specifies the interaction contracts for the web server monitoring architecture. For example, the interaction contract of the IntrusionDetector indicates, via the notation ⇑ self ?, that when IntrusionDetector receives a new profile from AccessingProfile, it might or might not push a profile. In practice, IntrusionDetector only pushes a profile when the profile is suspected to correspond to an intrusion. In contrast, the emission of the interaction contract associated with IP2Profile is ∅. When this component receives a pull request, it returns the data to the parent that sent the request, but it does not inform the other parents, if any, by publishing the data.

• A = ⇑ (A1, . . . , An) | ⇓ self , where n > 0, Ai
Synchronization. A sequence ⇑ (A1, . . . , An) in the activation condition of an interaction contract indicates the synchronization of multiple information sources. Suppose that the context calculated by the AccessLogParser context operator were refined into two types of contexts: the geographic location of the host and the web browser used for this access, represented by the context operators LocalizationCalc and WebBrowserCalc, respectively (see Figure 2). The information calculated by these context operators is then combined using a new context operator InfoCalc. Its interaction contract is ⇑ (WebBrowserCalc, LocalizationCalc); ∅; ⇑ self , which ensures that we obtain synchronised information from LocalizationCalc and WebBrowserCalc. Disjunction. A disjunction of names in an activation condition indicates that a context operator can use any one of multiple distinct contexts. For example, in a web server, a dangerous access can be due either to an intrusion or to an SQL injection. The information about both conditions has the same type, Access. Suppose we have a new context operator SQLInjDetector that pushes Access data when there is an SQL injection. Then, we can define a DangerDetection context operator that abstracts over these two types of danger using the interaction contract: ⇑ (IntrusionDetector ∨ SQLInjDetector); ∅; ⇑ self Interaction contract composition. As a context operator can be activated by different conditions, possibly leading to different behaviors, we introduce the operator that allows the combination of several basic interaction contracts. A composition of basic interaction contracts is, for example, necessary when a context operator can be activated by both a data pull from one of its parents and a data push from one of its children. For example, the AccessingProfile context operator could have a second interaction contract ⇓ self ; ∅; ∅ that allows access to the most recent value of this context at any moment in the execution of the application.

Architecture Consistency and Determinacy

An interaction contract of a context operator implies interaction requirements on the operator's parents and children. For example, given a context operator A, the existence of some interaction contract whose data requirement is ⇓ A implies that A has an interaction contract whose activation condition is ⇓ self . An architecture is consistent when each of its interaction contracts respects the requirements imposed by all other interaction contracts of the architecture.

Furthermore, a given data flow should not trigger the activation of multiple basic interaction contracts of a single context operator. This situation occurs, for example, if the activation conditions of two different interaction contracts of a single context operator are both pull requests. An architecture is deterministic if no context operator has a pair of basic interaction contracts that are activated by the same data flow.

Given a basic interaction contract A; U ; E , let names(A) be the set of names of sensor sources or context operators (self included) used in A. For example, names(⇑

(P ∨ Q, R)) = {P, Q, R} and names(⇓ self ) = {self }.
Definition 2 (Contract Consistency). Given an architecture ∆, an interaction contract α is consistent relative to ∆ if one of the following conditions is satisfied:

• if α = A; ⇓ (B1, . . . , Bm); E then:
for each Bi that is a context operator, there is a behavioral contract ⇓ self ; _; _ associated with Bi in ∆, if A = ⇑ (. . .) then for each N ∈ names(A) that is a context operator, there is an interaction contract _; _; ⇑ self or _; _; ⇑ self ? associated with N in ∆.

• if α = α1 . . . αn then each αi is consistent relative to ∆.

Definition 3 (Architecture Consistency). An architecture ∆ is consistent if each interaction contract associated with its context operators is consistent relative to ∆.

Definition 4 (Contract Interference). A basic interaction contract A; U ; E interferes with a basic interaction contract

A ; U ; E if names(A) ∩ names(A ) = ∅.
Definition 5 (Contract Determinacy). An interaction contract α1 • • • αn is deterministic if each basic interaction contract αi does not interfere with any of the others.

Definition 6 (Architecture Determinacy). An architecture is deterministic if all its interaction contracts are deterministic.

To ensure consistency and determinacy of an architecture, the architecture compiler should enforce these properties.

Interaction Contract Semantics

A context operator can be viewed as a function, as it reacts to some inputs and potentially produces an output. Thus, the denotational semantics of an interaction contract is a function type. Intuitively, each possible implementation of a context operator, whose interaction contract is C, corresponds to a function of type C , as defined in Table 2. In this table, O represents a context operator and T its return type. Essentially, the activation condition and the data requirements determine the types of the parameters of this function, and the emission determines its return type. Each data requirement maps to the type of a callback function that takes the request parameters as arguments. If a context operator is associated with several interaction contracts (denoted C1 . . . Cn), then the type of the context operator is represented as a tuple of functions C1 × . . . × Cn .

The rules in Table 2 use the functions args, publish, typeof, and access_typeof, defined as follows. Given an identifier n that is the name of a context operator or a sensor source, the function typeof (n) maps n to its type. For example, in the web server application:

typeof (line) = String typeof (AccessLogParser) = Access typeof (AccessingProfile) = Profile Note that typeof (A1 ∨ A2) = typeof (A1) ∪ typeof (A2)
where ∪ denotes the operator for the union type (in Java, for example, t1 ∪ t2 is the smallest common supertype of t1 and t2, which is at worst the type Object). The function access_typeof (n) maps n to the type of a data pull request: where args(n) returns the types of the parameters needed for a pull request on n. For example,

access_typeof (n) = args(n) → typeof (n) ⇑ (A1, . . . , An); ⇓ (B1, . . . , Bm); ⇑ self = Π n i=1 typeof (Ai) × Π m i=1 access_typeof (Bi) → T ⇑ (A1, . . . , An); ⇓ (B1, . . . , Bm); ⇑ self ? = Π n i=1 typeof (Ai) × Π m i=1 access_typeof (Bi) × publish(T ) → () ⇑ (A1, . . . , An); ⇓ (B1, . . . , Bm); ∅ = Π n i=1 typeof (Ai) × Π m i=1 access_typeof (Bi) → () ⇓ self ; ⇓ (B1, . . . , Bm); E = args(O) × Π m i=1 access_typeof (Bi) → T if E = ⇑ self or E = ∅ ⇓ self ; ⇓ (B1, . . . , Bm); ⇑ self ? = args(O) × Π m i=1 access_typeof (Bi) × publish(T ) → T C1 . . . Cn = C1 × . . . × Cn
access_typeof (ip2host) = IPAddress → String access_typeof (host2profile) = String → Profile
Finally, given a type T , we denote by publish(T ) the type T → (), which is the type of a function that publishes data of type T .

In the web server example, the denotation of the interaction contract ⇑ (AccessLogParser); ⇓ (IP2Profile); ⇑ self associated to AccessingProfile is the function type Access × (IPAddress → Profile) → Profile.

Design Support

The architectural pattern presented here is to be used as a paradigm guiding the architect in the decomposition of an SCC application into layers of components. The interaction contracts enable an architect to describe the allowed interactions among components. Interaction contracts are limited to the kinds of interactions possible within the SCC architectural pattern, further guiding the architect.

PROGRAMMING SUPPORT

We have integrated interaction contracts into DiaSpec, our domain-specific ADL for SCC applications [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF]. From a DiaSpec description, a compiler produces a dedicated Java programming framework that is both prescriptive and restrictive: it is prescriptive in the sense that it guides the developer, and it is restrictive in the sense that it limits the developer to what the architecture allows. In this section, we describe the compilation strategies that achieve this.

Structure of the Generated Code

Our compiler takes as input an architecture description written in the DiaSpec ADL. This specification describes textually an instance of the SCC architectural pattern and the associated interaction contracts. From this architecture description, the compiler generates a dedicated programming framework containing support for sensors, context operators, control operators, and actuators. We focus on the code generated for interaction contracts as the other parts of the framework have been described previously [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF].

For each context operator declared in the architecture description, the compiler generates an abstract class. The abstract methods in this class represent code to be provided by the developer, to allow him to program the application logic (e.g., to answer a pull request). To implement the context operator, the developer implements these methods in a subclass of this abstract class.

For each basic interaction contract, the generated abstract class contains an abstract method and a corresponding calling method. The abstract method is to be implemented by the developer while the calling method is used by the framework to call the implementation of the abstract method with the expected arguments. The translation of each interaction contract of the architecture into an abstract method is similar to the denotation found in Table 2. Callbacks are used to encapsulate an optional interaction between the context operator and its parents or one of its children. The developer may decide to invoke each callback depending on his needs. A callback is only provided when an interaction is optional. If the interaction is mandatory, it is automatically done by the calling method. If the interaction is forbidden, the calling method does not provide the developer with any means to perform the interaction.

Interaction Contract Compilation

To illustrate the compilation process, we consider the Java code generated for some of the interaction contracts of the web server monitoring architecture (see Table 1).

The AccessingProfile interaction contract is compiled into the following abstract method:

abstract IdentifiedAccess onNewAccessLogParser(Access newAccess, PullFromIP2ProfileCallback ip2Profile);

The name of this abstract method starts with onNew, reflecting the fact that the child is providing a new value. The method's first parameter represents the new parsed line and the second parameter represents a callback function that permits a pull interaction with IP2Profile. This callback takes an IPAddress as argument and returns a corresponding Profile. The return type of the onNewAccessLogParser abstract method forces the implementation of the abstract method to return a profile, which is pushed automatically by the calling method upon method return.

IP2Profile is a kind of database that can only be accessed through pull requests with an IPAddress as an argument. From its interaction contract, the following abstract method is generated: abstract Profile get(IPAddress newIPAddress, PullFromNSLookupCallback ip2Host, PullFromLDAPServerCallback host2Profile);

The name of this abstract method is get, reflecting the fact that the parent requested a value. The implementation of this abstract method may call two sources through corresponding callbacks. Because the emission is ∅, IP2Profile returns a result only to its requesting parent, i.e., IP2Profile does not push its value and has no way to do so. From the interaction contract of IntrusionDetector, the following abstract method is generated: abstract void onNewAccessingProfile( IdentifiedAccess newIdentifiedAccess, PublishCallback publish);

Not all identified accesses arriving at IntrusionDetector are necessarily intrusions. The publish callback allows the application logic in the method implementation to decide whether to give an alert about an intrusion.

Synchronization. From the interaction contract of InfoCalc, ⇑ (WebBrowserCalc, LocalizationCalc); ∅; ⇑ self , the following abstract method is generated:

abstract Info onNewWebBrowserCalcAndLocalizationCalc( WebBrowser newWebBrowser, Localization newLocalization);

This method is to be called with both values from the children as soon as they are both present. Various strategies can be used to implement this kind of synchronization: one approach is to remember only the most recent value from each source, while another is to enqueue all values. Our default implementation uses a queue for each source. When each queue has at least one value, the framework consumes one value from each queue and invokes the abstract method on the resulting tuple of values. This implementation may be changed by the developer.

Disjunction. From the interaction contract of DangerDetection, ⇑ (SQLInjDetector ∨ IntrusionDetector); ∅; ⇑ self , the following abstract method is generated:

abstract IdentifiedAccess onNewDisjunction( IdentifiedAccess newIdentifiedAccess);

This method has just one parameter to represent the disjunction. The generated framework calls this method each time data is sent from either SQLInjDetector or Intrusion-Detector.

Callbacks. As noted above, we use callbacks to implement optional interactions with parents and children. Each callback is implemented as an internal Java class, in the abstract class of the context operator, and contains a single method. For example, PullFromIP2ProfileCallback is defined as: Callbacks are instantiated by the calling method, which passes them to the abstract method. To ensure that the declared interaction contracts are respected, we have to ensure that a callback is not invoked after executing the code implementing the abstract method. I.e., the developer must not store the callback for later use. Currently, this property is not enforced statically, as it would require adapting a Java compiler. Instead, we provide a dynamic guard to prevent this situation at runtime. This dynamic guard is implemented as a private boolean variable in the internal class whose value is checked before executing the callback. The dynamic guard could also be extended to prevent the developer from calling a callback more than a given number of times, e.g., to limit resource usage.

Programming Support

The generated programming framework guides the developer with respect to the architecture description. Implementing a declared component is done by subclassing the corresponding generated abstract class. In doing so, the developer is forced to implement each abstract method. To facilitate this process, most IDEs (such as Eclipse) for objectoriented languages generate class templates based on abstract super-classes. The generated framework passes each required piece of information as an argument to the method. These arguments free the developer from having to guess method or class names. The following code presents a partial implementation as could be written by the developer of the AccessLogParser context operator. The method onNewLine is automatically called by the programming framework when a new line arrives from an instance of AccessLogReader. This method is typical of what has to be implemented by the developer. Because most of the interaction details are abstracted away by the generated framework, the developer can concentrate on the application logic. For example, the decision of whether or not to publish an Access value, and which components are interested in this value, is abstracted away from the implementation: on line 8, the developer simply returns the new value without having to know what will happen to it.

Ensuring Conformance

An implementation must conform to its architecture. There are three basic conformance criteria: decomposition, interface conformance and communication integrity [START_REF] Luckham | An event-based architecture definition language[END_REF].

Decomposition. "For each component in the architecture, there should be a corresponding component in the implementation." This property is satisfied in the sense that at least an abstract class is generated for each component; nevertheless, the framework is not able to force the developer to implement the full set of abstract classes.

Interface Conformance. "Each component in the implementation must conform to its architectural interface." Our compiler generates an abstract class that conforms by construction to the component description. By extending the abstract class, the component implementation automatically also conforms to this description.

Communication Integrity. "Each component in the implementation may only communicate directly with the components to which it is connected in the architecture." This property is satisfied because: (1) an interaction only happens during the execution of an onNew or get method, and only through the provided callbacks. (2) A component never gains a direct reference to another component, and thus it can never give such a reference to another component.

Support for Evolution

Maintenance and evolution are important parts of the development of any software system. Our code generation strategy limits the number of code changes required when the architecture description changes. When this happens, the framework can be regenerated without overwriting the developer's implementation. Any mismatches between the existing code and the new programming framework are revealed by the Java compiler. This strategy contrasts with strategies based on generating source code skeletons to be filled by the developer, which mix manually-written and generated code. In many of these strategies, regenerating a skeleton overwrites the developer's implementation.

VERIFICATION SUPPORT

In SCC applications, safety is a key requirement as unexpected behaviors can directly impact the environment and users through actuators. Interaction contracts make explicit valuable information about the data flow in the design and allow design-time safety verifications. For example, with interaction contracts, it is possible to know at design time all the context operators that will eventually be activated by the publication of a given source. Moreover, our generative approach ensures that these properties will be preserved at the implementation level. To illustrate the possible design-time analyses, we consider two kinds of properties:

• Data reachability: can a component unexpectedly access critical data from a sensor or a context operator? For example, personal information about a customer should not be displayed on a screen in a public building. • Interaction invariants: does data sensed from a given sensor always lead to a particular action? For example, sensing a fire should always cause an alarm to go off.

Data Reachability

In graph theory, a vertex y is said to be reachable from a vertex x when there is a path from x to y. In our case, data reachability properties are of type "A must not access B" or "A may access B." Checking such properties is required to ensure that, for example, private information cannot be compromised or to identify the potential impact of a sensor failure (e.g., a power outage) on the rest of the application.

We define data reachability from a component in the SCC architectural pattern by using the interaction contracts. Definition 7 (Data Reachability). Given a component C and name n of a sensor source or a context operator, the data associated with n is reachable from C if one of the following conditions is satisfied:

• C = n or • C is a context

operator and its interaction contract

A; U ; E is such that n is reachable from at least one of the names contained in names(A) ∪ names(U ) or • C is an actuator or a control operator and n is reachable from one of its children.

Consider an extension of the web server monitoring example where a dedicated public web page displays the top five most visited URLs. This top five is calculated from the data provided by the AccessLogParser. By applying Definition 7, we check that the user profiles calculated by AccessingProfile are not reachable from the actuator that updates the web page and thus these profiles cannot be published in this public web page. When there does exist an undesirable reachability path, the information in this path can guide the architect in fixing the interaction contracts.

Interaction Invariants

Interaction invariants are properties that are verified at any state of the SCC application. For example, we would like to ensure that the ProfileLogger is always activated whenever someone accesses the web server. We characterise the progress of an SCC application by its data flow and we use LTL [START_REF] Huth | Logic in Computer Science: Modelling and reasoning about systems[END_REF] (Linear Temporal Logic) formulae to characterise interaction invariants.

For example, the property on the web server can be specified by the following LTL formula:

(NewLine → (3ProfileLogger_Activated))
where the predicate NewLine is true if a new value for the line source of AccessLogReader is pushed and the predicate ProfileLogger_Activated is true if ProfileLogger is activated by a new profile. This property can be understood as: "At any moment ( ), if a new line is pushed, then the ProfileLogger will eventually (3) be activated."

To check the LTL invariants, we use the SPIN model checker associated with the Promela modelling language [START_REF] Holzmann | The SPIN Model Checker: Primer and Reference Manual[END_REF]. If an invariant is not satisfied, SPIN gives a counterexample in the form of an execution trace. This counterexample can guide the architect in fixing his interaction contracts. To check the above invariant, we translate each interaction contract of the web server monitoring example into a Promela process. For example, the interaction contract ⇑ (AccessLogParser); ⇓ (IP2Profile); ⇑ self associated to the AccessingProfile context operator is mapped into the following Promela process specification: Each interaction contract is mapped into a process and each component interaction is mapped into a channel. Also, each activation condition is mapped into a conditional expression (line 4) which is true if there is a new value in the channel. Each data requirement is mapped into a sequence of two instructions: one for the transmission of the request (line 5) and one to receive the corresponding response (line 6). Finally the emission is translated into a message send (line 7). The do/od statement is a loop construct that encodes the reactivity of context operators. 1 The Promela specification is automatically generated from the interaction contracts. Currently, we are working on the translation of counterexamples given by SPIN into high-level explanations.

Verification Support

Data reachability and interaction invariants are two examples that show how the architecture specification makes core concepts explicit and thus facilitates high-level safety analyses on the data flow. These design-time analyses support the architect by giving counterexamples. The same properties do not have to be checked again on the implementation because the implementation is guaranteed to conform to the design.

EVALUATION

This section gives an overview of the tool suite into which we have integrated interaction contracts, and discusses the measured benefits of this integration.

A Working Tool Suite

Previously, we have developed a Domain-Specific Language (DSL), DiaSpec, to express architecture descriptions that follow the SCC architectural pattern [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF]. This DSL is supported by a tool suite, DiaSuite, providing code generation and related functionalities. The code generator translates a DiaSpec description into a Java programming framework. Applications developed using this generated programming framework can be deployed using any of the communication protocols supported by the available back-ends, which currently comprise X10, UPnP, RMI and SIP. DiaSuitecompatible drivers have been implemented for hardware such as the iPod touch, various types of RFID tags and the Axis networked camera. Applications can furthermore be tested prior to deployment using a 2D simulator, requiring no change in the operator implementations. DiaSuite has been used to develop applications in areas including home/building automation, tier-system monitoring and avionics. 2Our experiences in using DiaSuite have motivated development of interaction contracts. Integration of interaction contracts into DiaSuite requires extending the DiaSpec language, and correspondingly extending the code generator to take into account the new constructs. The resulting generated code follows the denotational semantics presented in Section 2.5 and the class structure presented in Section 3.1

Benefits of Interaction Contracts

To assess the interaction contracts, we have conducted studies with 20 groups of 3 undergraduate computer science students each. The students had no prior experience with our tool suite or SCC. We gave each group the original version of DiaSuite [START_REF] Cassou | A generative programming approach to developing pervasive computing systems[END_REF] that did not include the interaction contracts. We also gave all groups the same diagram, similar to that of Figure 1: they had to translate it into DiaSpec and then implement the project. All groups designed a working architecture and most completed the assignment with an implementation. The experiment revealed some shortcomings in DiaSpec. The rest of this section presents these shortcomings and how interaction contracts resolve them.

Design support. In the original version of DiaSpec, the architect declared connections between components without specifying the permitted interactions, as was illustrated with the solid arrows in Figure 1. In particular, the architect did not specify whether a component is to be accessed through a push or a pull mechanism. This imprecision lead to different interpretations of the same architecture, and thus different implementations, some outside of the original expectations of the architect. With the introduction of interaction contracts, the architect precisely expresses the allowed interactions.

Programming support. We intentionally did not give students any documentation about the generated framework, to be able to determine to what extent this framework was in itself able to guide the implementation. The students thus had to search in the generated code for the methods of interest to perform component interactions. Using the original version of DiaSpec, there are twice as many of these methods as necessary, because the code generator is unable to determine the intent of the architect, and thus must generate code for both a push and a pull interaction between every pair of connected components. Our interaction contract compiler generates abstract methods that are self-contained: implementing them only requires using the arguments and returning a result. Furthermore, the only abstract methods generated are those that support the interactions intended by the architect.

Verification support. Without the interaction contracts, the verification support is limited. We first consider reachability properties. Data reachability is entirely determined by the parent-child relationship in the data-flow graph, and thus the set of data reachable from a given component is not affected by the addition of the interaction contracts. Nevertheless, the introduction of interaction contracts allows giving more precise counterexamples in the case of reachability property violations, as the counterexample can include the precise sequence of activation conditions. On the other hand, most interaction invariants, such as the one shown in Section 4, cannot be ensured without the interaction contracts as there is no guarantee that a component publishes a value.

Measuring Programming Support

To measure the impact of interaction contracts on the degree of programming support provided, we use several metrics on a representative set of applications, such as the web server monitor, an anti-intrusion system and a home remote-control application. These applications are implemented with and without interaction contracts. To perform these measurements, we use Sonar,3 a platform that uses various metrics to guide developers in improving source code quality. As there is little variation in the measurements for the different applications, we present only averages.

Program size. For each application, we have compared both handwritten and automatically generated number of lines of code with the number of lines in the architecture description, the implementation and the framework. Table 3 presents these results. The ratio of code for the architecture description (column Arch.) increases slightly, because the architect must now write the interaction contracts. The ratio of code for the implementation (column Implem.) decreases, in part because methods corresponding to useless interactions do not have to be implemented, and in part because some functionalities, such as the handling of synchronization (Section 2.3) are moved from the implementation to the generated code, requiring less programming effort from the application developer. Finally, the ratio of generated code (column Framew.) increases slightly, reflecting the code that has been moved from the implementation to the generated programming framework.

Execution coverage. Because the generated code can be arbitrarily large without impacting development time, the measures in Table 3 manner. To assess this, we measured the execution coverage of the programming framework code. On average, 76% of the generated framework is actually executed. We studied the parts that are not executed and found that all of them are either error handling code or features that may not be relevant to a given application, such as entity discovery.

Code quality. We also used Sonar to measure the code quality according to various criteria including code duplication, rule compliance, and code complexity. The results given by Sonar indicate an overall good quality of the code written by the developer. For example, the average code complexity of applications implemented with the interaction contracts is 2.6, on a scale of 0 to infinity, indicating well structured code. These code quality results, associated with the small percentage of code that has to be manually written, show that our generated programming framework guides the developer in producing well-structured and easy-to-maintain code.

RELATED WORK

Our work is related to software architectures, formalisms for interaction specifications, and model-driven development.

Software Architectures

To help in structuring SCC applications, dedicated architectural patterns have been proposed. Chen and Klotz propose to decompose an application into information sources and context operators [START_REF] Chen | Context aggregation and dissemination in ubiquitous computing systems[END_REF]. Their pattern focuses on information processing and control but does not model the relation with the environment (i.e., how the environment is sensed and modified) nor does it support implementation. Architecture Description Languages model systems to ensure various properties at compile time and at runtime. Most ADLs are dedicated to analysing architectures and provide little or no implementation support. Some ADLs like Darwin [START_REF] Magee | Dynamic structure in software architectures[END_REF] and Unicon [START_REF] Shaw | Abstractions for software architecture and tools to support them[END_REF] generate runtime support, but for components that have been developed separately with a generic programming framework. These approaches provide generic abstract classes like Component and Connector that the developer must implement. As a result, component implementation cannot benefit from any support generated from the architecture description [START_REF] Medvidovic | A classification and comparison framework for software architecture description languages[END_REF].

In general, architecture-based approaches that support implementation check conformance of the implementation to an architectural pattern, e.g., constraining the interactions between various variants of components and connectors, but not conformance to a specific architecture description that is an instance of that pattern. Notable exceptions include ACOEL [START_REF] Sreedhar | Mixin'up components[END_REF] and ArchJava [START_REF] Aldrich | ArchJava: connecting software architecture to implementation[END_REF]; they connect ADLs and programming languages by proposing new syntactic constructs. These constructs allow architectural concerns to be expressed inside the application. Our work goes beyond these approaches by separating architecture from implementation and generating a programming framework to bridge the two.

To date, Archface [START_REF] Ubayashi | Archface: A contract place where architectural design and code meet together[END_REF] is the work that is the most similar to ours. Archface leverages concepts from Aspect-Oriented Programming (AOP) to describe component interactions. By using implementation-level mechanisms such as pointcuts, architects can describe component interactions more accurately at the cost of anticipating the structure of the implementations. As such, the separation between architecture description and implementation becomes blurred, making the architectural design phase more difficult. As a general-purpose design language, Archface can be used to describe any component-oriented architecture, which limits the support it can provide in a particular domain.

Interaction Specifications

Automata-based models, such as IO automata [START_REF] Lynch | Hierarchical correctness proofs for distributed algorithms[END_REF] and Interface automata [START_REF] Alfaro | Interface automata[END_REF], are commonly used for modelling interactions and actions within distributed and concurrent systems. These approaches have been used to describe component interactions in ADLs [START_REF] Waignier | A model-based framework for statically and dynamically checking component interactions[END_REF]. Interaction contracts are simpler in that they do not describe the full interaction sequence but only capture interaction constraints. Our objective is to specify only what can be enforced by the generated framework. It is virtually impossible to completely enforce automata behaviors via the generated framework as we cannot guess how the developer will distribute the application logic within the sequences of messages. We could choose to enforce it partially, but in this case, properties verified at the automaton level would not necessarily hold in the implementation. Moreover, automata-based models are a general solution and do not capture the specific properties of SCC applications. For example, context operators are reactive and this characteristic must be checked on automata, whereas it is syntactically ensured by interaction contracts.

Model-Driven Development

Model-Driven Development uses models and model transformations as a way to specify software architectures and implementations. The goal of these approaches is to raise the level of abstraction in program specifications through graphical notations, and to generate a working implementation from such a specification. UML 2.0 (Unified Modeling Language) has been widely accepted as an architecture modeling notation and as a second-generation ADL [START_REF] Medvidovic | Moving architectural description from under the technology lamppost[END_REF]. Some approaches, such as PervML [START_REF] Serral | Towards the model driven development of context-aware pervasive systems[END_REF], relies on UML diagrams and OCL expressions to model domain-specific concerns. From such diagrams, a dedicated suite of tools is able to generate a complete implementation of the described system. By using UML diagrams, these approaches leverage existing knowledge from developers and also existing tools such as the Eclipse Graphical Modelling Framework (GMF). Even though such approaches propose a conceptual framework for developing applications, they only provide the user with generic tools. The PervML approach, as well as other MDEbased approaches, require developers to directly manipulate OCL and UML diagrams, which become "enormous, ambiguous and unwieldy" [START_REF] Picek | Model Driven Development -future or failure of software development[END_REF]. In contrast, DiaSpec abstracts away such technologies, limiting the amount of expertise required from the developers.

The CALM framework uses models as types for componentoriented systems [START_REF] Jung | A type-centric framework for specifying heterogeneous, large-scale, component-oriented, architectures[END_REF]. CALM provides three modelling tiers, where each tier constrains and guides activities in the tier below: the upper tier allows the definition of domain-specific ADLs, the middle tier allows the definition of the system components, and the lower tier allows the instantiation and combination of these components. DiaSpec and its notion of interaction contracts could potentially be described in CALM's upper tier, leveraging CALM's type checking capabilities. However, CALM neither verifies that an implementation conforms to its architecture description nor does CALM proposes an architect to verify safety properties.

CONCLUSION

In this paper, we have introduced a notion of interaction contracts dedicated to describing SCC applications. We have shown how interaction contracts guide the architect in describing allowed context operator interactions. We have also described how interaction contracts can be mapped into a generated programming framework and how this mapping guides the implementation of SCC applications. A key benefit of our approach is that the strategy for generating the dedicated programming framework guarantees conformance between the architecture and its implementation. Our generative approach allows unlimited regeneration of the framework without overwriting the developer's code. Finally, we have shown how interaction contracts guide analyses at the architecture level and how the properties checked by these analyses still hold at the implementation level.

We are currently expanding this work in several directions. We want to further guide development by automatically generating a dedicated unit-testing framework. Work is also in progress to add and compose non-functional layers (e.g., fault-tolerance, safety and security) on top of the SCC architectural pattern and have automatically generated support [START_REF] Gatti | A step-wise approach for integrating QoS throughout software development[END_REF][START_REF] Mercadal | A domain-specific approach to architecturing error handling in pervasive computing[END_REF]. Finally, we are investigating the applicability of interaction contracts to other SCC component types and to other architectural patterns.

Figure 1 :

 1 Figure 1: Architecture of a web server monitor. Solid arrows represent data flow. Dashed arrows represent pull requests. For simplicity, the diagram does not show the types of the values calculated by the components and the types of the parameters required by pull requests.

Figure 2 :

 2 Figure 2: Example of synchronization.

•

  Context operators refine (aggregate and interpret) the information given by the sensors. Context operators can push data to other context operators and to control operators. Context operators can also respond to requests from parent context operators.• Control operators transform the information given by the context operators into orders for the actuators. • Actuators trigger actions on the environment.

Context operator Associated interaction contract

	AccessLogParser	⇑ (line); ∅; ⇑ self
	AccessingProfile	⇑ (AccessLogParser); ⇓ (IP2Profile); ⇑ self
	IP2Profile	⇓ self ; ⇓ (ip2host, host2profile); ∅
	IntrusionDetector	⇑ (AccessingProfile); ∅; ⇑ self ?

Table 1 : Interaction contracts associated to the context operators of the web server architecture. Line, ip2host and host2profile abbreviate AccessLog- Reader.line, NSLookup.ip2host and LDAPServer.host2- profile, respectively.

 1

Table 2 : Denotation of an interaction contract.

 2

  are relevant only if the generated code is actually executed, and thus has to be produced in some

		Arch. Implem. Framew.
	Without interaction cont.	6%	14%	80%
	With interaction cont.	7%	11%	82%

Table 3 : The development effort for architecture descriptions without and with interaction contracts. The figures indicate the distribution (in percentage) of the number of lines of code.

 3

The full Promela specification can be found at http://diasuite.inria.fr/index.php/webserver

http://diasuite.inria.fr

http://www.sonarsource.com/