A type language for message passing component-based systems
JJ. Lange, A. Mavridou, L. Safina, A. Scalas (Eds.):13th Interaction and Concurrency Experience (ICE 2020).EPTCS 324, 2020, pp. 3–24, doi:10.4204/EPTCS.324.3 c (cid:13)
Z. Savanovi´c, L. Galletta & H.T. VieiraThis work is licensed under theCreative Commons Attribution License.
A type language for message passing component-basedsystems
Zorica Savanovi´c
IMT School for Advanced Studies, Lucca, Italy
Letterio Galletta
IMT School for Advanced Studies, Lucca, Italy
Hugo Torres Vieira
C4 - University of Beira Interior, Rua Marquˆes d’ ´Avila e Bolama, 6201-001, Covilh˜a, Portugal
Component-based development is challenging in a distributed setting, for starters considering pro-gramming a task may involve the assembly of loosely-coupled remote components. In order forthe task to be fulfilled, the supporting interaction among components should follow a well-definedprotocol. In this paper we address a model for message passing component-based systems wherecomponents are assembled together with the protocol itself. Components can therefore be indepen-dent from the protocol, and reactive to messages in a flexible way. Our contribution is at the level ofthe type language that allows to capture component behaviour so as to check its compatibility with aprotocol. We show the correspondence of component and type behaviours, which entails a progressproperty for components.
Code reusability is an important principle to support the development of software systems in a cost-effective way. It is a key principle in Component-Based Development (CBD) [15], where the idea is tobuild systems relying on the composition of loosely-coupled and independent units called components.The motivations behind CBD are, on the one hand, to increase development efficiency and lowerthe costs (by building a system from pre-existing components, instead of building from scratch), and onthe other hand, to improve quality of the software for instance to what concerns software errors (com-ponents can be tested over and over again in different contexts). Consider, for example, microservices(see, e.g., [8]) that have been recently adopted by massively deployed applications such as Netflix, eBay,Amazon and Uber, and that are reusable distributed software units. In such a distributed setting, com-posing software elements necessarily involves some form of communication scheme, for instance basedon message passing.In order for the functionality to be achieved, communication among components should follow awell-defined protocol of interaction, that may be specified in terms of some choreography language like,for example, WS-CDL [18] or the choreography diagrams of BPMN [17]. A component should be ableto carry out a certain sequence of I/O actions in order to fulfil its role in the protocol. One way toaccomplish this is to implement a component in a way that prescribes a strict sequence of I/O actions,that should precisely match the actions expected by the protocol. However, this choice interferes withreusability, since such a component can be used only in an environment that expects that exact sequenceof communication actions. For instance, if a component receives an image and outputs its classificationjust once, what will happen if we need to use this component in a context that requires the classificationis sent multiple times?In contrast, a more flexible design choice inspired by reactive programming is to design componentsso that they can respond to external stimulus without any specific I/O sequence. The reactive program-
A type language for message passing component-based systems ming principle for building such components is to consider that as soon as the data is available, it can bereceived or emitted. For example, we can design a component that is able to output a classification afterreceiving an image, as long as required. In such a way, reusability is promoted since such componentscan be used in different environments thanks to the flexibility given by the reactive behaviour. However,such a flexibility at the composition level may be too wild if all components are able to send / receivedata as soon as it is available. Hence, there is the need to discipline the interactions at the level of the en-vironment where the composition takes place. What if, for example, we have different images that needto be classified and the classifying component is continuously emitting the result for the first image?Carbone, Montesi and Vieira [5] proposed a language that supports the development of distributedsystems by combining the notions of reactive components with choreographic specifications of commu-nication protocols [16]. The proposal considers components that can dynamically send / receive dataas soon as it is available, while considering that an assembly of components is governed by a protocol.Hence, among all the possible reactions that are supported by the composed components, the only onesthat will actually be carried out are the ones allowed by the protocol. A composition of componentsdefines itself a component that can be further composed (under the governance of some protocol) alsoproviding a reactive behaviour. This approach promotes reusability thanks to the flexibility of the reactivebehaviour. For instance, by abstracting from the number of supported reactions, e.g., if a component can(always) perform a computation reacting to some data inputs, then it can be used in different protocolsthat require such computation to be carried out a different number of times; by abstracting from messageordering, e.g., if a component needs some values to perform a computation, it may be used with anyprotocol that provides them in any order.Component implementations should be hidden, so it shouldn’t be necessary to inspect the inner work-ings in order to asses if it is usable in a determined context for the purpose of off-the-shelf substitution orreuse. Hence, a component should be characterised with a signature that allows checking its compatibil-ity when used in a composition. In particular, it must be ensured that each component provides (at least)the behaviour prescribed by the protocol in which the component participates. Carbone et al. [5] proposea verification technique that ensures communication safety and progress. However, the approach requireschecking the implementation of components each time the component is put in a different context, i.e.,each time that the component is used “off-the-shelf” we need to check if the reactions supported by thecomponent are enough to implement its part in the protocol.In this work we consider a different approach, avoiding the implementation check each time a com-ponent is to be used. Firstly, we introduce a type language that characterises the reactive behaviour ofcomponents. Secondly, we devise an inference technique that identifies the types of components, basedon which we can verify whether the component provides the reactive behaviour required by a context.The motivation is in tune with reusability: once the component’s type is identified, there is no furtherneed to check the implementation, because the type is enough to describe “what the component can do”.Our types specify the ability of components to receive values of a prescribed basic type. Moreover,they track different kinds of dependencies, for instance that certain values to be emitted always (for eachoutput) require a specific set of inputs (dubbed per each value dependencies). Our types can also de-scribe the fact that a component needs to be, in some sense, initialised by receiving specific values beforeproceeding with other reactive behaviour (dubbed initial dependencies). Furthermore, our types alsoidentify constraints on the number of values that a component can send. Finally, we ensure the correct-ness of our type system by proving that our extraction procedures are sound with respect to the semanticsof the Governed Components (GC) language [5], considering here the choice-free subset of the GC lan-guage and leaving a full account of the language to future work. Moreover, we ensure that whenever atype of a component prescribes an action, a component will not be stuck, i.e., it will eventually carry out . Savanovi´c, L. Galletta & H.T. Vieira K :: = [ ˜ x (cid:105) ˜ y ] { L } (base) L :: = y = f ( ˜ x ) G :: = p (cid:96) −→ ˜q ; G (communication) [ ˜ x (cid:105) ˜ y ] { G ; R ; D ; r [ F ] } (composite) L , L µ X . G (recursion) X (recursion variable) end (termination)Role assignments Distribution Binders Forwarders R :: = p = K D :: = p . x (cid:96) ←− q . y F :: = z ← wR , R D , D F , F Table 1: Syntax of Governed Componentsthe matching action.The rest of the paper is organised as follows. We first present the GC language in Section 2. Thenin Section 3 we intuitively introduce our type language through a motivating example based on AWSLambda [1] where we point out different scenarios that might occur while composing components andhow our types allow to describe certain behavioural patterns. Section 4 introduces the syntax and thesemantics of our types. Then, we define the type extraction for base components in Section 4.1, whereasthe type extraction for composite components in Section 4.2. In Section 4.3 we present our results.Section 5 concludes, discusses related work and gives some future issues.
In this section we briefly introduce the GC language, focusing on the main points that allow to grasp theessence of the model and to support a self-contained understanding of this paper. We refer the interestedreader to [5] for a full account of the language. The syntax of the (protocol choice-free fragment ofthe) GC language is given in Table 1. There are two kinds of components ( K ): base and composite.Both kinds interact with the external environment by means of input and output ports exposed as thecomponent’s interface. Besides of the interface, components are defined by their implementation.In the case of a base component the implementation is given by the list of local binders ( { L } ). Alocal binder specifies a function, denoted as y = f ( ˜ x ) , which is used to compute the output values forport y relying on values received on list of (input) ports ˜ x . So, we say that component’s ability tooutput a value may depend on the ones received, where instead, components are always able to receivevalues.We abstract from the definition of such functions f and assume them to be total. Received valuesare processed in a FIFO discipline, so queues are added to the local binders at runtime (noted as y = f ( ˜ x ) (cid:104) ˜ σ ). Each element ( σ ) in a queue ( ˜ σ ) is a store defined as a partial mapping from input ports tovalues ( ˜ σ = σ , σ , . . . , σ k , where in σ the oldest values received are stored, in σ the second-oldestvalues, and so on and so forth up to σ k ). E.g., if y = f ( x , x ) < · and the component receives v and v in that order on port x and v , v and 5 on port x . The queue at this point has three mappings ( x → v , x → v ) , ( x → v , x → v ) , ( x → ) where two are “complete” to compute the function andone is not.The implementation of a composite component, represented by { G ; R ; D ; r [ F ] } , is an assembly ofsubcomponents whose interaction is governed by a protocol ( G ). The set of subcomponents are given in R together with their roles in the interaction (e.g., r = K denotes that component K is assigned to role r ). Composite components also specify a list of (distribution) binders ( D ) that provide an association be- A type language for message passing component-based systems tween the messages exchanged in the protocol ( (cid:96) ) and the ports ( x , y ) of the components (e.g., p . x (cid:96) ←− q . y states that a message with a label (cid:96) is emitted on port y of the component assigned to role q , and to bereceived on port x of the component assigned to role p ). Ports are uniquely associated to message labels( (cid:96) ) in such way that each communication step in the protocol has a precise mapping to a port, i.e., allvalues emitted on a port will be carried in messages with the same label and all values received on a portwill be delivered in messages with the same label. E.g., every time a value is emitted from some port y it will be carried in a message labelled with e.g., (cid:96) and a value delivered on some port x is delivered on amessage with the same label (cid:96) . Some other label cannot be attached to y , otherwise the association wouldnot be unique. The class message label (or some other) cannot be attached to y p otherwise the associationwould not be unique. Finally, subterm r [ F ] is used to specify the externally-observable behaviour: the(only interfacing) subcomponent responsible for the interaction with the external environment is identi-fied (by its role r ) and the respective connection between ports is provided by forwarders ( F ). The ideais that values received on the (input) ports of the composite component are directly forwarded to the(input) ports of the interfacing subcomponent, and values emitted on the (output) ports of the interfacingsubcomponent are forwarded to the (output) ports of the composite component. For example, the term x (cid:48) ← x is for forwarding an input, and the term y ← y (cid:48) is for forwarding an output ( x and y are the portsof the composite component).Protocol specifications prescribe the interaction among a set of parties identified by roles. Commu-nication term p (cid:96) −→ ˜q ; G specifies that role p sends the message labelled (cid:96) to the (nonempty) set of roles˜ q , after which the protocol continues as specified by G . The difference between this work and [5] is theabsence of branching. Then we have terms µ X . G and X for specifying recursive protocols. Finally, term end defines the termination of the protocol.We now present the operational semantics of the GC in terms of a labelled transition system (LTS).We denote by K λ −→ K (cid:48) that a component K evolves in one computational step to K (cid:48) , where observationsare captured by labels defined as follows λ :: = x ? v | y ! v | τ . Transition label x ? v represents an input onport x of a value v , label y ! v captures an output on port y of a value v , and label τ denotes an internalmove.The rules that describe the behaviour of components are presented in two parts, addressing base andcomposite components separately. We present only the main rules, the full semantics can be found in [5]. L y ! v −→ L (cid:48) y ∈ ˜ y [ ˜ x (cid:105) ˜ y ] { L } y ! v −→ [ ˜ x (cid:105) ˜ y ] { L (cid:48) } OutBase L x ? v −−→ L (cid:48) x ∈ ˜ x [ ˜ x (cid:105) ˜ y ] { L } x ? v −−→ [ ˜ x (cid:105) ˜ y ] { L (cid:48) } InpBase
Table 2: Semantics of base componentsRules
OutBase and
InpBase that are given in Table 2 capture base component behaviour, and aredefined relying on transitions exhibited by local binders, denoted L λ −→ L (cid:48) . Rule OutBase states that iflocal binders L can exhibit an output of value v on port y , where y is part of the component’s interface,then the corresponding output can be exhibited by the base component. Rule InpBase follows the samelines.Notice that the transition of the local binder specifies a final configuration L (cid:48) which is accounted forin the evolution of the base component. We omit here the rules for local binders (see [5]) and provideonly an informal account for them. Essentially, a (runtime) local binder y = f ( ˜ x ) (cid:104) ˜ σ is always receptiveto an input x ? v : if x is not used in the function ( x (cid:54)∈ ˜ x ) then value v is simply discarded; otherwise,the value is added to the (oldest) entry in mapping queue ˜ σ that does not have an entry for x (possibly . Savanovi´c, L. Galletta & H.T. Vieira K z ! v −→ K (cid:48) F = y ← z , F (cid:48) y ∈ ˜ y [ ˜ x (cid:105) ˜ y ] { G ; r = K , R ; D ; r [ F ] } y ! v −→ [ ˜ x (cid:105) ˜ y ] { G ; r = K (cid:48) , R ; D ; r [ F ] } OutComp K z ? v −−→ K (cid:48) F = z ← x , F (cid:48) x ∈ ˜ x [ ˜ x (cid:105) ˜ y ] { G ; r = K , R ; D ; r [ F ] } x ? v −−→ [ ˜ x (cid:105) ˜ y ] { G ; r = K (cid:48) , R ; D ; r [ F ] } InpComp K τ −→ K (cid:48) [ ˜ x (cid:105) ˜ y ] { G ; s = K , R ; D ; r [ F ] } τ −→ [ ˜ x (cid:105) ˜ y ] { G ; s = K (cid:48) , R ; D ; r [ F ] } Internal K u ! v −−→ K (cid:48) D = q . z (cid:96) ←− p . u , D (cid:48) G p ! (cid:96) (cid:104) v (cid:105) −−−→ G (cid:48) [ ˜ x (cid:105) ˜ y ] { G ; p = K , R ; D ; r [ F ] } τ −→ [ ˜ x (cid:105) ˜ y ] { G (cid:48) ; p = K (cid:48) , R ; D ; r [ F ] } OutChor K z ? v −−→ K (cid:48) D = q . z (cid:96) ←− p . u , D (cid:48) G q ? (cid:96) (cid:104) v (cid:105) −−−→ G (cid:48) [ ˜ x (cid:105) ˜ y ] { G ; q = K , R ; D ; r [ F ] } τ −→ [ ˜ x (cid:105) ˜ y ] { G (cid:48) ; q = K (cid:48) , R ; D ; r [ F ] } InpChor
Table 3: Semantics of composite componentsoriginating a new mapping at the tail of ˜ σ ). All local binders in L synchronise on an input, so each localbinder will store (or discard) its own copy of the value. Instead, local binder outputs are not synchronisedamong them: if a local binder outputs a value, other local binders will not react. For this to happen, theoldest mapping in queue ˜ σ must be complete (i.e., assign values to all of ˜ x ) at which point function f may be computed, the result which is then carried in the transition label (i.e., the v in y ! v ).We now introduce the rules that capture the behaviour of the composite components, displayed inTable 3. Notice that a composite component may itself be used as a subcomponent of another composi-tion (of a “bigger” component), and base components provide the syntactic leaves. Rules OutComp and
InpComp capture the interaction of a composite component with an external environment, realised by theinterfacing subcomponent. The role assignment r = K captures the relation between component K androle r , which is specified as the interfacing role ( r [ F ] ). Rule OutComp allows for the interfacing compo-nent K to send a value v to the external environment via one of the ports of the composite component ( y ).Notice that the connection between the port of the interfacing component ( z ) and the port of the compos-ite component ( y ) is specified in a forwarder ( F = y ← z , F (cid:48) ). Rule InpComp follows the same lines tomodel an externally-observable input. Rule
Internal allows for internal actions in a subcomponent ( K ),where the final configuration ( K (cid:48) ) is registered in the final configuration of the composite component.Rules OutChor and
InpChor capture the interaction among subcomponents of a composite compo-nent. Rule
OutChor addresses the case when a component is sending a message to another one. Thepremises, together with role assignment p = K , establish the connection among sender component K , thecomponent port u , sender role p , and message label (cid:96) . Premise K u ! v −−→ K (cid:48) says that the sender compo-nent ( K ) can perform an output of value v on port u . Premise D = q . z (cid:96) ←− p . u , D (cid:48) says that the distributionbinders specify the (unique) relation between port u of sender role p and message label (cid:96) (receiver role q and associated port z are not important here). The last premise G p ! (cid:96) (cid:104) v (cid:105) −−−→ G (cid:48) realises the componentgoverning the protocol, i.e., saying that the communication is only possible if the protocol prescribes it.Namely, the premise says that the protocol exhibits an output of a value v carried in message (cid:96) from role p . The rules for protocol transitions are presented in [5]. Naturally which semantics has an impact onour technical development (namely regarding end-point projection in local protocols), but to some extentcan be addressed in a modular way (i.e., up to the existence of the end-point projection). Notice that thetransitions of component K and protocol G specify final configurations K (cid:48) and G (cid:48) which are accounted A type language for message passing component-based systems for in the evolution of the composite component.Rule
InpChor is similar, but instead of message sending, it addresses the case when a subcompo-nent receives a message from another subcomponent. The premises are equivalent to the ones for Rule
OutChor , but now regard reception. Namely, by saying that receiving component K can exhibit the re-spective input transition, that the distribution binder specifies the relation of message label (cid:96) with receiverrole q and port z , and that protocol G prescribes the input of a value. In order to further motivate GC and also to introduce our typing approach, we now informally discuss anexample inspired by a microservices scenario [1] that addresses an Image Recognition System (
IRS ). Thebasic idea is that users upload images and receive back the resulting classification. Moreover, users canget the current running version of the system whenever desired. The
IRS is made of two microservices,
Portal and
Recognition Engine ( RE ), that interact according to a predefined protocol.The task is achieved according to the following workflow: Portal sends the image loaded by a userto RE to be processed. When RE service finishes its classification , it sends the class as the result of the classification to Portal . We model the scenario in the GC calculus by assigning to each microservice thecorresponding role and using components to represent them. We assign role
Portal to component K Portal and role RE to component K RE , where K Portal and K RE are base components. Interaction between thesetwo components is governed by global protocol G , that can be described as: Portal image −−−→ RE ; RE class −−−→ Portal . This (the part of G ) protocol exactly specifies the workflow described above: Portal sends an image to RE ( Portal image −−−→ RE ) that answers with the computed class ( RE class −−−→ Portal ). If we add thetermination ( end ) we obtain (complete G ) protocol Portal image −−−→ RE ; RE class −−−→ Portal ; end , which may bedescribed as a one-shot protocol, since the interaction is over ( end ) after the components exchange thetwo messages.We obtain composite component K IRS by assembling K Portal and K RE together with protocol G thatgoverns the interaction. Below, we show how it is possible to graphically represent component K IRS ,where we represent K Portal and K RE as its subcomponents:The subcomponent K Portal is the interfacing component (hence is the only one connected to theexternal environment via forwarders). We can specify K Portal in the GC language as [ x p , x (cid:48) p (cid:105) y p , y (cid:48) p , y (cid:48)(cid:48) p ] { y p = f u ( x p ) < ˜ σ y p , y (cid:48) p = f r ( x (cid:48) p ) < ˜ σ y (cid:48) p , y (cid:48)(cid:48) p = f () < ·} As previewed in the graphical illustration, from the specification we can see that K Portal componenthas two input ports ( x p , x (cid:48) p ), three output ports ( y p , y (cid:48) p , y (cid:48)(cid:48) p ), and three local binders that at runtime are . Savanovi´c, L. Galletta & H.T. Vieira σ y p , ˜ σ y (cid:48) p and empty queue · given that the respective binder does not use anyinput ports). Notice that the queues are only required at runtime and are initially empty.The idea of our type description is to provide an abstract characterisation of component’s behaviour.Types provide information about the set of input ports, namely the types of values that can be receivedon them, and about the output ports, namely regarding their behavioural capabilities. In particular, foreach output port there are constraints which comprise three pieces of information: what type of valuesare emitted; what is the maximum number of values that can be emitted; and what are the dependencieson input ports, possibly including the number of currently available values that satisfy the dependency atruntime.Informally, the type of K Portal announces the following: In the two input ports x p and x (cid:48) p the compo-nent can receive an image and a class , respectively ( { x p ( image ) , x (cid:48) p ( class ) } ). Also, the type says in y p the component can emit image s and it can do so an unbounded number of times (denoted by ∞ ) as the un-derlying local binder imposes no boundary constraints. In particular, the local binder can send an image as soon as one is received in x p . Hence, we have a per each value dependency of y p on x p . Formally, wewrite this constraint as y p ( image ) : ∞ : [ { x p : N p } ] , where N p is the number of values received on x p thatare available to be used to produce the output on y p . We may describe constraint y (cid:48) p ( class ) : ∞ : [ { x (cid:48) p : N (cid:48) p } ] in a similar way. In constraint y (cid:48)(cid:48) p ( version ) : ∞ : [ /0 ] there are no dependencies from input ports specified,hence the reading is only that a version can be emitted an unbounded number of times. We may specifythe type of K Portal as: T Portal = < { x p ( image ) , x (cid:48) p ( class ) } ; { y p ( image ) : ∞ : [ { x p : N p } ] , y (cid:48) p ( class ) : ∞ : [ { x (cid:48) p : N (cid:48) p } ] , y (cid:48)(cid:48) p ( version ) : ∞ : [ /0 ] } > Composite component K IRS is an assembly of two base components K Portal and K RE whose commu-nication is governed by global protocol G . The description of K IRS in GC language is the following: K IRS = [ x (cid:105) y , y (cid:48) ] { G ; Portal = K Portal , RE = K RE ; D ; Portal [ F ] } where G is the already described one-shot protocol G = Portal image −−−→ RE ; RE class −−−→ Portal ; end Interfacing component K Portal forwards the values from/to the external environment as specified in theforwarders ( F = x p ← x , y ← y (cid:48) p , y (cid:48) ← y (cid:48)(cid:48) p ). The forwarding implies that the characterisation of ports x , y and y (cid:48) in the type of K IRS relies on one of the ports x p , y (cid:48) p and y (cid:48)(cid:48) p , respectively, in the type of K Portal .The type of K IRS then says that it can always input on x values of type image accordingly to theinput receptiveness principle. The constraint for y (cid:48) is the same as for y (cid:48)(cid:48) p since y (cid:48)(cid:48) p does not depend onthe protocol (in fact it has no dependencies). However, this is not the case for y : in order for a class ofan image to be forwarded from y (cid:48) p there is a dependency (identified in T Portal ) on port x (cid:48) p . Furthermore,component K Portal will only receive a value on x (cid:48) p accordingly to the protocol specification, in particularupon the second message exchange. Hence, there is also a protocol dependency since the first messageexchange has to happen first, so there is a transitive dependency to an image being sent in the firstmessage exchange, emitted from port y p of component K Portal . Finally, notice that y p depends on x p which is linked by forwarding to port x of component K IRS , thus we have a sequence of dependenciesthat link y to x .Since we have a one-shot protocol, the communications happens only once, which implies that one class is produced for the first image received. We therefore consider that the dependency of y on x is initial (since one value suffices to break the one-shot dependency), and that the maximum number of0 A type language for message passing component-based systems values that can be emitted on y is 1. This constraint is formally written as y ( class ) : 1 : [ { x : Ω } ] . Theconstraint for y (cid:48) is y (cid:48) ( version ) : ∞ : [ /0 ] , where the set of dependencies is empty, i.e., it does not dependon any input. We then have the following type for component K IRS : T IRS = < { x ( image ) } ; { y ( class ) : 1 : [ { x : Ω } ] , y (cid:48) ( version ) : ∞ : [ /0 ] } > Let us now assume a recursive version of protocol G (cid:48) = µ X . Portal image −−−→ RE ; RE class −−−→ Portal ; X is used instead (i.e., K (cid:48) IRS = [ x (cid:105) y , y (cid:48) ] { G (cid:48) ; Portal = K Portal , RE = K RE ; D ; Portal [ F ] } ). The idea now is thatfor each image received a class is produced. So, class may be emitted on y an unbounded number oftimes and the dependency of y on x is of a per each kind. Notice that the chain of dependencies can bedescribed as before, but the one-shot dependency from before is now renewed at each protocol iteration.The constraint for y in this settings is y ( class ) : ∞ : [ { x : N i } ] , where N i captures the number of valuesreceived on x that are currently available to produce the outputs on y . The constraint for y (cid:48) is the same asin the previous case. We then have that the type of K (cid:48) IRS is < { x ( image ) } ; { y ( class ) : ∞ : [ { x : N i } ] , y (cid:48) ( version ) : ∞ : [ /0 ] } > Imagine that K (cid:48) Portal is now a composite component that has an initialisation phase such that, first itreceives a message about what kind of classification is required (e.g., “classify the image by the numberof faces found on it”), then it sends it to K (cid:48) RE , after which the uploading and classification of the imagescan start (all other characteristics remain). Let x be the port of K (cid:48) IRS on which this message is received.Let us consider the following protocol G (cid:48)(cid:48) = Portal kind −−→ RE ; µ X . Portal image −−−→ RE ; RE class −−−→ Portal ; X where after component K (cid:48) Portal sends the required kind of classifications (labelled as kind ), the communi-cation between K (cid:48) Portal and K (cid:48) RE is governed by a recursive protocol as described in the previous example.The type of the component K (cid:48) IRS is similar to the type from the previous example, but now announcesthat the output on y requires an initial value to be received on port x , as the image classification processcan only start after that. We then have the type of K (cid:48) IRS < { x ( image ) } ; { y ( class ) : ∞ : [ { x : N i , x : Ω } ] , y (cid:48) ( version ) : ∞ : [ /0 ] } > In this section we define the type language that captures the behaviour of components in an abstract way,starting with the presentation of the syntax which is followed by the operational semantics. Then wepresent two procedures that define how to extract the type of a component. The first procedure is forbase, and the second one is for composite components.
Syntax
The syntax of types is presented in Table 4 and some explanations follow. A type T consistsof two elements: a (possibly empty) set of input ports, where each one is associated with a basic type b (i.e., int, string, etc.), and a (possibly empty) set of constraints C , one for each output port. Basic types(ranged over by b , b , b , b x , b y , b (cid:48) , . . . ) specify the type of the values that can be communicated throughports, so as to ensure that no unexpected values arise. Each constraint in C contains a triple of the form . Savanovi´c, L. Galletta & H.T. Vieira Types and input interfaces Dependency kinds Boundaries T ∆ = < X b ; C > X b ∆ = { x ( b ) , . . . , x k ( b k ) } M :: = N | Ω B :: = N | ∞ Constraints Dependencies C ∆ = { y ( b ) : B : [ D ] , . . . , y k ( b k ) : B k : [ D k ] } D ∆ = { x : M , . . . , x k : M k } k ≥ N ∈ N Table 4: Type Syntax y ( b ) : B : [ D ] , which describes the type ( b ) of values sent via y , the capability ( B ) of y and the dependencies( D ) of y on the input ports. The set of constraints C is ranged over C , C , . . . , C (cid:48) , C (cid:48)(cid:48) , C y , . . . (likewiseother syntactic categories like N , B , D , . . . ). Capability B identifies the upper bound on the number ofvalues that can be sent from the output port: a natural number N denotes a bounded capability, whereas ∞ an unbounded one. Dependencies are of two kinds: per each value dependencies are of the form x : N and initial dependencies are given by x : Ω . A dependency x : N says that each value emitted on y requiresthe reception of one value on x , and furthermore N provides the (runtime) number of values available on x (hence, initially N = x : Ω says that y initially depends on a (single) valuereceived on x , hence the dependency is dropped after the first input on x .Note that there are only two kinds of dependencies: a per each value dependency and an initial one.Since we aim at static typing, the dependencies that appear after the extraction of a type are either x : 0 or x : Ω , but for the sake of showing our results, we need to capture these values in the evolution of the types.So, we need to capture the number of values available on the input ports, hence we have dependencies ofthe kind x : 1 , x : 2 , . . . (for N = , N = . . . ). Remark.
In this work we investigate the mathematical model for the purpose of showing our results, butwe may already point towards practical applications. In particular, for the purpose of the (static) typeverification we are aiming at, the counting required for the theoretical model would not be involved andthe component type information available for developers would be as follows: • set of input ports with their basic types • set of constraints for each output port with the following information1. the basic type associated to the output port2. one of two possibilities for output port capability: bounded or unbounded3. one of two possibilities for each kind of dependency: per each value or initialHence, for the sake of static type checking and from a developers perspective, apart the expectedinformation regarding basic (value) types, the type information would be y:bounded or y:unbounded to what concerns output port capabilities and x:pereach or x:initial to what concerns dependencies. Semantics
We now define the operational semantics of the type language, that is required to show thattypes faithfully capture component behaviour. The semantics is given by the LTS shown in Table 5.There are four kinds of labels λ described by the following grammar: λ :: = x ? | x ? ( b ) | y ! ( b ) | τ . Label x ? denotes an input on x ; whereas, label x ? ( b ) denotes an input of a value of type b ; then, label y ! ( b ) represents an output of a value of type b ; finally, τ captures an internal step.We briefly describe the rules shown in Table 5. Rules [T1,T2,T3] describe inputs of a (single) con-straint, while [T4, T5, T6] capture type behaviour. Rule [T1] says a constraint for y can receive (anddiscard) an input on x in case y does not depend on x , i.e., if x is not in the domain of D ( dom ( D ) = { x | D = { x : M } (cid:93) D (cid:48) } ), leaving the constraint unchanged. Rule [T2] addresses the case of an initialdependency, where after receiving the value on x the dependency is removed. Rule [T3] captures the2 A type language for message passing component-based systems x / ∈ dom [ D ] y ( b ) : B : [ D ] x ? −→ y ( b ) : B : [ D ] [ T ] y ( b ) : B : [ { x : Ω } (cid:93) D ] x ? −→ y ( b ) : B : [ D ] [ T ] y ( b ) : B : [ { x : N } (cid:93) D ] x ? −→ y ( b ) : B : [ { x : N + } (cid:93) D ] [ T ] T τ −→ T [ T ] ∀ i ∈ , , . . . , k y i ( b i ) : B i : [ D i ] x? −→ y i ( b i ) : B i : [ D (cid:48) i ] < { x ( b x ) (cid:93) X b } ; { y i ( b i ) : B i : [ D i ] | i ∈ , . . . , k } > x ? ( b x ) −−−→ < { x ( b x ) (cid:93) X b } ; { y i ( b i ) : B i : [ D (cid:48) i ] | i ∈ , . . . , k } > [ T ] ∀ i ∈ , , . . . , k N i ≥ B > < X b ; { y ( b y ) : B : [ { x i : N i | i ∈ , . . . , k } ] } (cid:93) C > y ! ( b y ) −−−→ < X b ; { y ( b y ) : B − [ { x i : N i − | i ∈ , . . . , k } ] } (cid:93) C > [ T ] Table 5: Type Semanticscase of a per each value dependency, where after the reception the number of values available on x for y is incremented.With respect to type behaviour, Rule [T4] says that the type can exhibit an internal step and remainunchanged, used to mimic component internal steps (which have no impact on the interface). Rule [T5]states that if all type constraints can exhibit an input on x and x is part of the type input interface, thenthe type can exhibit the input on x considering the respective basic type. Notice that rules [T4, T5, T6]say that constraints can always exhibit an input (simply the effect may be different). Finally, Rule [T6]says that if one of the constraints has all of the dependencies met, i.e., has at least one value for each x for which there is a dependency, and also that the boundary has not been reached (i.e., it is greater thanzero), then the type can exhibit the corresponding output implying the decrement of the boundary and ofthe number of values available in dependencies. Notice that in order for a port to output a value, there canbe no initial dependencies present (which are dropped once satisfied), only per each value dependencies.In the following example and in the rest of the paper (where appropriate) we adopt the followingnotation: i abbreviates the image type, c abbreviates the class type and v abbreviates the version type. Example 4.1.
We revisit the type of component K
Portal shown in Section 3 < { x p ( i ) , x (cid:48) p ( c ) } ; { y p ( i ) : ∞ : [ { x p : N } ] , y (cid:48) p ( c ) : ∞ : [ { x (cid:48) p : N } ] , y (cid:48)(cid:48) p ( v ) : ∞ : [ /0 ] } > for some N and N . Recall also type < { x ( i ) } ; { y ( c ) : 1 : [ { x : Ω } ] , y (cid:48) ( v ) : 1 : [ /0 ] } > that may evolve uponthe reception of an input on x as follows:y ( c ) : 1 : [ { x : Ω } ] x ? −→ y ( c ) : 0 : [ /0 ] [ T ] x / ∈ dom [ D ] y (cid:48) ( v ) : 1 : [ /0 ] x ? −→ y (cid:48) ( v ) : 1 : [ /0 ] [ T ] < { x ( i ) } ; { y ( c ) : 1 : [ { x : Ω } ] , y (cid:48) ( v ) : 1 : [ /0 ] } > x ? ( i ) −−→ < { x ( i ) } ; { y ( c ) : 0 : [ /0 ] , y (cid:48) ( v ) : 1 : [ /0 ] } > [ T ] The type language serves as a means to capture component behaviour, and types for components maybe obtained (inferred) as explained below. The results presented afterwards ensure that when the typeextraction is possible, then each behaviour in the component is explained by a behaviour in the type, andthat each behaviour in the type can eventually be exhibited by the component.
We describe the procedure that allows to (automatically) extract the type of a component, focusing firston the case of base components, remembering their reactive flavour. The goal is to identify the basic . Savanovi´c, L. Galletta & H.T. Vieira f ( ˜ x ) used in a local binder, we can infer the respective functiontype. We introduce the notation γ ( · ) to represent a mapping from basic elements (such as values, ports,or functions) to their respective types. We also use γ for lists of elements in which case we obtain thelist of respective types (e.g., γ ( , hello ) = integer , string ). Second, given a local binder y = f ( ˜ x ) < ˜ σ ,we need to count the number of values that y has available at runtime for each of the ports in ˜ x . Thiscorresponds to the number of elements in ˜ σ that have a mapping for a port x to a value, which we denoteby count ( x , ˜ σ ) defined as follows. Let X be the set of ports and Σ a set whose elements are the lists ofmappings from ports to values. Then function count : X × Σ → N is defined as follows: count ( x , ˜ σ ) = (cid:40) j if ˜ σ = σ , . . . , σ j , σ j + , . . . , σ l ∧ x ∈ (cid:84) ≤ i ≤ j dom ( σ i ) ∧ x / ∈ (cid:83) j + ≤ i ≤ l dom ( σ i ) σ are handled following a FIFO discipline, so the first (oldest) mappingsare the ones that need to be accounted for. We may now define our type extraction procedure for basecomponents: Definition 4.1 (Type Extraction for a Base Component) . Let [ ˜ x > ˜ y ] { y = f y ( ˜ x y ) < ˜ σ y , . . . , y k = f y k ( ˜ x y k ) < ˜ σ y k } be a base component, where ˜ y = y , y , . . . , y k .If there exists γ such that γ ( ˜ x ) = ˜ b and γ ( y ) = b (cid:48) , . . . , γ ( y k ) = b (cid:48) k and provided that γ ( f y i ) = ˜ b y i → b (cid:48) i forany i ∈ , . . . , k and that ˜ b y i = γ ( ˜ x y i ) for any i ∈ , . . . , k then the extracted type of the base component is < X b ; C > where X b = { x ( b ) | x ∈ ˜ x ∧ b = γ ( x ) } and C = { y i ( b i ) : ∞ : D y i | i ∈ , . . . , k ∧ b (cid:48) i = γ ( y i ) ∧ D y i = { x : count ( x , ˜ σ y i ) | x ∈ ˜ x y i }} In Definition 4 . f y i ), itsparameters ( ˜ x y i ) and the list of mappings ( ˜ σ y i ) are indexed with the output port that is associated to them( y i ), so as to allow for a direct identification. Moreover, notice that each list of arguments ˜ x y i (of function f y i ) is a permutation of list ˜ x , as otherwise they would be undefined. Notice also that every output portof the interface of the component has a local binder associated to it and that there is no local binder y t = f y t ( ˜ x y t ) < ˜ σ y t such that y t is not part of the component interface, i.e., we do not type componentsthat have undefined output ports or that declare unused local binders, respectively. We also rely inDefinition 4 . γ to ensure consistency. Namely, we consider γ provides the list ofbasic types for the input ports ( γ ( ˜ x ) = ˜ b ) and for the output ports ( γ ( y ) = b (cid:48) , . . . , γ ( y k ) = b (cid:48) k ). Then,we require that γ ( f y i ) , for each f y i , specifies the function type where the return type matches the oneidentified for y i (i.e., b (cid:48) i ). Furthermore, we require that the types of the parameters given in the functiontype (˜ b y i ) match the ones identified for the respective (permutation of) input port parameters ( γ ( ˜ x y i ) ).We then have that the extracted type of a base component is a composition of two elements. Thefirst one ( X b ) is a set of input ports which are associated with their basic types. The second one is aset of constraints C , one for each output port and of the form y i ( b (cid:48) i ) : ∞ : [ D y i ] . The constraint specifiesthe basic type ( b (cid:48) i ) which is associated to the output port, and the maximum number of values that canbe output on y i is unbounded ( ∞ ), since local binders can potentially perform computations indefinitely.The third element of the constraint ( D y i ) is a set of per each value dependencies (of port y i ) on the inputport parameters ˜ x y i , capturing that each value produced on y i depends on a value being received on allof the ports in ˜ x y i . Notice that the number of values that y i has available (at runtime) for each x in ˜ x y i isgiven by count ( x , σ y i ) .4 A type language for message passing component-based systems
From an operational perspective, Definition 4 . Example 4.2.
Consider our running example from Section 3, in particular, component K
Portal specifiedas [ x p , x (cid:48) p (cid:105) y p , y (cid:48) p , y (cid:48)(cid:48) p ] { y p = f u ( x p ) < ˜ σ y p , y (cid:48) p = f r ( x (cid:48) p ) < ˜ σ y (cid:48) p , y (cid:48)(cid:48) p = f () < ·} .Let us take γ such that γ ( x p , x (cid:48) p ) = i , c and γ ( y p ) = i, γ ( y (cid:48) p ) = c and γ ( y (cid:48)(cid:48) p ) = v. We know that functionf u takes an image (i) and gives an image in return, hence γ ( f u ) = i → i. Similarly, we also know thatfunction f r is typed as γ ( f r ) = c → c. Function f does not have any parameters hence γ ( time ) = () → v.The extracted set of input ports with their types is X b = { x p ( i ) , x (cid:48) p ( c ) } . Assume that the component is inthe initial (static) state, so the queues of lists of mappings are empty (i.e., ˜ σ y p = · = ˜ σ y (cid:48) p ). Hence, we havethat count ( x p , ˜ σ y p ) = and count ( x (cid:48) p , ˜ σ y (cid:48) p ) = . The extracted set of constraints is then C = { y p ( i ) : ∞ : [ { x p :0 } ] , y (cid:48) p ( c ) : ∞ : [ { x (cid:48) p :0 } ] , y (cid:48)(cid:48) p ( v ) : ∞ : [ /0 ] } and the extracted type of the component K Portal is < X b ; C > . Extracting the type of a composite component is more challenging than for a base component. The focusof the extraction procedure is on the interfacing subcomponent, which interacts both via forwarders andvia the protocol. For the purpose of characterising how components interact in a given protocol, weintroduce local protocols LP which result from the projection of a (global) protocol to a specific rolethat is associated to a component. We reuse the projection operation from [5], where message labels aremapped to communication ports (thanks to distribution binders D ) and also to basic types that describethe communicated values (that can be inferred from the ones of the ports). The syntax of local protocols LP is: LP : = x ? : b . LP | y ! : b . LP | µ X . LP | X | end .Term x ? : b . LP denotes a reception of a value of a type b on port x , upon which protocol LP is activated.Term y ! : b . LP describes an output in similar lines. Then we have standard constructs for recursion andfor specifying termination ( end ). Our local protocols differ from the ones used in [5] since here we onlyconsider choice-free global protocols. To simplify the setting, we consider global protocols that haveat most one recursion (consequently also the projected local protocols). We also consider that messagelabels can appear at most once in a global protocol specification (up to unfolding of recursion), hencealso ports occur only once in projected local protocols (also up to unfolding).We omit the definition of projection and present the intuition via an example. Example 4.3.
Let G be the (one-shot) protocol G = Portal image −−−→ RE ; RE class −−−→ Portal ; end from Section 3and let γ ( image , class ) = i , c be a function that given a list of a message labels returns a list of theirtypes.Then, the projection of protocol G to role Portal , denoted by G ↓ Portal is protocol y p !: i . x (cid:48) p ?: c . end andthe projection of G to role RE is local protocol x re ? : i . y re ! : c . end , where ports x (cid:48) p , y p , x re , y re are obtainedvia distribution binders RE . x re image ←−−− Portal . y p , Portal . x (cid:48) p class ←−−− RE . y re . Essentially, the local protocol of Portal describes that first it emits an image on y p and then receives a classification on x (cid:48) p , and the localprotocol of RE says that it first receives an image on x re and then outputs a result of a classification ony re . We introduce some notation useful for the definition of the type extraction for composite components.We use the language context for local protocols (excluding recursion), denoted by C , so as to abstractfrom the entire local protocol and focus on specific parts and we define it as: C [ · ] :: = x ? : b . C [ · ] | y ! : . Savanovi´c, L. Galletta & H.T. Vieira b . C [ · ] | · . We denote the set of ports appearing in a local protocol by fp ( LP ) and by rep ( LP ) the set ofports that occur in a recursion (e.g. in LP for recursion µ X . LP ). Considering a list of forwarders F , wedefine two sets: by F i we denote the set of (internal) input ports and by F o the set of (internal) outputports which are specified in F (e.g., if F = x p ← x then F i = { x p } ).We now introduce the important notions that are used in our type extraction, namely that accountfor values flowing in a protocol and for the kinds of dependencies involved in composite components.Finally, we address the boundaries for the output ports. Values flowing
Our types track the dependencies between output and input ports, including per eachvalue dependencies that specify how many values received on the input port are available to the outputport. As discussed in the previous section, for base components this counter is given by the numberof values available in the local binder queues. For composite components, as preliminary discussed inSection 3, per each value dependencies might actually result from a chain of dependencies that involvesubcomponents and the protocol. So, in order to count how many values are available in such case,we need to take into account how many values are in the subcomponents (which is captured by theirtypes) and also if a value is flowing in the protocol. We can capture the fact that a value is flowing byinspecting the structure of the protocol. In particular we are interested in values that flow from y to x when an output on y precedes an input in x in a recursive protocol, hence when the protocol is of theform C [ µ X . C (cid:48) [ y ! : b (cid:48) . C (cid:48)(cid:48) [ x ? : b . LP (cid:48) ]] . The value is flowing when the output has been carried out but theinput is yet to occur, which we may conclude if the protocol is also of the form C (cid:48)(cid:48)(cid:48) [ x ? : b . LP (cid:48)(cid:48) ] where x , y / ∈ fp ( C (cid:48)(cid:48)(cid:48) [ · ]) . We denote by vf ( LP , x , y ) that there is a value flowing from y to x in LP , in which case vf ( LP , x , y ) =
1, otherwise vf ( LP , x , y ) =
0. We will return to this notion in the context of the extractionof the dependencies of the output ports, discussed next.
Kinds of dependencies
Composite components comprise two kinds of dependencies between outputports and input ports, illustrated in Figure 1 and Figure 2, which are dubbed direct and transitive, respec-tively. Figure 1: Direct Dependency Figure 2: Transitive DependencyWe gather the set of direct dependencies, i.e., when external output ports directly depend on externalinput ports (see Figure 1), in D d ( C , F , y ) which is defined as follows: D d ( C , F , y ) (cid:44) { x : M | C = { y ( b y ) : B : [ { x : M } (cid:93) D ] } (cid:93) C (cid:48) ∧ x ∈ F i ∧ y ∈ F o } Hence, in D d ( C , F , y ) we collect all the dependencies for y given in (internal) constraint C whenever bothports are external and preserving the kind of dependency M so as to lift it to the outer interface.For transitive dependencies (see Figure 2) to exist there are three necessary conditions. The firstcondition is to have in the description of a local protocol at least one output action, say on port y (cid:48) , thatprecedes at least one input action, say on port x (cid:48) . The second condition is that such output port y (cid:48) dependson some external input port x and the third condition is that there exists some external output port y thatdepends on the input on x (cid:48) . In such cases, we say that y depends on x in a transitive way.6 A type language for message passing component-based systems
We introduce a relation that allows to capture the first condition above. Let LP be the local protocolthat is prescribed for an interfacing component. Two ports x (cid:48) and y (cid:48) are in relation (cid:5) LPi for some localprotocol LP if x (cid:48) , y (cid:48) ∈ fp ( LP ) and where i ∈ { , , } as follows: y (cid:48) (cid:5) LP x (cid:48) if LP = C [ y (cid:48) !: b y (cid:48) . C (cid:48) [ x (cid:48) ?: b x (cid:48) . LP (cid:48) ]] and x (cid:48) , y (cid:48) / ∈ rep ( LP ) ; y (cid:48) (cid:5) LP x (cid:48) if LP = C [ y (cid:48) ! : b y (cid:48) . C (cid:48) [ µ X . C (cid:48)(cid:48) [ x (cid:48) ? : b x (cid:48) . LP (cid:48) ]]] and y (cid:48) / ∈ rep ( LP ) ; y (cid:48) (cid:5) LP x (cid:48) if LP = C [ µ X . C (cid:48) [ y (cid:48) ! : b y (cid:48) . C (cid:48)(cid:48) [ x (cid:48) ? : b x (cid:48) . LP (cid:48) ]]] . We distinguish three cases: when both the output and the inputare non-repetitive, when only the input is repetitive, and when both the output and the input are repetitive.We may now characterise the transitive dependencies. Let [ ˜ x (cid:48) (cid:105) ˜ y (cid:48) ] { G ; r = K , R ; D ; r [ F ] } be the com-posite component, T r = < X b , C > the type of interfacing component K and LP its local protocol. Theset of transitive dependencies on y , denoted D t ( C , F , LP , y ) , is defined relying on an abbreviation η asfollows: η = C = { y ( b ) : B : [ { x (cid:48) : M (cid:48) } (cid:93) D (cid:48) ] , y (cid:48) ( b ) : B (cid:48) : [ { x : M } (cid:93) D ] } (cid:93) C (cid:48) ∧ x ∈ F i ∧ y ∈ F o ∧ y (cid:48) (cid:5) LPi x (cid:48) D t ( C , F , LP , y ) (cid:44) (cid:8) x : Ω | η ∧ i ∈ { , } ∧ M ≯ } (cid:83) (cid:8) x : Ω | η ∧ i = ∧ ( M = Ω ∨ ( M (cid:48) = Ω ∧ M = ∧ vf ( LP , x (cid:48) , y (cid:48) ) = )) (cid:9) (cid:83) (cid:8) x : ( N + N (cid:48) + vf ( LP , x (cid:48) , y (cid:48) )) | η ∧ i = ∧ M = N ∧ M (cid:48) = N (cid:48) (cid:9) In η we gather a conjunction of conditions that must always hold in order for a transitive dependencyto exist: namely that the (internal) constraint C specifies dependencies between y and x (cid:48) and between y (cid:48) and x and also that y and x are external ports while y (cid:48) precedes x (cid:48) in the protocol. To simplify presentationof the definition of D t ( C , F , LP , y ) we rely on the (direct) implicit matching in η of the several mentionedelements.There are two kinds of transitive dependencies that are gathered in D t ( C , F , LP , y ) , namely initial( x : Ω ) and per each value ( x : N ). For initial dependencies there are two separate cases to consider. Thefirst case is when the protocol specifies that the output on y (cid:48) is non-repetitive ( i ∈ { , } ), hence will beprovided only once. Condition M ≯ η ), hence either M = x : Ω or M = y (cid:48) and x (cid:48) are repetitive in theprotocol ( i =
3) but at least one of the internal dependencies (between y (cid:48) and x and between y and x (cid:48) ,given by M and M (cid:48) respectively) is an initial dependency. This means that, regardless of the protocol,such a dependency is dropped as soon as a value is provided which implies that the transitive dependencyis also dropped. Since M is at the beginning of the dependency chain, if it is initial then no furtherconditions are necessary. However, if M (cid:48) is initial we need to ensure that there is no value alreadyflowing ( vf ( LP , x (cid:48) , y (cid:48) ) =
0) or already available to be output on y (cid:48) ( M = vf ( LP , x (cid:48) , y (cid:48) ) = M ≥ y (cid:48) and x (cid:48) are repetitive in the protocol ( i =
3) and internal dependencies M and M (cid:48) are both per each valuedependencies ( M = N and M (cid:48) = N (cid:48) ), which means that the dependency chain is persistent. The numberof values available of (external) x for y is the sum of the values available in the internal dependencies ( N and N (cid:48) ) plus one if there is a value flowing (zero otherwise). Notice that the definition of value flowingpresented previously focuses exclusively in the case when y (cid:48) and x (cid:48) are repetitive in the protocol, sincethis is the only case where values might be flowing and the dependency is still present in the protocolstructure (i.e., y (cid:48) (cid:5) LP x (cid:48) holds). In contrast, a dependency y (cid:48) (cid:5) LPi x (cid:48) for i ∈ { , } is no longer (structurally) . Savanovi´c, L. Galletta & H.T. Vieira y (cid:48) no longer occurs in the protocol after anoutput).It might be the case that one output port depends in multiple ways on the same input port. For thatreason we introduce a notion of priority among dependencies, denoted by pr ( , ) that gives priority to pereach value dependencies (with respect to “initial”). The priority builds on the property that if multipleper each value dependencies (including direct and transitive) are collected (e.g., x : N , . . . , x : N k ) then thenumber of available values specified in them is the same (i.e., N = . . . = N k ). The list of dependenciesfor port y is then given by the (prioritised) union of direct and transitive dependencies: D ( C , F , LP , y ) = pr ( D d ( C , F , y ) ∪ D t ( C , F , LP , y )) Boundaries
The last element that we need to determine in order to extract the type of a compositecomponent is the boundary of output ports. The type of the interfacing component already specifies a(internal) boundary, however this value may be further bound by the way in which the component is usedin the composition. In particular, if an output port depends on input ports that are not used in the protocolnor are linked to external ports, then no (further) values are received in them and the potential for theoutput port is consequently limited. We distinguish three cases for three possible limitations: B = { N (cid:48) | C = y ( b ) : B : [ { x (cid:48) : N (cid:48) } (cid:93) D (cid:48) ] (cid:93) C (cid:48) ∧ x (cid:48) / ∈ ( fp ( LP ) ∪ F i ) } B = { | C = { y ( b ) : B : [ { x (cid:48) : Ω } (cid:93) D (cid:48) ] } (cid:93) C (cid:48) ∧ x (cid:48) / ∈ ( fp ( LP ) ∪ F i ) } B = { ( N (cid:48) + ) | C = { y ( b ) : B : [ { x (cid:48) : N (cid:48) } (cid:93) D (cid:48) ] } (cid:93) C (cid:48) ∧ x (cid:48) ∈ fp ( LP ) ∧ x (cid:48) / ∈ ( rep ( LP ) ∪ F i ) } In B and B we capture the case when there is a dependency on a port that is not used in the protocol( x (cid:48) / ∈ fp ( LP ) ) nor linked externally ( x (cid:48) / ∈ F i ), where the difference is in the kind of dependency. Forper each value dependencies (if any), the minimum of the internally available values is identified as thepotential boundary, while for initial dependencies (if present) the potential boundary is zero (or the emptyset). In B we capture a case similar to B where the port is used in the protocol but in a non-repetitiveway, hence only one (further) value can be provided.The final boundary determined for y , denoted by B ( y , LP , C ) , is the minimum number among theinternal boundary of y (i.e., B if C = y ( b ) : B : [ D ] (cid:93) C (cid:48) ) and possible boundaries B , B and B describedabove. B ( y , LP , C ) = min ( { B } ∪ B ∪ B ∪ B ) We may now present the definition of type extraction of a composite component relying on a renam-ing operation. Since the type extraction of a composite component focuses on the interfacing subcompo-nent, we single out the ports that are linked via forwarders to the external environment. To capture suchlinks, we introduce renaming operation ren ( , ) that renames the ports of the interfacing subcomponentto the outer ones by using the forwarders as a guideline. For example, if we have that F = x p ← x than ren ( F , x p ) = x . Definition 4.2 (Type Extraction for a Composite Component) . Let [ ˜ x (cid:105) ˜ y ] { G ; r = K , R ; D ; r [ F ] } be a com-posite component and LP = G (cid:23) r the local protocol for component K. If T r = < X rb ; C r > is the type ofcomponent K, then the extracted type from LP and T r isT ( LP , T r , F ) = ren ( F , < X b ; C > ) where: X b = { x ( b ) | x ( b ) ∈ X rb ∧ x ∈ F i } C = { y ( b (cid:48) ) : B ( y , LP , C r ) : [ D ( C r , F , LP , y )] | C r = { y ( b (cid:48) ) : B (cid:48) : [ D (cid:48) ] } (cid:93) C (cid:48) ∧ y ∈ F o } . Example 4.4.
Let us extract the type of component K
IRS from Section 3 considering protocol G = Portal image −−−→ RE ; RE class −−−→ Portal ; end . The type of interfacing component K Portal isT
Portal = < { x p ( i ) , x (cid:48) p ( c ) } ; { y p ( i ) : ∞ : [ { x p : N p } ] , y (cid:48) p ( c ) : ∞ : [ { x (cid:48) p : N (cid:48) p } ] , y (cid:48)(cid:48) p ( v ) : ∞ : [ /0 ] } > A type language for message passing component-based systems
We have that local protocol is LP = y p ! : i . x (cid:48) p ? : c . end and sets of external ports F i = { x p } and F o = { y (cid:48) p , y (cid:48)(cid:48) p } , where ren ( F , x p ) = x, ren ( F , y (cid:48) p ) = y and ren ( F , y (cid:48)(cid:48) p ) = y (cid:48) . This immediately gives us the set ofinput ports that is in the description of the type of component K IRS which is X b = { x ( i ) } .Let us now determine the constraints of the output ports. Since port y (cid:48)(cid:48) p has no dependencies alsoport y (cid:48) will not have any, and moreover has the same boundary ( ∞ ). So, the extracted constraint for y (cid:48) will be ren ( y (cid:48)(cid:48) p ( v ) : ∞ : [ /0 ]) , which is y (cid:48) ( v ) : ∞ : [ /0 ] . Port y (cid:48) p instead depends on port x (cid:48) p which is used inthe protocol (x (cid:48) p ∈ fp ( LP ) ). Since the protocol is not recursive we have the consequent limited boundary(case B explained above), namely the boundary of y (cid:48) p is min ( N (cid:48) p + , ∞ ) = N (cid:48) p + . Furthermore. we havethat y p (cid:5) LP x (cid:48) p and that y p has per each value dependency x p : N p . If N p > then y (cid:48) p does not transitivelydepend on x p , otherwise there is an initial dependency. Let us consider the initial (static) state whereno image has been receive yet, i.e., N p = . In such case we have that the resulting constraint for y (cid:48) p isy (cid:48) p ( c ) : N (cid:48) p : [ x p : Ω ] , which after renaming for y is y ( c ) : N (cid:48) p : [ x p : Ω ] . So, the extracted type of K IRS is thefollowing { x ( i ) } ; { y ( c ) : N (cid:48) p : [ x p : Ω ] , y (cid:48) ( v ) : ∞ : [ /0 ] } In this section we present our main results that show a tight correspondence between the behaviourof components and of their extracted types. Apart from the conditions already involved in the typeextraction, for a component to be well-typed we must also ensure that any component that interacts in aprotocol can actually carry out the communication actions prescribed by the protocol.For this reason we introduce the conformance relation, denoted by (cid:46)(cid:47) , that asserts compatibility be-tween the type of a component and the local protocol that describes the communication actions prescribedfor the component. For the purpose of ensuring compatibility, in particular for the interfacing component,we also introduce an extension of our type language, dubbed modified types T (see Appendix A). Theidea for modified types is to allow to abstract from input dependencies from the external environment,namely by considering such dependencies can (always) potentially be fulfilled, allowing conformance tofocus on internal compatibility. By T ( F , T ) we denote the modified type that results from abstractingsuch external dependencies in T , relying on forwarders F , namely by considering per each value depen-dencies for external input ports are unbounded ( ∞ ) and dropping initial dependencies. The rules for thesemantics of modified types are the same as the ones shown in Section 4, the only implicit difference formodified types is that decrementing an unbounded dependency has no effect.The definition of the conformance relation (see Appendix B) is given by induction on the structureof the local protocol and it is characterised by judgments of the form Γ (cid:96) T (cid:46)(cid:47) LP , where Γ is a typeenvironment that handles protocol recursion (i.e., Γ maps recursion variables to modified types). Wereport and comment here only on the rules for input and output: T x ? ( b ) −−−→ T (cid:48) Γ (cid:96) T (cid:48) (cid:46)(cid:47) LP Γ (cid:96) T (cid:46)(cid:47) x ? : b . LP [ InpCon f ] T y ! ( b ) −−→ T (cid:48) Γ (cid:96) T (cid:48) (cid:46)(cid:47) LP Γ (cid:96) T (cid:46)(cid:47) y ! : b . LP [ OutCon f ] Rule [
InpCon f ] states that a modified type T is conformant with protocol x ? : b . LP , if T can input avalue of type b on port x and if continuation T (cid:48) is conformant with the continuation of protocol LP . Rule[ OutCon f ] is similar but deals with the output of a value on port y .We can now formally define when a component K has type T , in which case we say K is well-typed. Definition 4.3.
Let K be a component, we say that K has a type T , denoted by K ⇓ T :1. If K is a base component, K ⇓ T when T is obtained by Definition . . . Savanovi´c, L. Galletta & H.T. Vieira
2. If K = [ ˜ x > ˜ y ] { G ; r = K , . . . , r k = K k ; D ; r [ F ] } then K ⇓ T when • ∃ T r i | K i ⇓ T r i , for i = , , . . . , k; • T is extracted type from T and G (cid:23) r by Definition . ; • T ( F , T r i ) (cid:46)(cid:47) G (cid:23) r i for i = , , . . . , k; Notice that the definition relies on modified types for conformance, but for any type T not associatedwith the interfacing component we have that T ( F , T ) = T since there can be no links to external ports(assuming that all ports have different identifiers).We can now our type safety results given in terms of Subject Reduction and Progress, which providethe correspondence between the behaviours of well-typed components and their types. In the statementswe rely on notation λ ( v ) that represents x ? ( v ) , y ! ( v ) or τ and λ ( b ) that represents x ? ( b ) , y ! ( b ) or τ . Theorem 4.1 (Subject Reduction) . If K ⇓ T and K λ (v) −−→ K (cid:48) and v has type b then T λ ( b ) −−→ T (cid:48) and K (cid:48) ⇓ T (cid:48) .Proof. By induction on the derivation of K λ ( v ) −−→ K (cid:48) .Theorem 4 . K performs a computation step to K (cid:48) , then its type T can also evolve to type T (cid:48) which is the type of component K (cid:48) . Moreover, the theorem ensures that if K carries out an input or an output of a value v , type T performs the corresponding action at the levelof types. Theorem 4 . K λ (v) == ⇒ K (cid:48) to denote a sequence of transitions K τ −→ · · · K (cid:48)(cid:48) λ ( v ) −−→ K (cid:48)(cid:48)(cid:48) τ −→ · · · K (cid:48) , i.e, that component K may perform a sequence of internal moves, then an I/O action, after which another sequence of internalmoves leading to K (cid:48) . Theorem 4.2 (Progress) . If K ⇓ T and T λ ( b ) −−→ T (cid:48) and λ ( b ) (cid:54) = τ then b is the type of a value v andK λ (v) == ⇒ K (cid:48) and K (cid:48) ⇓ T (cid:48) .Proof. By induction on the structure of K .Theorem 4 . T of component K can evolve by exhibiting an I/O action to type T (cid:48) ,then K can eventually (up to carrying out some internal computations) exhibit a corresponding actionleading to K (cid:48) , and where K (cid:48) has type T (cid:48) . Theorem 4 . .
1, to attest that types faithfully capture component behaviour. Intuitively,our types can be seen as promises of behaviour in the sense that whatever they prescribe as possiblebehaviours, the components will eventually deliver. For the sake of addressing any possible componentconfiguration, in particular when components have already all the dependencies (internally) satisfied inorder to provide some behaviour, it is crucial that types capture the number of (internally) availableresources.
In this paper we introduce a type language for the choice-free subset of the GC language [5] that char-acterises the reactive behaviour of components and allows to capture “what components can do”. In0
A type language for message passing component-based systems particular, our types describe the ability of components to receive and send values, while tracking differ-ent kinds of dependencies (per each value and initial ones) and specifying constraints on the boundaryof the number of values that a component can emit. We show how types of components can be extracted(inferred) and prove that types faithfully capture component behaviour by means of Subject Reductionand Progress theorems. Typing descriptions such as ours are crucial to promote component reusability,since to use a component we should only need to analyse its type and not its implementation (like in [5]).For instance, for the sake of ensuring the behaviour of a component is compatible with a governing com-munication protocol, where such compatibility is attested in our case by the conformance of the type tothe (local) protocol.We place our approach in the behavioural types setting (cf. [10]) since our types evolve in orderto explain component behaviour (cf. Theorem 4 . service based architectures (SOA’s) [13] ex-poses components that exchange services between each other via ports. However, the authors do notpresent the type language, where some ideas we presented for extracting a type of a component could beused for the model they present.We may also find the notion of distributed components is the Signal Calculus (SC) [6], where in eachcomponent a process is located. The type-based approach presented in [7] addresses the issue of ensuringSC local processes are composed and interact in a way such that they follow a well-defined protocol ofinteraction. Our model embeds the protocol in the operational semantics so such coordination is ensuredby construction. Our types focus on a different purpose of ensuring data dependencies are met in orderto ensure components are not stuck in the sense of the progress result.In the work about Interactive verification of ADPs [14] the authors introduce a notion of componenttype which characterizes components with a certain behaviour. One core difference between [14] and ourwork is that the authors do not provide any means to automatically extract types from given components.We believe the ideas reported in this paper can contribute to the theoretical basis for providing sup-port for component-based development in distributed systems. Immediate directions for future workinclude the support for protocols with branching, and providing a characterisation of the substitution . Savanovi´c, L. Galletta & H.T. Vieira Acknolegements
We thank the anonymous reviewers for their suggestions and comments which helpedus to improve the paper.
References [1] Amazon Web Services, Inc (2019):
AWS Lambda: Developer Guide . Available at https://docs.aws.amazon.com/en_pv/lambda/latest/dg/lambda-dg.pdf .[2] Marco Autili, Amleto Di Salle, Francesco Gallo, Claudio Pompilio & Massimo Tivoli (2019):
CHOReVOLUTION: Automating the Realization of Highly–Collaborative Distributed Applica-tions . In Hanne Riis Nielson & Emilio Tuosto, editors: , Coordination Models and Languages
LNCS-11533, Springer International Publishing, pp. 92–108, doi:10.1007/978-3-030-22397-7 6. Part 2:Tools (1).[3] Franco Barbanera & Mariangiola Dezani-Ciancaglini (2019):
Open Multiparty Sessions . In Mas-simo Bartoletti, Ludovic Henrio, Anastasia Mavridou & Alceste Scalas, editors:
Proceedings 12thInteraction and Concurrency Experience, ICE 2019, Copenhagen, Denmark, 20-21 June 2019 , EPTCS
Deadlock-freedom-by-design: multiparty asyn-chronous global programming . In Roberto Giacobazzi & Radhia Cousot, editors:
The 40th An-nual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL ’13,Rome, Italy - January 23 - 25, 2013 , ACM, pp. 263–274, doi:10.1145/2429069.2429101.[5] Marco Carbone, Fabrizio Montesi & Hugo Torres Vieira (2018):
Choreographies for ReactiveProgramming . CoRR abs/1801.08107. Available at http://arxiv.org/abs/1801.08107 .[6] Gian Luigi Ferrari, Roberto Guanciale & Daniele Strollo (2006):
JSCL: A Middleware for ServiceCoordination . In Elie Najm, Jean-Franc¸ois Pradat-Peyre & V´eronique Donzeau-Gouge, editors:
Formal Techniques for Networked and Distributed Systems - FORTE 2006, 26th IFIP WG 6.1 In-ternational Conference, Paris, France, September 26-29, 2006 , Lecture Notes in Computer Science
Coordination ViaTypes in an Event-Based Framework . In John Derrick & J¨uri Vain, editors:
Formal Techniquesfor Networked and Distributed Systems - FORTE 2007, 27th IFIP WG 6.1 International Confer-ence, Tallinn, Estonia, June 27-29, 2007, Proceedings , Lecture Notes in Computer Science
Microservices: Yesterday, today, and tomorrow . InManuel Mazzara & Bertrand Meyer, editors:
Present and Ulterior Software Engineering , Springer,pp. 195–216, doi:10.1007/978-3-319-67425-4 12.[9] Kohei Honda, Nobuko Yoshida & Marco Carbone (2016):
Multiparty Asynchronous Session Types . J. ACM
A type language for message passing component-based systems [10] Hans H¨uttel, Ivan Lanese, Vasco T. Vasconcelos, Lu´ıs Caires, Marco Carbone, Pierre-MaloDeni´elou, Dimitris Mostrous, Luca Padovani, Ant´onio Ravara, Emilio Tuosto, Hugo Torres Vieira& Gianluigi Zavattaro (2016):
Foundations of Session Types and Behavioural Contracts . ACMComput. Surv.
CHOReVOLUTION project . .[12] Barbara Liskov & Jeannette M. Wing (1994): A Behavioral Notion of Subtyping . ACM Trans.Program. Lang. Syst.
A Model of Service-Oriented Architectures . In: , IEEE ComputerSociety, Los Alamitos, CA, USA, pp. 110–119, doi:10.1109/SBCARS.2015.22.[14] Diego Marmsoler & Habtom Kashay Gidey (2019):
Interactive verification of architectural designpatterns in FACTum . Formal Aspects of Computing
Mass Produced Software Components . In:
Software Engineering:Report of a conference sponsored by the NATO Science Committee , Garmisch, pp. 138–155.[16] Fabrizio Montesi (2013):
Choreographic Programming . Ph.D. thesis, IT University of Copen-hagen. Available at http://fabriziomontesi.com/files/choreographic_programming.pdf .[17] Object Management Group, Inc. (OMG) (2014):
Business Process Model and Notation, specifica-tion version 2.0.2 . Available at .[18] W3C WS-CDL Working Group (2004):
Web Services Choreography Description Language Version1.0 . Available at . A Modified type T Now we introduce the modified type denoted by T . The interfacing component of the composite one,beside its interaction with other components, also interacts with an external environment. In this case thecrucial part is that it is able to receive in any moment values that are input externally. For the purpose ofobserving if a type of a component can perform actions required by the protocol, we need to modify thetype according to the possible inputs that a (interfacing) component can receive from the external contextwithout any constraints. The modified type of a type T , taking into account the list of corresponding listof forwarders, is denoted by T ( F , T ) . If T is the type of the interfacing component, each dependency onthe external input ports is per each value dependency and the number of values available is unbounded(assuming that whenever the value is available it is received on the external input ports). The syntax of T -type is given in the Table 6. It is similar to a syntax of the types which we have already shown, withthe difference in the number of values received, that in the modified type can be unbounded (infinite).Moreover, the rules defining the semantics of modified type are the same as the ones shown for our typ-ing language (Table 7). T -Type syntax . Savanovi´c, L. Galletta & H.T. Vieira Types Constraints Dependencies T ∆ = < X b ; C > X b ∆ = { x ( b ) , . . . , x k ( b k ) } C ∆ = { y ( b ) : B : [ D ] , . . . , y k ( b k ) : B k : [ D k ] } D ∆ = { x : M , . . . , x k : M k } Kinds of Dependencies Boundaries M :: = N | Ω B :: = N | ∞ k ≥ N ∈ N N :: = N | ∞ Table 6: T -Type syntax T -Type semantics x / ∈ dom [ D ] y ( b ) : B : [ D ] x ? −→ y ( b ) : B : [ D ] [ T ] y ( b (cid:48) ) : B : [ { x : Ω } (cid:93) D ] x ? −→ y ( b (cid:48) ) : B : [ D ] [ T ] y ( b (cid:48) ) : B : [ { x : N } (cid:93) D ] x ? −→ y ( b (cid:48) ) : B : [ { x : N + } (cid:93) D ] [ T ] T τ −→ T [ T ] ∀ i ∈ , , . . . , k y i ( b i ) : B i : [ D i ] x? −→ y i ( b i ) : B i : [ D (cid:48) i ] < { x ( b x ) (cid:93) X b } ; { y i ( b i ) : B i : [ D i ] | i ∈ , . . . , k } > x ? ( b x ) −−−→ < { x ( b x ) (cid:93) X b } ; { y i ( b i ) : B i : [ D (cid:48) i ] | i ∈ , . . . , k } > [ T ] B > N i ≥ < X b ; { y ( b y ) : B : [ { x i : N i | i ∈ , . . . , k } ] } (cid:93) C > y ! ( b y ) −−−→ < X b ; { y ( b y ) : B − [ { x i : N i − | i ∈ , . . . , k } ] } (cid:93) C > [ T ] Table 7: T Semantics
Definition A.1.
If T r = < X b ; C > is a type of interfacing subcomponent K of composite component [ ˜ x > ˜ y ] { G ; r = K , R ; D ; r [ F ] } then T ( F , T r ) is the T r -modified type where: T ( F , < X b , C > ) (cid:44) < X b ; T ( F , C ) > T ( F , { y ( b ) : B : [ D ] } (cid:93) C ) (cid:44) T ( F , { y ( b ) : B : [ D ] } ) (cid:93) T ( F , C ) T ( F , { y ( b ) : B : [ D ] } ) (cid:44) { y ( b ) : B : [ T ( D )] } T ( F , { x : M } (cid:93) D ) (cid:44) T ( F , { x : M } ) (cid:93) T ( D ) where M ∈ { N , Ω } T ( F , x : M ) (cid:44) { x : M } if x / ∈ F i , where M ∈ { N , Ω } T ( F , x : M ) (cid:44) { x : ∞ } if x ∈ F i T ( F , x : Ω ) (cid:44) /0 if x ∈ F i Note that for K = [ ˜ x > ˜ y ] { G , r = K , r = K , . . . , r n = K n ; D ; r [ F ] } we have that T ( F , T r ) = T r , . . . , T ( F , T r k ) = T r k since the only component that forwards the values from/to external environment is component K .4 A type language for message passing component-based systems
B Conformance relation T x ? ( b ) −−−→ T (cid:48) Γ (cid:96) T (cid:48) (cid:46)(cid:47) LP Γ (cid:96) T (cid:46)(cid:47) x ? : b . LP [ InpCon f ] T y ! ( b ) −−→ T (cid:48) Γ (cid:96) T (cid:48) (cid:46)(cid:47) LP Γ (cid:96) T (cid:46)(cid:47) y ! : b . LP [ OutCon f ] Γ (cid:96) T (cid:46)(cid:47) end [ EndCon f ] T (cid:48) ≤ T Γ , X : T (cid:48) (cid:96) T (cid:46)(cid:47) X [ VarCon f ] Γ , X : T (cid:96) T (cid:46)(cid:47) LP Γ (cid:96) T (cid:46)(cid:47) recX . LP [ RecCon f ] Table 8: Conformance
Definition B.1. T (cid:48) ≤ T if exists a (possibly empty) set of typed input ports { x ( b ) , x ( b ) , . . . , x k ( b k ) } such that T (cid:48) x ? ( b ) −−−−→ · · · x k ? ( b k ) −−−−→ T . Rule [
InpCon f ] ensures that a modified type T is conformant with the protocol, where it can receivean input of a matching type with a continuation as a protocol LP , if a modified type can receive a value onport x , and assuming that port x receives a values of type b and the evolved type is conformant with LP .Similar reasoning is for an output. Rule [ EndCon f ] states that a modified type is always conformant withthe termination protocol. Finally, we have two rules [
VarCon f ] and [
RecCon f ] for the recursion. Thepremise of Rule [