Document not found! Please try again

A WSDL-based type system for WS-BPEL - CiteSeerX

5 downloads 0 Views 274KB Size Report
Mar 28, 2006 - A compensation stack push function, denoted by csp(h,κn) with κn ∈ SIDN .... An operational semantics for stac, a language ... Electronic Notes.
A WSDL-based type system for WS-BPEL∗ Alessandro Lapadula, Rosario Pugliese and Francesco Tiezzi Dipartimento di Sistemi e Informatica, Universit`a di Firenze

March 28, 2006 Abstract We tackle the problem of providing rigorous formal foundations to current software engineering technologies for web services. We focus on two of the most used XML-based languages for web services: WSDL and WS-BPEL. To this aim, first we select an expressive subset of WS-BPEL, with special concern for modeling the interactions among web service instances in a network context, and define its operational semantics. We call - the resulting formalism. Then, we put forward a rigorous typing discipline that formalizes the relationship existing between - terms and the associated WSDL documents and supports verification of their compliance. We prove that the type system and the operational semantics of - are ‘sound’ and apply our approach to a pair of illustrative examples. Finally, we extend the - to define an operational semantics for whole WS-BPEL.

Contents 1 Introduction

2

2 - 2.1 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Operational semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 4 6

3 Types 3.1 Type inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Type soundness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10 11 13

4 Examples 4.1 A brokerage scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Shipping service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21 21 22

5 Extensions of - 5.1 Flow graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Timed activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 Scopes and compensation handling . . . . . . . . . . . . . . . . . . . . . . . . . .

31 31 32 35

6 Concluding remarks

37

References

39

Appendix

40



Supported by EU within the FP6-2004-IST-FET Proactive project SENSORIA proposal contract number 016004.

1

1 Introduction Service-Oriented Computing (SOC) has recently put forward as a promising computing paradigm for developing massively distributed, interoperable, evolvable systems and applications that exploit the pervasiveness of the Internet and its related technologies. The SOC paradigm advocates the use of ‘services’, to be understood as autonomous, platform-independent computational entities that can be described, published, discovered, and dynamically assembled, as the basic blocks for building applications. Web services (WS), along with grid computing, are the present most successful instantiation of the SOC paradigm, as it is demonstrated by the fact that companies like IBM, Microsoft and Sun invested a lot of efforts and resources to promote their deployment. A web service is basically a set of operations that can be invoked through the Web via XML messages complying with given standard formats. To support the WS approach, many new languages, most of which based on XML, have been designed, like e.g. business coordination languages (such as WS-BPEL, WSFL, WSCI, and XLANG), contract languages (such as WSDL and SWS), and query languages (such as XPath and XQuery). However, current software engineering technologies for WS still lack rigorous formal foundations. The challenges come from the necessity of dealing at once with issues like communication, co-operation, resource usage, failures, security, etc. in a setting where demands and guarantees can be very different for the many components. In this paper we focus on two of the most used XML-based languages for WS: Web Services Description Language (WSDL [CCMW01]) and Web Services Business Process Execution Language (WS-BPEL [BCG+ 05]). The former is a W3C standard that permits to express the functionalities offered and required by web services by defining, akin object interfaces in Object-Oriented Programming, the signatures of operations and the structure of the documents for invoking them and returned by them. The latter, currently under evaluation to become a standard by OASIS, permits to describe the activities to be executed for completing the service as a reaction to a service invocation. WSDL declarations can be exploited to verify the possibility of connecting different services, while WS-BPEL descriptions can be used to define new services by appropriately composing other existing ones. We aim at formalizing the relationship existing between WS-BPEL processes and the associated WSDL documents by putting forward a rigorous typing discipline. In general, the WSDL document associated to a WS-BPEL process does not contain the declarations of all the operations provided and required by the process, together with the structure of the messages exchanged. In fact, some of these declarations usually are in the WSDL documents of the orchestrated services. Moreover, WSDL provides four different types of operations, but only two of them are really supported by WS-BPEL: (synchronous) request-response and one-way. There is another interaction pattern that is largely used in WS-BPEL (see, e.g., the example 16.1 in [BCG+ 05]) but it is not provided by WSDL: asynchronous request-response. This last pattern is implemented through a partner link connecting two one-way operations but no constraint is imposed on which process must declare the type of the operations. Finally, WS-BPEL provides many redundant programming constructs and suggest a quite liberal programming style. For example, it is possible for a programmer to write parallel activities that have strict implicit dependencies so that they are sequentially (rather than concurrently) executed. To achieve our goal, we first define a semantic model for WS-BPEL because the semantics of the language, as presented in [BCG+ 05], is informal and, sometimes, ambiguous. Hence, as a first contribution of this paper, we introduce a process language, that we call - (web services calculus), that formalizes the semantics of an expressive subset of WS-BPEL, with special concern for modeling the interactions among web services, be them WS-BPEL processes or not, in a network context. This allows us to tackle those problems arising when executing WS-BPEL

2

processes, such as multiple start activities, receive conflicts, routing of messages, while avoiding the intricacies of dealing with any, possibly redundant, WS-BPEL construct. As a second contribution, we define a type system for - terms and show that the type system and the operational semantics are ‘sound’, in the sense that - terms reached along any reduction sequence starting from well-typed terms are still well-typed and, thus, do not generate runtime errors. The type system enforces many of the constraints imposed by WSDL/WS-BPEL, e.g. it prevents programs from passing links that have been implicitly initialized and from invoking callback operations that do not have previous triggering receive operations. However, in some cases it is even further restrictive so to enforce a more disciplined programming style. Thus, for example, the type system deems as ill-typed those programs containing flow activities that have strict implicit dependencies. Moreover, in case of asynchronous request-response, it forces the WSDL document associated to the process providing the service to contain the declaration of both the two operations, that for invoking the service and that for sending the reply back to the client. This last choice is dictated by the need to preserve two important properties of web services, namely compositionality and loose coupling. Indeed, should each client contain the declaration for the reply, then, if the service provider wants to modify such a declaration, all clients should be updated. Finally, we extend the - to incorporate such other important constructs of WS-BPEL as flow graphs, timed activities, scopes and compensation handling, that should be considered for modeling the semantics of full-blown orchestration languages. We will show that flow graphs can be easily encoded in -, while the semantics of the remaining constructs is given by extending the operational semantics of -. This way, as a third contribution, we define an operational semantics for WS-BPEL executable processes. A case study. As a reference case study, in this paper we consider the shipping service described in the official specification of WS-BPEL (Section 16.1). This example covers most of the language features we are interested in, including correlation sets, variables, and flow control structures. We assume that the reader is already familiar with the main features of WS-BPEL. This service handles the shipment of orders. From the service point of view, orders are composed of a number of items. The shipping service offers two types of shipment: shipments where the items are held and shipped together and shipment where the items are shipped piecemeal until all of the order is accounted for. The process definition of the shipping service exploits the following basic activities. The receive activity allows the service to receive orders from customers, the assign activity permits to handle the received data, and the invoke activity permits to send shipping notices to customers. An order request contains an order identifier that is used to correlate the ship notice(s) with the ship order. The flow control of the process is defined by means of conditional and iterative constructs. In our calculus, the latter is modelled by recursive definition. The formal description of the service will be presented in Section 4.2. Overview of the paper. The rest of the paper is organized as follows. Syntax and operational semantics of - are defined in Section 2, while the type system and the soundness results are presented in Section 3. Section 4 illustrates two applications of our framework to modelling examples of web services composition. Section 5 extends - and defines an operational semantics for the whole WS-BPEL. In Section 6 we touch upon directions for future work and comparisons with related work. The appendix contains a revisited version of the type system described in Section 3.

3

n C m s

::= ::= ::= ::= | | | | | | | | |

a ::Op,L C ∗s | m  s | ha, o, u¯ i | C | C ∅ | {p = u} | m ∪ m 0 exit ass (w, ¯ e¯ ) inv (r, o, w) ¯ rec (r, o, w) ¯ if (e) then {s} else {s} s; s s|s P ¯ i ) ; si i∈I rec (ri , oi , w A(w) ¯

(nodes) (components) (correlation constraints) (services) (null) (exit) (assign) (invoke) (receive) (switch) (sequence) (flow) (pick) (call)

Table 1: - syntax (The syntax of types Op, L is in Table 5)

2

-

- (web services calculus) permits to express web services in a primitive form with special concern for modeling the interactions among web service instances in a network context.  can directly model the semantics of an expressive subset of WS-BPEL, we refer the interested reader to Section 5 for a complete account of whole WS-BPEL.

2.1 Syntax The syntax of -, given in Table 1, is parameterized with respect to the following syntactic sets, which we assume to be countable and pairwise disjoint: properties (sorts of late bound constants storing some relevant values within service instances, ranged over by p), basic values (integers Int, strings Str, and booleans) and corresponding variables (ranged over by b), addresses (ranged over by a) and partner links (namely variables storing addresses used to identify service partners within an interaction, ranged over by l), and service identifiers (ranged over by A) each with a fixed nonnegative arity. The language is also parametric with respect to a set of operations, ranged over by o, which we do not specify, and expressions, ranged over by e, whose exact syntax is deliberately omitted; we just assume that expressions contain, at least, basic values and variables, partner links, addresses and properties. Notationally, we will use u to range over values (i.e. basic values and addresses), v to range over variables (i.e. basic variables and partner links), w to range over operation parameters (i.e. variables and properties), c to range over correlation patterns (i.e. values and properties), and r to range over addresses and partner links. Addresses may be underlined to denote that they cannot be transmitted as operation parameters, while partner links may be subject to the operator p· q that forces them to be already initialized. Notation ¯· denotes tuples of objects. E.g. v¯ is a tuple of variables; this will sometimes be written as v¯ i∈I , for an appropriate index-set I, and vi denotes the i-th element. We assume that variables in the same tuple are pairwise distinct. When convenient, we shall regard a tuple simply as a set writing e.g. a ∈ u¯ to mean that a is an element of u¯ . All notations shall extend to tuples component-wise. A - node can be thought of as a WS-BPEL process web service. Nodes, written as a ::Op,L C, are uniquely identified by an address a and have a declarative part Op, L, i.e. its type, 4

and a behavioural part C. Finite sets of nodes are called nets and are ranged over by N, N 0 , N1 , . . .. The type of a node collects all the information about the format of the messages exchanged by the operations available at the node, Op, and the local declarations, L, like the WSDL document associated to the corresponding WS-BPEL process web service. Since we are interested in describing asynchronous interactions, we model each communication pattern by connecting one or more one-way operations. In the simplest interaction, a single one-way operation suffices; the service provider process, which is the one that performs the receive activity, holds the type definition of the requested operation. The more complex asynchronous request-response interaction pattern is expressed by connecting two one-way operations (request and callback); in this case, the provider holds the type definitions of both operations (the rationale for this choice has been explained in the Introduction). We defer syntax of types and comments on them to Section 3. Components C may be service specifications, instances or requests. The behavioural specification of a service s is written ∗s, while m  s0 represents a service instance that behaves according to s0 and whose properties evaluate according to the (possibly empty) set m of correlation constraints. A correlation constraint is a pair, written p = u, recording the value u assigned to the property p. Properties are used to store values that are important to identify service instances. For example, one might use a property named purchase-order-id to uniquely identify instances of a service that handles purchase orders. A service request ha, o, u¯ i represents an operation invocation that must still be processed and contains the invoker address a, the operation name o and the data u¯ for operation execution. - operation names represent WS-BPEL pairs ‘partner link – operation’ (instead, WS-BPEL partner links are not explicitly modeled), thus pairs ‘a – o’, that are the first two components of service requests, represent endpoints between two interacting process web services. Services are structured activities built from basic activities, i.e. instance forced termination exit, assignment ass (·, ·), service invocation inv (·, ·, ·) and service request processing rec (·, ·, ·), by exploiting operators for conditional choice if (·) then {·} else {·} (switch), sequential composition P ·; · (sequence), parallel composition · | · (flow), external choice1 i∈I rec (·, ·, ·) ; · (pick) and service call A(w1 , · · · , wn ) where n is the arity of A. Every service identifier A with arity n has a unique de f definition of the form A(¯vi∈{1,..,n} : τ¯ ?i∈{1,..,n} ) = s, where the vi must be fresh and pairwise distinct. Notably, parameters of a service definition are typed (see the next section). The - binding constructs are ass (w, ¯ e¯ ) and rec (r, o, w) ¯ that bind the variables and the properties in w. ¯ The latter also binds r if it is a partner link and is not subject to the operator p· q; we will say that r is implicitly initialized (conversely, we will say that a partner link is explicitly initialized in all other cases). This means that pl q represents a free occurrence of l (e.g. a callback address) that must have been bound previously. The scope of the bindings extends to the whole component where the binder occurs (namely, like in WS-BPEL, variables and properties are global to the instance). A variable occurrence is free if it is not under the scope of a binder. We assume that all bound partner links are pairwise distinct, but for those occurring within alternative branches of switch and pick constructs. Thus, the following fragment of service is well-defined: . . . if (e) then {. . . rec (l, . . . , . . .) . . .} else {. . . rec (l, . . . , . . .) . . .}; inv (l, . . . , . . .) . . . In general, we use f v(s) (resp. bv(s)) to denote the set of variables which occur free (resp. bound) in de f s. In particular, variables of w¯ are free in A(w). ¯ In a definition A(¯v : τ¯ ? ) = s we assume f v(s) ⊆ v¯ . In the sequel we shall only consider nets that are well-formed in the sense that they comply with the following syntactic constraints. First, pairwise distinct nodes must have different addresses. Then, if we call start activities of a service s all those activities that are not syntactically preceded by other ones (as formalized by function eR() whose inductive definition will be described in a little 1

Whenever the external choice is between two activities, we shall simply write s1 + s2 .

5

s; 0 0; s (s; s0 ); s00 s+0 s + s0

≡ ≡ ≡ ≡ ≡

s + (s0 + s00 ) s+s s|0 s | s0 0 s | (s | s00 )

s s s; (s0 ; s00 ) s s0 + s

If s and s0 are α-equivalent

(s + s0 ) + s00 s s s0 | s (s | s0 ) | s00

s ≡ s0 s | C ≡ s0 | C

s ≡ s0 C|m0≡C

≡ ≡ ≡ ≡ ≡

C1 | C2 ≡ C2 | C1

(C1 | C2 ) | C3 ≡ C1 | (C2 | C3 )

C ≡ C0

N1 ≡ N10

{a ::Op,L C} ≡ {a ::Op,L C 0 }

N1 ∪ N2 ≡ N10 ∪ N2

Table 2: Structural congruence ≡

while), then at least one start activity of ∗s must be a rec (·, ·, ·) and, if multiple rec (·, ·, ·) are enabled concurrently, then they must use the same non-empty set of properties.

2.2 Operational semantics The operational semantics of - is given in terms of a structural congruence and of a reduction relation over nets. For the sake of simplicity, in this section we model taking place of errors (e.g. when the premises of reduction rules are not satisfied) simply as deadlock. We refer the interested reader to Section 5 for more details on fault throwing and handling exceptions. The semantics of nets will be defined over an enriched set of nets that also includes those auxiliary nets resulting from replacing (free occurrences of) variables with values in nets produced by the syntax of Table 1. Therefore, we will let free occurrences of v (and w) to also denote corresponding values. The structural congruence, denoted by ≡ and defined by the rules in Table 2, identifies syntactically different terms which intuitively represent the same term. In Table 2, and in the sequel, notation s shall denote both service specifications (∗s) and service instances (m  s). At the level of services, the structural congruence states that: the sequence operator is associative and has 0 as identity element (law 0; s ≡ s is exploited to enable a new activity when a preceding one terminates); the flow operator is commutative, associative and has 0 as identity element; the pick operator enjoys the same properties and, additionally, is idempotent; services only differing for the bound variables are the same (alpha-conversion). The remaining rules of Table 2 extend the structural congruence to components and nets, and should be self-explicative. In particular, components composition is commutative and associative, and has m  0 as identity element (i.e. instances of this form are terminated instances and, thus, can be removed). α The reduction relation over nets, written − →, relies on a labelled transition relation −−→ over service instances, where α is generated by the following production: α ::= \ | w¯ := u¯ | i(a, o, u¯ ) | r(r, o, w) ¯ The meaning of labels is as follows: \ denotes forced termination of a service instance, w¯ := u¯ denotes execution of a multiple assignment, i(a, o, u¯ ) denotes invocation of operation o located at a 6

\

w:= ¯ mB¯e

m ` ass (w, ¯ e¯ ) −−−−−−−→ 0 (Assign)

m ` exit −→ 0 (Exit)

r , pl q

i(a,o,mB¯c)

m ` inv (a, o, c¯ ) −−−−−−−−→ 0 (Invoke)

(Receive)

r(r,o,w) ¯

m ` rec (r, o, w) ¯ −−−−−−→ 0 α

m ` s2 −−→ s02

m B e = false

(Ifff )

α

m ` if (e) then {s1 } else {s2 } −−→ s02

α

m ` if (e) then {s1 } else {s2 } −−→ s01 α

α

m ` s1 −−→ s01 α

m ` s1 ; s2 −−→

s01 ; s2

m ` s1 −−→ s01

(Sequence)

r(r,o,w) ¯

m ` s1 −−−−−−→ s01

α

m ` s1 −−→ s01

m B e = true

α , r(·, ·, ·) α

m ` s1 | s2 −−→ s01 | s2

 @ rec r, o, w¯ 0 ∈ eR(s2 ) . P(w) ¯ = P(w¯ 0 ) r(r,o,w) ¯

(Iftt )

(Flow)

(FlowRec )

m ` s1 | s2 −−−−−−→ s01 | s2 r(r,o,w) ¯

m ` rec (r, o, w) ¯ ; s −−−−−−→ s0

@ i ∈ I . ri = r ∧ oi = o ∧ P(w¯ i ) = P(w) ¯ X (Pick) r(r,o,w) ¯ m ` rec (r, o, w) ¯ ;s+ rec (ri , oi , w¯ i ) ; si −−−−−−→ s0 i∈I α

m ` s · (¯v 7→ m B c¯ ) −−→ s0 α

m ` A(¯c) −−→ s0

de f

A(¯v : τ¯ ? ) = s (Call)

Table 3: - operational semantics: instances

with data u¯ and r(r, o, w) ¯ denotes launching of o with operation parameters w¯ on request of a web service instance located at r. To define the operational semantics, we exploit a few auxiliary functions. First, we define a function for evaluating expressions: it takes an expression and returns a basic value or an address. We write m B e such a function, but we do not explicitly define it because the exact syntax of expressions is deliberately not specified (recall that - is parameterized wrt the syntax of expressions). Expressions to be evaluated can contain properties; thus, evaluation of e takes place wrt a set of correlation constraints m storing the values of the properties that may occur within e. On the contrary, expressions to be evaluated cannot contain (free) variables because these occurrences are replaced with the corresponding values as soon as the variables are bound. Indeed, execution of a binding construct generates a substitution (ranged over by σ), i.e. a map from basic variables to basic values and from partner links to addresses, that is applied to the whole instance where the binder occurs. A substitution σ will be sometimes written as (¯v 7→ σ(¯v)) for v¯ = dom(σ). Application of substitution σ to s is written s · σ. The effect of s · σ is that, for each x ∈ dom(σ), every free occurrence of x in s is replaced with σ(x). Another ingredient we need to define the semantics is a mechanism for checking if the assignments of ui to wi , for any index i in a given set I, comply with the correlation constraints in m. We will write m B (w¯ i∈I := u¯ i∈I ) such a mechanism. In case the check succeeds, to take care of the 7

effect of the assignments, a pair hm0 , σi is returned where m0 is the set of the correlation constraints for the properties in w¯ i∈I and σ is the substitution for the variables in w¯ i∈I . The function is defined inductively on the syntax of w¯ as follows: m B (v := u) = h∅, (v 7→ u)i   h∅, ∅i    h{p = u}, ∅i m B (p := u) =     undef

if p = u ∈ m if it does not exists u0 s.t. p = u0 ∈ m otherwise (

m B (w, w¯ := u, u¯ ) =

hm0



m00 , σ



σ0 i

if m B (w := u) = hm0 , σi and m ∪ m0 B (w¯ := u¯ ) = hm00 , σ0 i

Finally, the last two auxiliary functions we need are: • P(w) ¯ returns the set of properties contained in w¯ and is defined as follows: P(v) = ∅ P(p) = {p} P(hw1 , . . . , wn i) = P(w1 ) ∪ . . . ∪ P(wn ) • eR(C) returns the set of activities rec (·, ·, ·) that are start activities of C and is defined inductively on the syntax of C as follows: eR( s) = eR(s) eR(ha, o, u¯ i) = ∅ eR(C1 | C2 ) = eR(C1 ) ∪ eR(C2 ) eR(0) = ∅ eR(exit) = ∅ eR(rec (r, o, w)) ¯ = {rec (r, o, w)} ¯ eR(inv (r, o, w)) ¯ =∅ eR(ass (¯v, e¯ )) = ∅ eR(if (e) then {s} else {s}) = ∅ eR(s1 ; s2 ) = eR(s1 ) eR(s1 | s2 ) = eR(s1 ) ∪ eR(s2 ) P eR( i∈I rec (ri , oi , w¯ i ) ; si ) = {rec (ri , oi , w¯ i ) | i ∈ I} de f eR(A(w)) ¯ = eR(s) if A(¯v : τ¯ ? ) = s α

The labelled transition −−→ is the least relation over service instances induced by the rules in Table 3. For the sake of simplicity, we explicitly write only those entities that are necessary for a transition to occur or are modified by it. For example, since correlation constraints are sometimes α necessary but are never modified by a transition, we write the relation as m ` s −−→ s0 instead α of m  s −−→ m  s0 . The most of the rules are obvious, we only remark a few points. Rule (Receive) states that a rec (·, ·, ·) cannot be performed when the address of the sender of a request is unknown and cannot be learned (i.e. the first argument is neither an address nor a link). Rules (Flow) and (FlowRec ) state that, in case no receive conflict occurs2 (i.e. there aren’t two or more 2 Sets of correlation constraints are exploited precisely to deal with receive conflicts: they prevent loss of correlation information (which would be lost if properties are simply replaced by the corresponding values). For example, if properties are dealt with as basic variables, by applying the substitution (p 7→ 5) to the service instance (. . . rec (r, o, hpp q, vi) | rec (r, o, hpp q, v0 i) . . .) we would obtain (. . . rec (r, o, h5, vi) | rec (r, o, h5, v0 i) . . .) that does not permit to establish if the receive activities are in conflict. Indeed, we would obtain the same term by applying the substitution (p 7→ 5, v00 7→ 5) to (. . . rec (r, o, hpp q, vi) | rec (r, o, hv00 , v0 i) . . .), where no conflict occurs.

8

w:= ¯ u¯

m ` s −−−−−→ s0

m B (w¯ := u¯ ) = hm0 , σi

{a :: m  s | C} − → {a :: (m ∪ m0 )  s0 · σ | C} i(a2 ,o,¯u)

m ` s −−−−−−−→ s0

(Assign)

a0 < u¯

{a1 :: m  s | C1 , a2 :: C2 } − → {a1 :: m  s0 | C1 , a2 :: ha1 , o, u¯ i | C2 } r(a0 ,o,w) ¯

m ` s −−−−−−−→ s0

m B (w¯ := u¯ ) = hm0 , σi

m,∅

{a :: m  s | ha0 , o, u¯ i | C} − → {a :: (m ∪ m0 )  s0 · σ | C} r(l,o,w) ¯

m ` s −−−−−−→ s0

m B (l, w¯ := a0 , u¯ ) = hm0 , σi 0

0

(Invoke)

(ReceiveaI )

m,∅ 0

(ReceivelI )

{a :: m  s | ha , o, u¯ i | C} − → {a :: (m ∪ m )  s · σ | C}  ∅ B (w¯ := u¯ ) = hm, σi rec a0 , o, w¯ < eR(C)

r(a0 ,o,w) ¯

∅ ` s −−−−−−−→ s0

{a :: ∗s | ha0 , o, u¯ i | C} − → {a :: ∗s | m  s0 · σ | C} r(l,o,w) ¯

∅ ` s −−−−−−→ s0

∅ B (l, w¯ := a0 , u¯ ) = hm, σi rec (l, o, w) ¯ < eR(C) 0

0

(ReceiveaS )

(ReceivelS )

{a :: ∗s | ha , o, u¯ i | C} − → {a :: ∗s | m  s · σ | C} N1 − → N10

\

m ` s −→ s0

(Terminate)

N1 ∪ N2 − → N10 ∪ N2

{a :: m  s | C} − → {a :: C} N ≡ N1

N1 − → N2 N − → N0

N2 ≡ N 0

(Part)

(Cong)

Table 4: - operational semantics: nets

receive activities simultaneously enabled for the same combination of partner link, operation and correlation set), executions of the two argument services are interleaved. Rule (Pick) states that, in case no receive conflict occurs, the pick activity can execute any of its receive activities and then proceed accordingly. The reduction relation − → is the least relation over nets induced by the rules in Table 4. Types of nodes are omitted because they play no role in the operational semantics of -. Let us now comment on the rules. Rule (Assign) states that the effect of an assignment is global wrt the instance and consists of replacing the free occurrences of the variables bound by the assignment with the corresponding values and of extending the set of correlation constraints identifying the instance with the pairs resulting from the assignment. Rule (Invoke) states that service invocation corresponds to adding a service request to the dataspace of the invoked service provided that no address implicitly received is exported as operation parameter. The request is a tuple, containing the address a1 of the invoker, the name of the invoked operation o and the message u¯ (i.e. the arguments to be passed to o). Hence, the invocation of a remote service is asynchronous because the invoker can proceed before its request is processed. WS-BPEL also provides a synchronous invocation

9

Op L bt τ t

::= ::= ::= ::= ::=

∅ | {o : τ¯ } | Op ∪ Op ∅ | {b : bt} | {p : bt} | L ∪ L I | S | B bt | Op τ¯ |  | 

(operation type sets) (local declarations) (basic types) (message types) (generic types)

Table 5: Type syntax

that forces the invoker to wait for an answer by the invoked service, which indeed performs a pair of activities receive – reply. In -, this behaviour is rendered as execution of a pair of activities invoke – receive by the invoker and of a pair of activities receive – invoke by the invoked service. Rule (ReceiveaI ) states that activity receive cannot progress until a matching request has been received. Thus, differently from activity invoke, it is blocking. Requests are routed to the correct service instance by exploiting the partner link and the operation contained in the request, which must coincide with those in the label of the transition performed by the service instance, and the correlation constraints identifying the instance, which must enable the assignment of the values contained in the request to the parameters contained in the receive. The correlation set identifying the instance must not be empty otherwise it could not be possible to determine the correct instance to which the request must be delivered. When the reduction takes place, the matching request is consumed and the effect on the instance is the same as that of the corresponding assignment. Rule (ReceivelI ) differs only because in this case the address of the invoker is not known in advance. After the reduction, the address contained in the request is marked as not further transmissible and is used to replace the partner link occurring in the receive. The last two rules for the activity receive, (ReceiveaS ) and (ReceivelS ), permit to create a new service instance on receipt of a request that cannot be routed to an existing instance. The additional premise prevents interferences with the first two rules for receive in case of multiple start activities, as illustrated by the example  {a :: ∗(rec (l, o, hpi) | rec l0 , o0 , hpi ) | {p = 10}  rec (l, o, hpi) | ha0 , o, h10ii} where only the service instance can evolve. Rule (Terminate) states that the whole service instance performing a transition labelled \ immediately terminates. Rule (Part) states that if a part of a larger net evolves, the whole net evolves accordingly. Rule (Cong) is standard and states that structural congruent nets have the same reductions.

3 Types The syntax of types is defined in Table 5. An operation type set Op is a collection of type definitions of operations o : τ¯ , where τ¯ is a tuple of message types that characterizes the format of the arguments that an operation requires. We assume that the type definition of a given operation only occurs at a single node within a net. Local declarations L consist of type definitions of basic variables and properties, which have basic types bt (for simplicity sake, we only consider I, S and B). Types  and  are those of (well-typed) nets and services, respectively. In the sequel, we will use the symbol ? to type partner links that are implicitly initialized (i.e. they are bound as first argument of a rec (, , )). Notation τ? , which is used to type the parameters of service definitions (see the previous section), stands for a message type τ or for ?. Typing a parameter with ? means that it is a partner link that should have been bound implicitly by a receive

10

∀i ∈ I

Γ, {a j : Op j | j ∈ I} ` ai ::Opi ,Li Ci :  Γ ` {ai ::Opi ,Li Ci | i ∈ I} : 

Γ `aL C :  Γ ` a ::Op,L C : 

Γ0 ` N : 

(netToServ)

(net)

Γ 6 Γ0

Γ ` N : 

(netWeak)

Table 6: Inference rules for Γ ` N : 

activity that syntactically precedes the service call. Moreover, notation s shall denote both service specifications (∗s) and service instances (m  s).

3.1 Type inference Type environments, ranged over by Γ, map addresses and partner links to sets of operation types Op or to ?, and service identifiers to . If x < dom(Γ), we write Γ, x : t for the type environment obtained by extending Γ with the binding of x to t (the notation generalizes to Γ, {xi : ti }i∈I with the obvious meaning). We write ∅ to denote the type environment with empty domain. Type environments are ordered by the standard preorder over functions, thus we write Γ 6 Γ0 when dom(Γ) ⊇ dom(Γ0 ) and Γ(x) = Γ0 (x) for each x ∈ dom(Γ0 ). Type environments hold the types of nodes and of partner links. This information is exploited to properly deal with address passing (indeed, invoke and receive activities can use partner links as parameters to exchange node addresses). The type of a partner link is a set of operation types Op stating that the partner link can be bound only to addresses holding a type Op0 such that Op ⊆ Op0 . During the type checking wrt Γ, we can easily determine if a partner link l has been implicitly or explicitly initialized according to the fact that Γ(l) is ? or Op, respectively. When a partner link is implicitly initialized, the type system checks that the associated address is never transmitted (the example in Section 4.1 shows that this limitation does not affect the expressive power of the calculus), as required by WSDL / WS-BPEL. When a partner link is explicitly initialized, the type system checks that the link is not reassigned (in fact, this control is done implicitly because if l ∈ dom(Γ) then Γ, l : Op is undefined). Type environments also hold service identifiers: this information is exploited when typing recursive service definitions. The judgment Γ ` N : , defined by the inference rules of Table 6, says that a net N is well-typed under the type environment Γ. The initial type environment used to typecheck a net does not contain type associations for partner links; this kind of associations may be added to the environment during the type checking of services, by means of the function envExt·,· (·). Rule (net) says that a net is well-typed under a type environment, if each node is well-typed under the environment extended with type information extracted from all nodes. Rule (netToServ) says that a node is well-typed if its components are well-typed. Rule (netWeak) says that a type environment can be replaced with a stronger one (i.e. one making more assumptions). The judgment Γ `aL S : t, defined by the set of inference rules shown in Tables 7 and 8, says that S has type t, where S is a metavariable denoting values, variables, properties, requests and services, wrt a type environment Γ and a pair a–L made of the address of a node and a set of local declarations. The symbol v denotes the subtyping preorder over τ induced by letting Op v Op0 if Op ⊆ Op0 . The preorder extends to tuples of message types by letting hτ1 , . . . , τn i v hτ01 , . . . , τ0n i if τi v τ0i for i = 1..n. To distinguish partner links within a tuple of variables and properties, we

11

exploit the auxiliary function pl(·) that, given a tuple w¯ i∈I , returns the set of indexes of the partner links therein. The function is defined inductively on the syntax of w¯ i∈I as follows: [ pl(bi ) = ∅ pl(pi ) = ∅ pl(li ) = {i} pl(w¯ i∈I ) = pl(wi ) i∈I

We comment on the most significant rules in Table 8, since the rules in Table 7 are standard. Rule (inv) is applied when an invoke activity is performed by a client in a one-way interaction or to start a request-response interaction. In these cases, indeed, the address of the provider (holding the type definition of the operation) is given by r. Of course, the parameters of the invoked operation must conform to the corresponding operation type. In particular, when an invoke transmits an address, e.g. w¯ = w¯ i∈I , wk = r0 and τk = Op00 , then it must be that Op00 ⊆ Op0 where Op0 is the operation type set associated to r0 in Γ (i.e. Γ `aL r0 : Op0 ). This is indeed what the condition τ¯ v τ¯ 0 checks. Rule (inv cb) is applied to an invoke activity performed as a callback in a request-response interaction. The local node is the operation provider. The only difference with the previous rule is that, in case the first argument of the activity is a partner link l, it is additionally checked that a triggering receive activity which initializes l logically precedes the invoke (this is expressed by the premise Γ `aL l : ?). Rule (rec cb) is applied when a client performs a receive activity to obtain a callback in a request-response interaction. Similarly to rule (inv), the type of the operation must be retrieved from the provider node whose address is given by r. In case the first argument of the operation is a free occurrence of a link it is checked that the link is not transmitted. Rule (rec) is similar but is applied when the local node is the provider of the receive activity. Rule (seq) says that a sequence of services s1 ; s2 is well-typed under Γ if s1 is well-typed under Γ and s2 is well-typed under Γ extended with the type associations for the partner links bound by s1 (notably, the extension is possible only if such partner links are not reassigned). The set of new associations is returned by the auxiliary function envExt·,· (·), that can be defined inductively on the syntax of services. The most significant cases, i.e. those for the binding constructs, are defined as follows: envExt ¯ =  Γ,a (rec (r, o, w))  {l : τi | ∃ i . wi = l ∧ τi ∩ Op = ∅} ∪ {l0 : ? | r = l0 }          {l : τi | ∃ i . wi = l ∧ Γ `∅a r : Op0 ∧ o : τ¯ ∈ Op0 ∧     Γ `∅a a : Op ∧ τi ∩ Op = ∅}

if Γ `∅a a : Op ∧ o : τ¯ ∈ Op otherwise

envExtΓ,a (ass (w, ¯ e¯ )) = {l : τi | ∃ i . wi = l ∧ Γ `∅a e¯ : τ¯ ∧ Γ `∅a a : Op ∧ τi ∩ Op = ∅}

Condition τi ∩ Op = ∅ avoids that the service executing the activity can receive its same address as an argument. The remaining cases that define envExt·,· (·) are the following: • envExtΓ,a (0) = ∅ • envExtΓ,a (exit) = ∅ • envExtΓ,a (inv (r, o, w)) ¯ =∅ • Given G1 = envExtΓ,a (s1 ) and G2 = envExtΓ,a (s2 ), we have:   G if G1 = G2 = G    envExtΓ,a (if (e) then {s1 } else {s2 }) =     undef otherwise 12

u ∈ Int ∅

`aL

u : I

u ∈ Str

(int)



l : Op

pl q : Op

Γ0 `aL S : t

Γ `aL S : t

∅ `aL b : τ

(ref2 )

Γ 6 Γ0

u : S

b:τ∈L

r : Op `aL r : Op (ref)

`aL

`aL

u ∈ {true, false}

(str)

∅ `aL u : B p:τ∈L

(var)

Γ `aL w1 : τ1

∅ `aL p : τ ...

Γ `aL wn : τn

Γ `aL hw1 , . . . , wn i : hτ1 , . . . , τn i Γ `aL e1 : τ1

(weak)

...

Γ `aL en : τn

Γ `aL he1 , . . . , en i : hτ1 , . . . , τn i

(bool)

(prop)

(w) ¯

(¯e)

Table 7: Inference rules for Γ `aL S : t

• envExtΓ,a (s1 ; s2 ) = envExt(Γ, envExtΓ,a (s1 )),a (s2 ) • envExtΓ,a (s1 | s2 ) = envExtΓ,a (s1 ) ∪ envExtΓ,a (s2 ) • Given Gi = envExtΓ,a (rec (ri , oi , w¯ i ) ; si ) for i ∈ I, we have:   G  X   envExtΓ,a ( rec (ri , oi , w¯ i ) ; si ) =     undef i∈I

if ∀ i ∈ I it holds that Gi = G otherwise

• envExtΓ,a (A(w)) ¯ = A :  Finally, rule (flow) forces the two component services to type check in the same environment. This control prevents implicit flow of addresses from one component to the other (recall that partner link declarations are global to the instance) which would force a strict execution ordering of the components (thus, e.g., the service instance rec (l, o, w) | inv (l, o0 , 5) does not type check).

3.2 Type soundness The major property of our type system is that if a net typechecks then it does never generate runtime errors (Corollary 3.5). The proof proceeds in the style of [WF94] by first proving subject reduction, namely that nets well-typedness is an invariant of the reduction relation (Theorem 3.3), and then proving type safety, namely that well-typed nets do not immediately generate errors (Theorem 3.4). First, we introduce some auxiliary definitions. A (generic) context Cg is a service with one subterm replaced by a hole, denoted [·]. Formally, Cg is defined by the following grammar: Cg

::= |

P [·] | Cg | s | Cg ; s | s; Cg | rec (r, o, w) ¯ ; Cg + i∈I rec (ri , oi , w¯ i ) ; si if (e) then {s} else {Cg } | if (e) then {Cg } else {s} | A(¯c)

13

Γ `aL C1 : 

Γ `aL C2 : 

Γ `aL C1 | C2 :  Γ `aL a : Op

Γ `aL a0 : Op0

Γ `aL s : 

(par)

Γ `aL s : 

o : τ¯ ∈ Op ∪ Op0

Γ `aL u¯ : τ¯ 0

(serv) τ¯ v τ¯ 0

Γ `aL ha0 , o, u¯ i :  ∅ `aL 0 :  (nil) Γ `aL e¯ i∈I : τ¯ i∈I

∅ `aL exit :  (exit)

Γ `aL w¯ i∈(I\J) : τ¯ i∈(I\J)

Γ `aL ass (w¯ i∈I , e¯ i∈I ) :  Γ `aL r : Op

o : τ¯ ∈ Op

A :  `aL A :  (def2 )

J = pl(w¯ i∈I )

Γ `aL w¯ : τ¯ 0

(ass)

τ¯ v τ¯ 0

(inv)

Γ `aL inv (r, o, w) ¯ :  Γ `aL a : Op

o : τ¯ ∈ Op

Γ `aL w¯ : τ¯ 0

τ¯ v τ¯ 0

r = l ⇒ Γ `aL l : ?

Γ `aL inv (r, o, w) ¯ :  Γ `aL r : Op o : τ¯ i∈I ∈ Op Γ `aL w¯ j∈(I\J) : τ¯ j∈(I\J) r,l r = pl q ⇒ ∀ i ∈ J wi , l Γ `aL rec (r, o, w¯ i∈I ) :  Γ `aL a : Op o : τ¯ i∈I ∈ Op Γ `aL w¯ j∈(I\J) : τ¯ j∈(I\J) r = pl q ⇒ ∀ i ∈ J wi , l ∧ Γ `aL l : ? Γ `aL rec (r, o, w¯ i∈I ) :  Γ `aL e : B

Γ `aL s1 : 

Γ `aL s2 : 

Γ, envExtΓ,a (s1 ) `aL s2 :  Γ `aL s1 ; s2 : 

Γ `aL s1 :  Γ `aL s2 :  Γ `aL s1 | s2 :  Γ `aL A :  Γ

J = pl(w¯ i∈I ) (rec cb)

J = pl(w¯ i∈I ) (rec)

(seq)

Γ `L rec (ri , oi , w¯ i ) ; si :  Xa (pick) Γ `aL rec (ri , oi , w¯ i ) ; si : 

∀i ∈ I (flow)

i∈I

Γ `aL w¯ : τ¯ ?1 `aL

(inv cb)

(if)

Γ `aL if (e) then {s1 } else {s2 } :  Γ `aL s1 : 

(req)

τ¯ ? v τ¯ ?1

A(w) ¯ :  L ∪ {¯vi∈(I\J) : τ¯ ? } i∈(I\J)

Γ, A : , v¯ j∈J : τ¯ ?j∈J `a

de f

A(¯v : τ¯ ? ) = s (call)

s : 

Γ `aL A : 

de f

A(¯vi∈I : τ¯ ?i∈I ) = s , J = pl(¯vi∈I )

Table 8: Inference rules for Γ `aL S : t (cont.)

14

(def1 )

de f

where the body of the service definition is a context, i.e. A(¯v : τ¯ ? ) = Cg . Notably, terms of the P form [·] ; s + i∈I rec (ri , oi , w¯ i ) ; si are not considered (for the moment). Notation Cg [s] denotes the service resulting from filling the hole of Cg with service s. An execution context C is a context such that, once the hole is filled with a service s, the resulting service C[s] is capable of immediately performing an activity of s. Formally, C is defined by the following grammar: C ::= [·] | C | s | C; s | if (e) then {C} else {s} | if (e) then {s} else {C} | A(¯c) de f

where A(¯v : τ¯ ? ) = C. Whenever, we only consider basic receive activities, we can extend the set of possible execution contexts as follows: P Cr ::= C | [·] ; s + i∈I rec (ri , oi , w¯ i ) ; si The subject reduction theorem exploits the following two auxiliary lemmas. The former is the key for showing type preservation for reductions involving substitutions, the latter states that if a service is well-typed then its continuation after a transition is well-typed too. Lemma 3.1 Suppose Γ `aL s : . If Γ `aL v : τ, Γ `aL u : τ0 and τ v τ0 , then Γ `aL s · (v 7→ u) : . Proof: The proof in case of a substitution for a basic variable is easy, then we consider only the most relevant case of a substitution for a partner link. Thus, we have (v 7→ u) = (l 7→ a0 ), τ = Op and τ0 = Op0 . We proceed by induction on the length of the proof of Γ `aL s : , and case analysis on the last step. The following cases • s=0 • s = exit • s = inv (r, o, w¯ i∈I ) with l < {r} ∪ {w j | j ∈ pl(w¯ i∈I )} • s = rec (r, o, w¯ i∈I ) with r , pl q • s = ass (w¯ i∈I , e¯ i∈I ) with l < {e j | j ∈ pl(¯ei∈I )} are trivial. Indeed, since s does not contain a free occurrence of l, we have s · (l 7→ a0 ) = s, so we can conclude Γ `aL s · (l 7→ a0 ) : . The other base cases are the following: • s = inv (l, o, w¯ i∈I ) with l < {w j | j ∈ pl(w¯ i∈I )} If Γ `aL s :  is inferred by rule (inv), we have o : τ¯ 00 ∈ Op. Since Op ⊆ Op0 , we have o : τ¯ 00 ∈ Op0 , then, by (inv), Γ `aL inv (a0 , o, w¯ i∈I ) : . Otherwise, Γ `aL s :  is inferred by rule (inv cb), hence o : τ¯ 00 ∈ Op00 , where Γ `aL a : Op00 . Then, by (inv cb), Γ `aL inv (a0 , o, w¯ i∈I ) : . • s = inv (r, o, h. . . l . . .i) with l , r By both (inv) and (inv cb), we have that the operation o has type τ¯ 00 = h. . . Op00 . . .i such that Op00 ⊆ Op. Since Op ⊆ Op0 , we have Op00 ⊆ Op0 and, by (inv) or (inv cb), Γ `aL inv (r, o, h. . . a0 . . .i) : . 15

• s = inv (l, o, h. . . l . . .i) We obtain the thesis combining the proofs of the two previous cases. • s = rec (pl q, o, w) ¯ L If Γ `a s :  is inferred by rule (rec), we can directly infer Γ `aL rec (a0 , o, w) ¯ : . Otherwise, Γ `aL s :  is inferred by (rec cb), then we have o : τ¯ 00 ∈ Op. Since Op ⊆ Op0 , we have o : τ¯ 00 ∈ Op0 . Thus, we can infer Γ `aL rec (a0 , o, w) ¯ : . • s = ass (w, ¯ h. . . l . . .i) By rule (ass), we can directly infer Γ `aL ass (w, ¯ h. . . a0 . . .i) : . Finally, the remaining cases follow by induction. For instance, if s = s1 | s2 , from Γ `aL s1 | s2 :  by the first premise of (flow) we have Γ `aL s1 :  and by inductive hypothesis we have Γ `aL s1 · (l 7→ a0 ) : . By the second premise of (flow), we have Γ `aL s2 :  and by inductive hypothesis we have Γ `aL s2 ·(l 7→ a0 ) : . Then, by (flow), Γ `aL s1 ·(l 7→ a0 ) | s2 ·(l 7→ a0 ) : , i.e. Γ `aL (s1 | s2 ) · (l 7→ a0 ) : .  α

Lemma 3.2 If Γ `aL s :  and m ` s −−→ s0 then Γ0 `aL s0 :  with Γ0 such that3 : • Γ0 6 Γ in case of α = \, i(a0 , o, u¯ ); • Γ0 6 Γ, envExtΓ,a (rec (r, o, w)) ¯ in case of α = r(r, o, w); ¯ • Γ0 6 Γ, envExtΓ,a (ass (w, ¯ e¯ )) in case of α = (w¯ := u¯ ) and s ≡ C[ass (w, ¯ e¯ )]. α

Proof: The proof is by induction on the depth of the shortest inference of −−→. The base cases (of depth 1) are trivial; when the applied rules are (Exit), (Assign), (Invoke) and (Receive), we have s0 = 0; thus, we can easily conclude Γ0 `aL 0 :  by rules (nil) and (weak). For the inductive step, we reason by case analysis on the last rule applied in the inference: α

• (Sequence): In this case s ≡ s1 ; s2 , m ` s1 −−→ s01 and s0 ≡ s01 ; s2 . Since s is well-typed, by rule (seq) we have Γ `aL s1 :  and Γ00 `aL s2 :  for Γ00 = Γ, envExtΓ,a (s1 ). By inductive hypothesis, we have Γ0 `aL s01 :  for some Γ0 6 Γ. In particular, we can choose Γ0 such that Γ00 = Γ0 , envExtΓ,a (s01 ). Then, by rule (seq), we have the thesis. α

• (Ifff ) and (Iftt ): In case of m B e = true we have s ≡ if (e) then {s1 } else {s2 }, m ` s1 −−→ s0 . Since s is well-typed, by rule (flow) we have Γ `aL s1 : . So, by inductive hypothesis, we have straightaway the thesis. In case of m B e = false, we proceed in similar way. P α • (Pick): In this case s ≡ rec (r, o, w) ¯ ; s00 + i∈I rec (ri , oi , w¯ i ) ; si , m ` rec (r, o, w) ¯ ; s00 −−→ s0 . ¯ ; s00 : . So, by inductive Since s is well-typed, by rule (pick) we have Γ `aL rec (r, o, w) hypothesis, we straightaway have the thesis. α

• (Flow) and (FlowRec ): In this case s ≡ s1 | s2 , m ` s1 −−→ s01 and s0 ≡ s01 | s2 . Since s is well-typed, by rule (flow) we have Γ `aL s1 : . By inductive hypothesis, we have Γ0 `aL s01 :  for some Γ0 6 Γ. By rules (flow) and (weak), Γ0 `aL s2 :  holds and then, by (flow), we have the thesis. 3

Notably, wrt the type environment on the right of 6 , Γ0 can additionally contain further associations due to service calls. This explains the use of 6 instead of =.

16

de f

α

• (Call): In this case s ≡ A(¯c) with A(¯vi∈I : τ¯ ?i∈I ) = s00 and m ` s00 · (¯v 7→ m B c¯ ) −−→ s0 . Since 0 s is well-typed, by rules (call) and (def1 ) we have Γ00 `aL s00 :  holds for Γ00 = (Γ, A : , v¯ j∈J : τ¯ ?j∈J ) and L0 = L ∪ {¯vi∈(I\J) : τ¯ ?i∈(I\J) } with J = pl(¯vi∈I ). By Lemma 3.1 and by the fact that if we substitute in a well-typed service a partner link having type ? with any address then the service is still well-typed (because the partner link is used only to perform 0 a callback), Γ00 `aL s00 · (¯v 7→ m B c¯ ) :  holds and, since the occurences of v¯ in s00 are replaced by m B c¯ , we have that Γ00 `aL s00 · (¯v 7→ m B c¯ ) :  holds. Thus, by inductive hypothesis, we directly have the thesis.  Theorem 3.3 (Subject Reduction) If Γ ` N :  and N − → N 0 then Γ0 ` N 0 :  for some Γ0 . Proof: Given N ≡ {ai ::Opi ,Li Ci | i ∈ I}, by the rule (net) it does exists an environment Γ00 = Γ, {a j : Op j | j ∈ I} such that for all i ∈ I we have Γ00 ` ai ::Opi ,Li Ci : . By rule (netToServ), (par) and (serv), we have that ∀ s ∈ Ci the judgment Γ00 `aLii s :  holds, i.e. the service of each instance located in some node of the net is well-typed under the environment Γ00 and under its address and local declarations. Moreover, ∀ ha, o, u¯ i ∈ Ci the judgment Γ00 `aLii ha, o, u¯ i :  holds, i.e. all service requests located in the net nodes are well-typed. Looking at the definitions in Table 4 we proceed by rule induction. We consider the following base cases: • (Invoke) and (Terminate): In these cases we see that for each net reduction N − → N 0 there is, α 0 at service level, a corresponding transition m ` s −−→ s , for some component s in a node of N. In case of (Invoke), after the transition there will be a new service request in the data space of some node of N 0 . This tuple is well-typed, because rule (req) has the same requirements of rules for invoke activities. Thus, since s is well-typed, by Lemma 3.2 and applying in reverse order the rules (netToServ), (par), (serv) and (net), we obtain the thesis. w:= ¯ u¯

• (Assign): We have N ≡ {a ::Op,L m  s | C}, Γ00 `aL s : , m ` s −−−−−→ s0 , N 0 ≡ {a ::Op,Loc (m ∪ m0 )  s0 · σ | C} with m B (w¯ := u¯ ) = hm0 , σi. By Lemma 3.2, we have Γ0 `aL s0 :  for Γ0 6 Γ00 such that for each association (l 7→ a0 ) in σ there is a corresponding (l : Op) in Γ0 with Op ⊆ Op0 , with Γ00 `aL a0 : Op0 . Moreover, for each association (b 7→ u) in σ, the types of b and u match, because (ass) checks that basic variables and values within an assign activity have the same type. Then, we can apply Lemma 3.1 and obtain Γ0 `aL s0 ·σ : . Now, applying in reverse order the rules (netToServ), (par), (serv) and (net), we have the thesis. • (ReceiveaI ), (ReceivelI ), (ReceiveaS ) and (ReceivelS ): we proceed similarly to the previous case. The cases for (Part) and (Cong) follow by induction.  The errors that our type system can capture, are characterized by predicate →err that holds true when a net can immediately generate a runtime error. Rules defining →err are shown in Table 9. Here, we linger on the most significant rules. Rule (opDefError1) raises an error when an operation is invoked whose type declaration is neither in the type of the caller nor in that of the callee. Rule (opDefError2) raises an error if the type declaration of the requested operation is not found in the type of the local node. Indeed, the service must be the provider since the activity first argument is 17

 s ≡ C[inv a0 , o, w¯ ] o : τ¯ < Op o : τ¯ < Op0 0

0

{a ::Op,L s | C, a0 ::Op ,L C 0 } →err

(opDefError1)

s ≡ Cr [rec (l, o, w)] ¯ o : τ¯ < Op

(opDefError2) {a ::Op,L s | C} →err  s ≡ Cr [rec a0 , o, w¯ ] o : τ¯ < Op o : τ¯ < Op0 (opDefError3) 0 0 {a ::Op,L s | C, a0 ::Op ,L C 0 } →err  s ≡ Cr [rec (l, o, w) ¯ ; Cg [inv l0 , o0 , w¯ 0 ]] ∃ i . w0i = l (linkError) {a ::Op,L s | C} →err s ≡ C[inv (l, o, w)] ¯ o : τ¯ ∈ Op {a ::Op,L s | C} →err  s ≡ C[ass (w, ¯ u¯ ) ; Cg [inv l, o, w¯ 0 ]] o : τ¯ ∈ Op

(rrError1) ∃ i . wi = l

{a ::Op,L s | C} →err

(rrError2)

s ≡ C[inv (a0 , o, w)] ¯ w¯ = hw1 , . . . , wn i w1 : τ1 ∈ L . . . wn : τn ∈ L [(o : τ¯ ∈ Op ∧ τ¯ 6v hτ1 , . . . , τn i) ∨ (o : τ¯ 0 ∈ Op0 ∧ τ¯ 0 6v hτ1 , . . . , τn i)] Op,L

{a ::

0

s | C, a ::

Op0 ,L0

0

C } →

s ≡ Cr [rec (l, o, w)] ¯ o : τ¯ ∈ Op w¯ = hw1 , . . . , wn i w1 : τ1 ∈ L . . . wn : τn ∈ L τ¯ 6v hτ1 , . . . , τn i Op,L

{a ::

(varError1)

err

(varError2)

err

s | C} →

s ≡ Cr [rec (a0 , o, w)] ¯ w¯ = hw1 , . . . , wn i w1 : τ1 ∈ L . . . wn : τn ∈ L [(o : τ¯ ∈ Op ∧ τ¯ 6v hτ1 , . . . , τn i) ∨ (o : τ¯ 0 ∈ Op0 ∧ τ¯ 0 v 6 hτ1 , . . . , τn i)] Op,L

{a ::

0

s | C, a ::

Op0 ,L0

0

C } →

s ≡ C[ass (w, ¯ u¯ )] ∃ i . wi : bt {a :: N1 →err N1 ∪ N2 →err

Op,L

(varError3)

err

ui < typeS et(bt) err

s | C} →

N ≡ N0

(partError)

(assError)

N →err

N 0 →err

(congError)

Table 9: Runtime errors

a link. If the first argument of the activity is an address, there is no way to tell if the service is a client or a provider. Therefore, rule (opDefError3) raises an error only if the type declaration of the requested operation is neither in the type of the callee nor in that of the caller. Rule (linkError) raises an error when a partner link implicitly initialized is going to be passed in a communication. Rule (rrError1) raises an error if a callback invoke is going to be executed that does not have a previous triggering receive (indeed, its first argument is uninitialized). Rule (rrError2) raises an error if the

18

first argument of a callback invoke is initialized by an assignment rather than by a triggering receive. Finally, rule (assError) raises an error if the type of an evaluated expression is not conform to the type of corresponding basic variable. We use the auxiliary function typeS et(·) that, given a basic type, returns the corresponding value set and is defined as follows: • typeS et(I) = Int • typeS et(B) = {true, false} • typeS et(S) = Str Some obvious facts about deductions that we use in the proof of the following theorem are: • if Γ `aL Cg [s] :  then there exists Γ0 such that Γ0 6 Γ and Γ0 `aL s : ; • if there is no Γ0 such that Γ0 `aL s : , then there are no Γ such that Γ0 6 Γ and Γ `aL Cg [s] : . These follow from the facts that there is exactly one inference rule for each service form, and each inference rule requires a proof for each subterm of the service in its conclusion. Replacing Cg by C or Cr the facts still hold. We can now prove the type safety theorem. Theorem 3.4 (Type Safety) Γ ` N :  implies that N →err holds false. Proof: We prove, by rule induction, that if N →err then there is no Γ for which Γ ` N :  can be derived. Looking at the definition in Table 9, we see that N can have one of the following forms: 0

0

N1 ≡ {a ::Op,L s | C, a0 ::Op ,L C 0 } N2 ≡ {a ::Op,L s | C} Moreover, we have that the following base cases have to be considered. • (opDefError1): N has the form N1 with s ≡ C[inv (a0 , o, w)] ¯ and o undefined in Op and Op0 . Suppose that for some environment Γ we can derive Γ ` N : . By rule (net) it does exists an environment Γ0 such that Γ0 = (Γ, a0 : Op0 ) and Γ0 ` (a ::Op,L s | C) : . By rule (netToServ), (par) and (serv) we have Γ0 `aL s : . ¯ :  must hold for some Γ00 6 Γ0 . This Since C is an execution context, Γ00 `aL inv (a0 , o, w) can be inferred only by rules (inv cb) and (inv). But, rule (inv cb) cannot be applied, because Γ00 `aL a : Op, such that o : τ¯ ∈ Op, is not satisfied. Similarly, rule (inv) cannot be applied, because Γ00 `aL a0 : Op0 , such that o : τ¯ ∈ Op0 , is not satisfied. • (opDefError2): N has the form N2 with s ≡ Cr [rec (l, o, w)] ¯ and o undefined in Op. Suppose that for some environment Γ we can derive Γ ` N : . By rule (net), we have Γ ` (a ::Op,L s | C) :  and, by rule (netToServ), (par) and (serv) we have Γ `aL s : . ¯ :  must hold for some Γ0 6 Γ. This Since Cr is an execution context, Γ0 `aL rec (l, o, w) can be inferred only by rules (rec) and (rec cb). But the rule (rec) cannot be applied, because Γ0 `aL a : Op, such that o : τ¯ ∈ Op, is not satisfied. Moreover, the fact that the first argument of the receive is a partner link means that l is unitialized, i.e. no association for l can be in Γ0 . Then, the rule (rec cb) cannot be applied because Γ0 `aL l : Op is not satisfied. 19

• (opDefError3): N has the form N1 with s0 ≡ Cr [rec (a0 , o, w)] ¯ and o undefined in Op and 0 0 L 0 Op . Similarly to the previous case, Γ `a rec (a , o, w) ¯ :  must hold and this can be inferred only by rules (rec) and (rec cb). Similarly to (opDefError1), we can prove that these rules cannot be applied. • (linkError): N has the form N2 with s ≡ Cr [rec (l, o, w) ¯ ; Cg [inv (l0 , o0 , w¯ 0 )]] and ∃ i . w0i = l. Suppose for some Γ we can infer Γ ` N : . Thus, Γ0 `aL rec (l, o, w) ¯ :  must hold for 0 00 L 0 0 some Γ 6 Γ. Then, by rule (seq), Γ `a Cg [inv (l , o, w¯ )] :  must hold, for some Γ00 such that Γ00 6 Γ0 . By envExt·,· (·) definition, we have that Γ00 `aL l : ? holds. Since ? is not a message type, rules (inv) and (inv cb) cannot be applied because the premise Γ00 `aL w¯ 0 : τ¯ 0 is not satisfied. • (rrError1): N has the form N2 with s ≡ C[inv (l, o, w)] ¯ and o : τ¯ ∈ Op. Similarly to (opDefError2), Γ0 `aL inv (l, o, w) ¯ :  must hold and, since o is defined in Op, this can be inferred only by rule (inv cb). Since the first argument of the invoke is a partner link, a previous triggering receive doesn’t be performed, then Γ0 `aL l : ? is not satisfied. • (rrError2): N has the form N2 with s ≡ C[ass (w, ¯ u¯ ) ; Cg [inv (l, o, w¯ 0 )]], o : τ¯ ∈ Op and ∃ i . wi = l. Suppose for some Γ we can infer Γ `aL ass (w, ¯ u¯ ) : . Then, by rule (seq), Γ0 `aL Cg [inv (l, o, w¯ 0 )] :  must hold, for some Γ0 and Op0 such that Γ0 6 (Γ, l : Op0 ). Similarly to the previous case, (inv cb) cannot be used to infer the type of the invoke activity, because, Γ0 `aL l : ? is not satisfied. • (varError1): N has the form N1 with s ≡ C[inv (a0 , o, w)], ¯ w¯ = hw1 , . . . , wn i, w1 : τ1 ∈ Op,. . . , wn : τn ∈ Op. Similarly to (opDefError1), Γ00 `aL inv (a0 , o, w) ¯ :  must hold for some environment Γ00 . The predicate →err holds if one of these cases holds: – (o : τ¯ ∈ Op ∧ τ¯ 6v hτ1 , . . . , τn i) Here we have to apply the rule (inv cb). But it isn’t possible, because Γ00 `aL w) ¯ : hτ1 , . . . , τn i and τ¯ v hτ1 , . . . , τn i cannot hold both. – (o : τ¯ 0 ∈ Op0 ∧ τ¯ 0 6v hτ1 , . . . , τn i) Here we have to apply the rule (inv). But it isn’t possible, for the same reason of the previous case. • (varError2): N has the form N2 with s0 ≡ Cr [rec (l, o, w)], ¯ o : τ¯ ∈ Op, w¯ = hw1 , . . . , wn i, w1 : τ1 ∈ Op,. . . , wn : τn ∈ Op. Similarly to (opDefError2), Γ0 `aL rec (l, o, w) ¯ :  must hold. Since o is defined in Op, this judgement can be inferred only by rule (rec). But the rule cannot be applied, because the premise Γ `aL w¯ j∈({1..n}\J) : τ¯ j∈({1..n}\J) , with J = pl(w¯ i∈{1..n} ), is not satisfied. • (varError3): this case is similar to (varError1), with the difference that here the concerned activity is a receive and the corresponding rules for its type inference are (rec) and (rec cb). • (assError): N has the form N2 with s0 ≡ C[ass (w, ¯ u¯ )] and ∃ i ∈ {1..n} . wi : bt such that ¯ u¯ ) :  must hold. The only ui < typeS et(bt). Similarly to the previous cases, Γ0 `aL ass (w, rule that can be applied is (ass). But it is not possible, because the premise Γ `aL w¯ j∈({1..n}\J) : τ¯ j∈({1..n}\J) , where τ¯ i∈{1..n} is the type of u¯ and J = pl(w¯ i∈{1..n} ), is not satisfied. The cases of (partError) and (congError) follow by induction. Suppose, for example, that N1 ∪ N2 →err because N1 →err . By induction N1 is not typeable and therefore we cannot use (net), the only possible rule, to infer that N1 ∪ N2 is well-typed. 20

 To conclude, we have (− →∗ denotes the reflexive and transitive closure of − →) Corollary 3.5 (Type Soundness) Let Γ ` N : . Then N 0 →err holds false for every net N 0 such that N − →∗ N 0 . Proof: Subject Reduction implies that Γ ` N 0 :  and therefore we can apply Type Safety to obtain N 0 →err holds false. 

4 Examples In this section we show two application of our framework. The former is an example of a wellknown interaction pattern, where a process receives a request and delegates another process to reply, the latter is an example from WS-BPEL specification, where the interaction pattern is the traditional request-response.

4.1 A brokerage scenario Suppose a client process invokes a process that acts as a broker for a third process. The latter process, once received a message with an integer value and the client address, increases the value by one (of course, this can be replaced with any complex operation) and sends the response back to the client by exploiting the received address. This scenario is modelled by the net (we write Z , W to assign a symbolic name Z to the term W) N , {ac ::Opc ,Lc ∗sc | hac , oinit , 10i , ab ::Opb ,Lb ∗sb , ar ::Opr ,Lr ∗sr }

(1)

where ac , ab and ar are the addresses of client, broker and responder, respectively. The client service is defined as follows: sc , rec (linit , oinit , p) ; inv (ab , o, hp, ac i) ; rec (lr , ocb , hp, resi) The first receive creates a client instance by consuming the initialization tuple hac , oinit , 10i. Since multiple client instances can wait a response along the same partner link and operation, we use a correlation set to route each incoming message to the correct instance. At instantiation time, a correlation set consisting of the property p is initialized. When the client process invokes the broker, it must send an integer value and its address to allow the responder process to send back the reply. After this invocation, the client waits the callback. The client type declarations are Opc = {oinit : hIi, ocb : hI, Ii} and Lc = {p : I, res : I}. Notice that, in this communication pattern, differently from asynchronous request-response, the client has the provider role for the callback operation. The broker service is defined as follows: sb , rec (l, o, hb, lc i) ; inv (ar , o0 , hb, lc i) When invoked, the broker creates an instance (by using the receive activity) that will forward the client request to the responder and then terminate. Since no session with multiple interactions is started, the broker does not use a correlation mechanism. The broker type declarations are Opb = {o : τ¯ } with τ¯ = hI, {ocb : hI, Ii}i and Lb = {b : I}. Of course, the broker has the provider 21

role for the operation invoked by the client. In the message type of the operation, the second field is an operation type set and identifies the client operations that are visible to the broker. Finally, the responder service is defined as follows: sr , rec (l, o0 , hb, lcb i) ; ass (b0 , b + 1) ; inv (lcb , ocb , hb, b0 i) When invoked, the responder creates an instance that will process the received value and send the response back to the client. Also this process does not need a correlation mechanism. The responder type declarations are Opr = {o0 : τ¯ } and Lr = {b : I, b0 : I}. Notice that, since the responder receives the client address from the broker, its view of client operations along the partner link lcb agrees with that of the broker. According to our framework, to ensure that N will never generate errors, it suffices to prove that N is well-typed wrt the empty environment, i.e. ∅ ` N : . This, by rule (net), means that each node of N must be well-typed wrt the type environment Γ = {ac : Opc , ab : Opb , ar : Opr }. Now, by the rule (netToServ), (par) and (serv) this holds if all components hac , oinit , 10i, sc , sb and sr are well-typed wrt Γ and appropriate local type declarations. Formally, we must check that judgements Γ `aLcc hac , oinit , 10i : , Γ `aLcc sc : , Γ `aLbb sb :  and Γ `aLrr sr :  hold. This is what the inferences in Tables 10, 11, 12 and 13, respectively, show. For the sake of presentation, the inferences are split in a few parts with references between them. Comments on inference for the client service are in order. Notably, for both receive activities we must apply rule (rec), because the type environment does not store type information for the partner links linit and lr . Indeed, the client has provider role for both the operations oinit and ocb and we check if their type definitions are in the set of operation types of the client Opc , which is obtained by inferring Γ `aLcc ac : Opc . Instead, to check the invoke activity, we apply rule (inv), because in this case the service has client role. Opb contains the type definition of the invoked operation o and is obtained by the inference of Γc `aLcc ab : Opb , where ab is the target of the invoke activity. Notice that the type associated to o is a subtype of the type associated to the operation parameters (i.e. τ¯ v hI, Opc i), because {ocb : hI, Ii} ⊆ Opc . We have thus proved that the net N defined in 1 behaves correctly. Now, we smoothly modify N so that its execution would eventually generate a runtime error and show that our type system can statically point out this situation. Indeed, suppose that ocb : hI, Ii < Opc . This could take place, for example, in case the client tries a request-response interaction with the broker (which would be the provider of both operations). The modified net N 0 would behave as follows (we omit the responder node because it plays no role): N0

− → − → − → →err

{ac ::Opc ,Lc ∗sc | hac , oinit , 10i , ab ::Opb ,Lb ∗sb } {ac ::Opc ,Lc ∗sc | {p = 10}  s0c , ab ::Opb ,Lb ∗sb } {ac ::Opc ,Lc ∗sc | {p = 10}  rec (lr , ocb , hp, resi) , ab ::Opb ,Lb ∗sb | hac , o, h10, ac ii}

where the runtime error is generated by rule (opDefError2). This situation can be captured in advance, since N 0 is not well-typed because, in the inference for the client service, Γc `aLcc rec (lr , ocb , hp, resi) :  cannot be inferred.

4.2 Shipping service This example presents the use of a - process to describe a rudimentary shipping service (from Subsection 16.1 of WS-BPEL specification). This service handles the shipment of orders. From the service point of view, orders are composed of a number of items. The shipping service offers two types of shipment: shipments where the items are held and shipped together and shipment where the items are shipped piecemeal until all of the order is accounted for. 22

10 ∈ Int (ref) ac : Opc `aLcc ac : Opc (weak) Γ `aLcc ac : Opc

∅ `aLcc 10 : I oinit : hIi ∈ Opc Γ

`aLcc

Γ `aLcc 10 : I

(int) (weak)

I v I

hac , oinit , 10i : 

(req)

Table 10: Type inference for the service request

This service is modelled by the node a ::Op,L ∗s where the service specification is defined as follows: s , rec (cust, shipReq, req) ; if (req2 ) then {sthen } else {selse } sthen

,

ass (res2 , req3 ) ; inv (cust, shipNot, res)

selse

,

ass (itemsS hipped, 0) ; B(hitemsS hipped, req3 , req1 , custi)

B(par : τ¯ ?B )

de f

ass (itemC, rand()) ; inv (lc , shipNot, hordId, itemCi) ; ass (itemsS hipped0 , items + itemC) ; if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0}

=

where: • cust is the partner link used by the service to communicate with its customers; • shipReq and shipNot are the operations used to receive the shipping request and to send shipping notices, respectively; • req = hp orderId, complete, itemsT oti is the tuple of parameters used for the request shipping message; each instance of the shipping service is uniquely identified by the correlation set composed by the property p orderId; • res = hp orderId, itemsCounti is the tuple of parameters used for the response message; we notice that the property p orderId is used to fill the first field of the response message; • itemsS hipped is an integer variable used as counter; • par , hitems, tot, ordId, lc i is the tuple of formal parameters of service definition with identifier B and τ¯ ?B , hI, I, I, ?i is the tuple of their types; • rand() is a function which returns a random integer number and represents an internal interaction with back-end system (for the sake of simplicity, we don’t describe this interaction). The service type declarations are Op = {shipReq : τ¯ r , shipNot : τ¯ n }, where τ¯ r = hI, B, Ii and τ¯ n = hI, Ii, and L = {p orderId : I, complete : B, itemsT ot : I, itemsCount : I, itemsS hipped : I, itemC : I, itemsS hipped0 : I}. Notice that the 23

Table 11: Type inference for the client service sc (Γc is (Γ, linit : ?))

24

Γ `aLcc ac : Opc

(weak)

oinit : hIi ∈ Opc

(weak)

(ref)

ocb : hI, Ii ∈ Opc

Γ `aLcc

(weak)

(prop)

Γc `aLcc ac : Opc

(rec)

(weak)

(prop)

τ¯ v hI, Opc i

(w) ¯

(weak)

(var)

(inv)

Γc `aLcc inv (ab , o, hp, ac i) ; rec (lr , ocb , hp, resi) :  (seq)

(1) Γc `aLcc inv (ab , o, hp, ac i) :  (2) Γc `aLcc rec (lr , ocb , hp, resi) : 

rec (linit , oinit , p) ; inv (ab , o, hp, ac i) ; rec (lr , ocb , hp, resi) : 

Γ `aLcc p : I

∅ `aLcc p : I

p : I ∈ Lc

(1) Γc `aLcc inv (ab , o, hp, ac i) : 

(w) ¯

(weak)

(ref)

(rec)

Γc `aLcc res : I

∅ `aLcc res : I

res : I ∈ Lc

ac : Opc `aLcc ac : Opc

Γc `aLcc hp, ac i : hI, Opc i

Γc `aLcc p : I

∅ `aLcc p : I

p : I ∈ Lc

(weak)

(prop)

Γc `aLcc hp, resi : hI, Ii

Γc `aLcc p : I (2) Γc `aLcc rec (lr , ocb , hp, resi) : 

(weak)

(ref)

o : τ¯ ∈ Opb

Γ `aLcc rec (linit , oinit , p) : 

ac : Opc `aLcc ac : Opc

(ref)

Γc `aLcc ab : Opb

ab : Opb `aLcc ab : Opb

Γc `aLcc ac : Opc

ac : Opc `aLcc ac : Opc

∅ `aLcc p : I

p : I ∈ Lc

(seq)

Table 12: Type inference for the broker service sb (Γb is (Γ, l : ?, lc : {ocb : hI, Ii}))

25

Opb `aLbb

(weak)

(ref)

ab : Opb

(weak)

Γb `aLbb lc : {ocb : hI, Ii}

o : τ¯ ∈ Opb Γ `aLbb

(weak)

(var)

lc , l (rec)

(weak)

(ref)

τ¯ v hI, {ocb : hI, Ii}i

 (1) Γb `aLbb inv ar , o0 , hb, lc i :  (seq)  rec (l, o, hb, lc i) ; inv ar , o0 , hb, lc i : 

Γ `aLbb b : I

∅ `aLbb b : I

b : I ∈ Lb

(w) ¯

lc : {ocb : hI, Ii} `aLbb lc : {ocb : hI, Ii}

Γb `aLbb hb, lc i : hI, {ocb : hI, Ii}i  (1) Γb `aLbb inv ar , o0 , hb, lc i : 

Γb `aLbb b : I

(var)

Γ `aLbb rec (l, o, hb, lc i) : 

(weak)

(ref)

o0 : τ¯ ∈ Opr

Γ `aLbb ab : Opb

ab :

Γb `aLbb ar : Opr

ar : Opr `aLbb ar : Opr

∅ `aLbb b : I

b : I ∈ Lb

(inv)

Table 13: Type inference for the responder service sr (Γr is (Γ, l : ?, lcb : {ocb : hI, Ii}))

26

Γ `aLrr ar : Opr

ar : Opr `aLrr ar : Opr

(weak)

(var)

Γr `aLrr 1 : I

∅ `aLrr 1 : I Γr `aLrr b0 : I

∅ `aLrr b0 : I

b0 : I ∈ Lr

Γ `aLrr b : I

∅ `aLrr b : I

b : I ∈ Lr

Γ `aLrr

lcb , l (rec)

(ass)

(w) ¯

(weak)

(var)

(seq)

hI, Ii v hI, Ii

  (1) Γr `aLrr ass b0 , b + 1 ; inv lcb , ocb , hb, b0 i : 

rec (l, o0 , hb, lcb i) ; ass (b0 , b + 1) ; inv (lcb , ocb , hb, b0 i) : 

(weak)

(var)

 Γr `aLrr ass b0 , b + 1 : 

o0 : τ¯ ∈ Opr

(weak)

(var)

Γr `aLrr b0 : I

∅ `aLrr b0 : I

 (2) Γr `aLrr inv lcb , ocb , hb, b0 i :  (seq)   (1) Γr `aLrr ass b0 , b + 1 ; inv lcb , ocb , hb, b0 i : 

(exp+ )

(weak)

(int)

 Γ `aLrr rec l, o0 , hb, lcb i : 

(weak)

(ref)



(weak)

(var)

b0 : I ∈ Lr

Γr `aLrr hb, b0 i : hI, Ii

Γr `aLrr b : I (2) Γr `aLrr inv lcb , ocb , hb, b0 i : 

ocb : hI, Ii ∈ {ocb : hI, Ii}

1 ∈ Int

(weak)

(ref)

Γr `aLrr b + 1 : I

Γr `aLrr b : I

∅ `aLrr b : I

b : I ∈ Lr

Γr `aLrr lcb : {ocb : hI, Ii}

lcb : {ocb : hI, Ii} `aLrr lcb : {ocb : hI, Ii}

∅ `aLrr b : I

b : I ∈ Lr

(inv)

adopted communication pattern is the asynchronous request-response, so the process, which has the provider role, holds the type definitions of both request operation (shipReq) and callback operation (shipNot). To ensure that the net, consisting of only the service node, will never generate errors, it suffices to prove that it is well-typed wrt the empty environment. By the rule (net), we have that Γ ` a ::Op,L ∗s : , with Γ = ∅, a : Op. So, by the rule (netToServ) and (serv), this holds if the service specification s is well-typed wrt Γ and the local declarations. Formally, we must check that Γ `aL s :  holds. This is what the inferences in Tables 14, 15 and 16, show. For the sake of presentation, the inferences are split in a few parts with references between them.

27

Table 14: Type checking of shipping service specification s (Γ0 is (Γ, cust : ?))

a : Op

Γ `aL a : Op

a : Op

`aL

(weak)

(var)

(weak)

(ref)

Γ0 `aL a : Op

a : Op `aL a : Op

Γ

`aL p orderId : I

∅ `aL p orderId : I

p orderId : I ∈ L

Γ `aL rec (cust, shipReq, req) : 

shipReq : τ¯ r ∈ Op

(ass)

(weak)

(var) (weak)

(ref)

shipNot : τ¯ n ∈ Op

(weak)

(prop)

Γ `aL req : τ¯ r (rec)

complete : B

(weak)

(var)

(weak)

Γ

`aL

itemsT ot : I

∅ `aL itemsT ot : I

itemsT ot : I ∈ L

(w) ¯

(weak)

(var)

(inv cb)

(weak)

(ref)

(seq)

(2) Γ0 `aL selse : 

(1) Γ0 `aL sthen : 

Γ0 `aL cust : ?

cust : ? `aL cust : ?

Γ0 `aL if (complete) then {sthen } else {selse } : 

(weak)

(var)

(w) ¯

(weak)

(var)

Γ0 `aL complete : B

∅ `aL complete : B

complete : B ∈ L

Γ0 `aL inv (cust, shipNot, res) :  (seq)

Γ0 `aL itemsCount : I

∅ `aL itemsCount : I

itemsCount : I ∈ L

Γ0 `aL res : τ¯ n

Γ0 `aL p orderId : I

∅ `aL p orderId : I

(var)

Γ `aL rec (cust, shipReq, req) ; if (req2 ) then {sthen } else {selse } : 

Γ

`aL

∅ `aL complete : B

complete : B ∈ L

(1) Γ0 `aL ass (res2 , req3 ) ; inv (cust, shipNot, res) : 

Γ0 `aL itemsCount : I

∅ `aL itemsCount : I

itemsCount : I ∈ L

Γ0 `aL ass (itemsCount, itemsT ot)

Γ0 `aL itemsT ot : I

∅ `aL itemsT ot : I

itemsT ot : I ∈ L

p orderId : I ∈ L

(if)

Table 15: Γ00 is (Γ0 , B : , lc : ?) and L0 is L ∪ {items : I, tot : I, ordID : I}

0

(ran)

0

0 ∈ Int

(weak)

Γ0 `aL itemsS hipped : I

∅ `aL itemsS hipped : I

Γ0 `aL ass (itemsS hipped, 0) : 

Γ0 `aL 0 : I

(int)

itemsS hipped : I ∈ L

(ass)

(weak)

(var)

Γ00 `aL itemsC : I

Γ00 `aL ass (itemsC, rand()) : 

∅ `aL 0 : I

0

Γ00 `aL rand() : I

∅ `aL itemsC : I

0

itemsC : I ∈ L0

(ass)

(w) ¯

Γ0 `aL B : 

0

Γ0 `aL cust : ?

(weak)

(ref)

(seq)

(w) ¯

τ¯ B v hI, I, I, ?i (call)

(4) Γ00 `aL ass (itemsS hipped0 , items + itemC) ; if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0} : 

cust : ? `aL cust : ?

(inv cb)

(weak)

(ref)

Γ0 `aL hitemsS hipped, req3 , req1 , custi : hI, I, I, ?i

...

0

Γ00 `aL lc : ?

0

lc : ? `aL lc : ?

Γ0 `aL B(hitemsS hipped, req3 , req1 , custi) : 

(def1 )

(3) Γ00 `aL ass (itemC, rand()) ; inv (lc , shipNot, hordId, itemCi) ; ass (itemsS hipped0 , items + itemC) ; if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0} : 

0

0

0

Γ00 `aL hordId, itemCi : τ¯ n

Γ00 `aL inv (lc , shipNot, hordId, itemCi) : 

shipNot : τ¯ n ∈ Op

...

(2) Γ0 `aL ass (itemsS hipped, 0) ; B(hitemsS hipped, req3 , req1 , custi) : 

(weak)

(var)

0

(weak)

(ref)

(3) Γ00 `aL ass (itemC, rand()) ; inv (lc , shipNot, hordId, itemCi) ; ass (itemsS hipped0 , items + itemC) ; if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0} : 

0

Γ00 `aL a : Op

0

a : Op `aL a : Op

(seq)

Table 16: Type checking of a shipping service subterm

0

0

0

0

...

0

Γ00 `aL lc : ?

0

Γ00 `aL B(hitemsS hipped0 , tot, ordId, lc i) : 

0

0

0

(w) ¯

τ¯ ?B v hI, I, I, ?i

(seq)

(call)

(5) Γ00 `aL if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0} : 

(4) Γ00 `aL ass (itemsS hipped0 , items + itemC) ; if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0} : 

(ass)

(weak)

(var)

Γ00 `aL itemsS hipped0 : I

∅ `aL itemsS hipped0 : I

itemsS hipped0 : I ∈ L0 0

(weak)

(ref)

Γ00 `aL hitemsS hipped0 , tot, ordId, lc i : hI, I, I, ?i

 0 Γ00 `aL ass itemsS hipped0 , items + itemC : 

(+int )

0

(weak)

(def2 )

0

lc : ? `aL lc : ?

(5) Γ00 `aL if (itemsS hipped0 < tot) then {B(hitemsS hipped0 , tot, ordId, lc i)} else {0} : 

(weak)

(var)

Γ00 `aL itemsC : I

0

∅ `aL itemsC : I

0

Γ00 `aL B : 

0

B :  `aL B : 

itemsC : I ∈ L0

(

Suggest Documents