4.4      Component Implementations

(1)   A component implementation represents the realization of a component in terms of subcomponents, their connections, flow sequences, properties, component modes and mode transitions.  Flow sequences represent implementations of flow specifications in the component type, or end-to-end flows to be analyzed.  Modes represent alternative operational modes that may manifest themselves as alternate configurations of subcomponents, connections, call sequences, flow sequences, and property values.

(2)   A component type can have zero, one, or multiple component implementations.  If a component type has zero component implementations, then it is considered to be a leaf in the system component hierarchy.  For example, a partial AADL model may have processes as components without realization, while a task level AADL model expand to threads as leaves.  If no implementation is associated then the properties on the component types provide information about the component for analysis and system generation. 

(3)   A component implementation can be declared as an extension of another component implementation.  In that case, the component implementation inherits the declarations of its ancestors as well as its component type. A component implementation extension can refine inherited declarations, and add subcomponents, connections, subprogram call sequences, flow sequences, mode declarations, and property associations. 

(4)   Component implementations can declare prototypes, i.e., classifier parameters that are used in subcomponent declarations.  The prototype bindings are supplied when the component implementation is being extended or used in subcomponent declarations.

(5)   Component implementations build on the component type extension hierarchy in two ways.  First, a component implementation is a realization of a component type (shown as dashed arrows in Figure 3).  As such it inherits features and property associations of its component type and any component type ancestor.  Second, a component implementation declared as extension inherits subcomponents, connections, subprogram call sequences, flow sequences, modes, property associations, and annex subclauses from the component implementation being extended (shown as solid arrows in Figure 3).  A component implementation can extend a component implementation that in turn extends another component implementation, e.g., in Figure 3 GPS. Handheld extends GPS.Basic and is extended by GPS_Secure.Handheld.  Component implementations higher in the extension hierarchy are called ancestors and those lower in the hierarchy are called descendents.  A component implementation can extend another component implementation of its own component type, e.g., GPS.Handheld extends GPS.Basic, or it can extend the component implementation of one of its ancestor component types, e.g., GPS_Secure.Handheld extends GPS.Handheld, which is an implementation of the ancestor component type GPS.  The component type and implementation extension hierarchy is illustrated in Figure 3. 

Figure 3 Extension Hierarchy of Component Types and Implementations

Syntax

component_implementation ::= 
   component_category implementation
   defining_component_implementation_name [ prototype_bindings ]
  [ prototypes ( { prototype }+ | none_statement ) ] 
   [ subcomponents ( { subcomponent }+  | none_statement ) ]
   [ calls ( { subprogram_call_sequence }+  | none_statement ) ]   
   [ connections ( { connection }+ | none_statement ) ]
   [ flows ( { flow_implementation | 
               end_to_end_flow_spec }+ | none_statement ) ]
   [modes_subclause ]
   [ properties ( { property_association | contained_property_association  }+ 
                  | none_statement ) ]
   { annex_subclause }*
   end defining_component_implementation_name ;
 
component_implementation_name ::= 
        component_type_identifier . component_implementation_identifier

component_implementation_extension ::=
   component_category implementation
   defining_component_implementation_name
   extends unique_component_implementation_reference [ prototype_bindings ]
   [ prototypes ( { prototype | prototype_refinement }+ | none_statement ) ] 
   [ subcomponents 
        ( { subcomponent | subcomponent_refinement }| none_statement ) ]
   [ calls ( { subprogram_call_sequence }+  | none_statement ) ]   
   [ connections 
        ( { connection | connection_refinement }+  | none_statement ) ]
   [ flows ( { flow_implementation  | flow_implementation_refinement |
               end_to_end_flow_spec | end_to_end_flow_spec_refinement }+ 
               | none_statement ) ]
   [modes_subclause ]
   [ properties ( { property_association | contained_property_association }+ 
     | none_statement ) ]
   { annex_subclause }*
   end   defining_component_implementation_name ;
 
unique_component_implementation_reference ::= 
    [ package_name :: ] component_implementation_name

NOTES: The above grammar rules characterize the common syntax for all component categories. The sections defining each of the component categories will specify further restrictions on the syntax.

The prototypes, subcomponents, connections, calls, flows, modes, and properties subclauses of the component implementation are optional or if used and empty, require an explicit empty declaration.  The latter is provided to accommodate AADL modeling guidelines that require explicit documentation of empty subclauses. An empty subclause declaration consists of the reserved word of the subclause and a none statement ( none ; ).

The annex_subclause of the component implementation is optional.

The refines type subclause of AADL V1 has been removed.  Its role was to allow association of implementation-specific property values to features and flow specifications declared in the component type. The same can be achieved by contained property associations whose applies to subclause names the feature or flow specification.

Naming Rules

(N1)     A component implementation name consists of a component type identifier and a component implementation identifier separated by a dot (“.”).  The first identifier of the defining component implementation name must name a component type that is declared in the same package as the component implementation, or name an alias to a component type in another package.  

(N2)     The defining identifier of the component implementation must be unique within the local namespace of the component type. 

(N3)     Every component implementation defines a local namespace for all defining identifiers of prototypes, subcomponents, subprogram calls, connections, flows, and modes declared within the component implementation.  The defining identifier of a prototype, subcomponent, subprogram call, connection, flow, or mode must be unique within this namespace.  For example, a subcomponent and a mode cannot have the same defining identifier within the same component implementation, or a mode with the same defining identifier cannot be declared in a component type and a component implementation.

(N4)     This local namespace inherits the namespace of the associated component type, i.e., defining identifiers must be unique within the local namespace and also within the component type namespace.

(N5)     Refinement identifiers of features must exist in the namespace of the associated component type or one of the component type’s ancestors.  Refinement identifiers of prototype, subcomponent, and connection refinements must exist in the local namespace of an ancestor component implementation.

(N6)     In a component implementation extension, the component type identifier of the component implementation being extended, which appears after the reserved word extends, must be the same as or an ancestor of the component type of the extension.  The component implementation being extended may exist in another package.  In this case the component implementation name is qualified with the package name.

(N7)     When a component implementation extends another component implementation, the local namespace of the extension is a superset of the local namespace of the ancestor.  That is, the local namespace of a component implementation inherits all the identifiers in the local namespaces of its ancestors (including the identifiers of their respective component type namespaces).

(N8)     Within the scope of the component implementation, subcomponent declarations, connections, subprogram call sequences, mode transitions, and property associations can refer directly to identifiers in the local namespace, i.e., to declared prototypes, subcomponents, connections, and modes, as well as to required bus, data, subprogram, and subprogram group subcomponents and features declared in the associated component type.

(N9)     The prototype referenced by the prototype binding declaration must exist in the local namespace of the component implementation being extended.  In other words, prototype binding declarations may bind prototypes of the component type and of the component implementation.

NOTES:

A component type can be made visible in a new namespace (package) without qualifying it with the package name by declaring it as renames that refers to the component type in the original package.  This allows an implementation to be placed in a separate package from the component type package.  In the following example, renames LM::GPS allows the type GPS to be named without a qualifying package name.  This allows a system implementation to be added to GPS in the package LM1.   

package LM1 public

renames LM::GPS;

system implementation GPS.newimpl

Legality Rules

(L1)      The pair of identifiers separated by a dot (“.”) following the reserved word end must be identical to the pair of identifiers following the reserved word implementation.

(L2)      The prototypes, subcomponents, connections, calls, flows, modes, and properties subclauses are optional. If they are present and the set of feature or required subcomponent declarations or property associations is empty, none followed by a semi-colon must be present in that subclause.

(L3)      The category of the component implementation must be identical to the category of the component type for which the component implementation is declared.

(L4)      If the component implementation extends another component implementation, the category of both must match, i.e., they must be identical or the category being extended must be abstract.

(L5)      The classifier being extended in a component implementation extension may include prototype bindings.  There must be at most one prototype binding for each unbound prototype.

(L6)      If the component type of the component implementation contains a requires_modes_subclause then  the component implementation must not contain any modes subclause.

(L7)      If modes are declared in the component type, then modes cannot be declared in component implementations.

(L8)      If modes or mode transitions are declared in the component type, then mode transitions can be added in the component implementation. These mode transitions may refer to event or event data ports of the component type and of subcomponents.

(L9)      The category of a subcomponent being refined must match the category of the refining subcomponent declaration, i.e., they must be identical or the category being refined must be abstract.

(L10)   For all other refinement declarations the categories must match (see the respective sections).

(L11)   Component implementations and component implementation extensions must not refine prototypes declared in a component type.

Standard Properties

Classifier_Substitution_Rule: inherit enumeration (Classifier_Match,  Type_Extension, Signature_Match)
Prototype_Substitution_Rule: inherit enumeration (Classifier_Match, Type_Extension, Signature_Match)
Classifier_Matching_Rule: inherit enumeration (Classifier_Match, Equivalence, Subset, Conversion, Complement)

 

Semantics

(6)   A component implementation represents the internal structure of a component through subcomponent declarations. Interaction between subcomponents is expressed by the connections, flows, and subprogram call sequences. Mode declarations represent alternative runtime configurations (internal structure) and alternative execution behavior (interaction between subcomponents).  A component implementation also has property values to express its non-functional attributes such as safety level or execution time which can also vary by mode. 

(7)   Each component implementation is associated with a component type and provides a realization of its features (interface).  A component type can have multiple implementations. A component implementation can be viewed as a component variant with the same interface but with differing property values that characterize the differences between implementations without exposing the internals of their realization.  This can be achieved by placing the component implementation declaration without subcomponents and connections in the public section of an AADL package, and a component implementation declaration with subcomponents and connections for the same component in the private section of an AADL package.

(8)   The actual system being modeled by component types and component implementations may contain subcomponents, some of which may contain subcomponents themselves.  The subcomponent containment hierarchy reflects the actual system structure. 

(9)   A component implementation that is an extension of another inherits all prototypes, subcomponents, connections, subprogram call sequences, flow sequences (flow implementations and end-to-end flows), modes, mode transitions, and property associations from its ancestors as well as features, and  associations, from its associated component type (and that component type’s ancestors).  For annex subclauses  each annex defines whether annex declarations are inherited. 

(10)  A component implementation extension can refine prototypes and subcomponents previously declared in ancestor component implementations by supplying component classifiers, and by associating new property values.  A component implementation extension can refine connections, flows, and modes of its ancestor component implementations by associating new property values.  A component implementation extension can refine features of its associated component type (and that component type’s ancestors) by associating new property values to them.  A component implementation being extended may include declaration of prototype bindings.  If prototype bindings are declared for a subset of the prototypes, then only the prototypes without binding can be bound  in component implementation extensions.

(11)  A component implementation extension can also add prototypes, subcomponents, connections, subprogram call sequences, flow sequences, modes, property associations, and annex subclauses.  This extension capability supports evolutionary development and modeling of system families by declaring partially complete component implementations that get refined in extensions.

(12)  A descendent component implementation is said to contain all subcomponents whose identifiers appear in its local namespace, i.e., subcomponents declared in the component implementation and any of its ancestors.  In other words, an instance of a component implementation extension contains instances of declared and inherited subcomponents, features, connections, subprogram call sequences, flow sequences, and modes.

(13)  Properties are predefined for each of the component categories and will be described in the appropriate sections. See Section 11.3 regarding rules for determining property values.

Processing Requirements and Permissions

(14)  A component implementation denotes a set of actual system components, existing or potential, that are compliant with the component implementation declaration as well as the associated component type.  That is, the actual components denoted by a component implementation declaration are always compliant with the functional interface specified by the associated component type declaration.  Actual components denoted by different implementations for the same component type differ in additional details such as internal structure or behaviors; these differences may be specified using properties.

(15)  In general, two actual components that comply with the same component type and component implementation are not necessarily substitutable for each other in an actual system.  This is because an AADL specification may be legal but not specify all of the characteristics that are required to ensure total correctness of a final assembled system.  For example, two different versions of a piece of source text might both comply with the same AADL specification, yet one of them may contain a programming defect that results in unacceptable runtime behavior.  Compliance with this standard alone is not sufficient to guarantee overall correctness of a actual system. 

Examples

package ImplementationExample

public

data Bool_Type

end Bool_Type;

 

thread DriverModeLogic

features

   BreakPedalPressed : in data port Bool_Type;

   ClutchPedalPressed : in data port Bool_Type;

   Activate : in data port Bool_Type;

   Cancel : in data port Bool_Type;

   OnNotOff : in data port Bool_Type;

   CruiseActive : out data port Bool_Type;

end DriverModeLogic;

 

-- Two implementations whose source texts use different variable names for

-- their cruise active port

thread implementation DriverModeLogic.Simulink

properties

  Dispatch_Protocol=>Periodic;

  Period=> 10 ms;

  Source_Name => “CruiseControlActive” applies to CruiseActive;

end DriverModeLogic.Simulink;

 

thread implementation DriverModeLogic.C

properties

  Dispatch_Protocol=>Periodic;

  Period=> 10 ms;

  Source_Name => “CCActive” applies to CruiseActive;

end DriverModeLogic.C;

end ImplementationExample;