Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Contents lists available at ScienceDirect
Journal of Logical and Algebraic Methods in Programming www.elsevier.com/locate/jlamp
A calculus for modeling floating authorizations ✩ Ivan Prokic´ a,∗ , Jovanka Pantovic´ a,∗ , Hugo Torres Vieira b,∗ a b
Faculty of Technical Sciences, University of Novi Sad, Trg Dositeja Obradovi´ca 6, 21000, Novi Sad, Serbia IMT School for Advanced Studies Lucca, Piazza San Francesco 19, 55100, Lucca, Italy
a r t i c l e
i n f o
Article history: Received 3 August 2018 Received in revised form 2 May 2019 Accepted 13 June 2019 Available online 18 June 2019 Keywords: Language-based security Resource usage Process calculus Type systems
a b s t r a c t Controlling resource usage in distributed systems is a challenging task given the dynamics involved in access granting. Consider, e.g., the setting of floating licenses where access can be granted if the request originates in a licensed domain and if the number of active users is within the license limits. Access granting in such scenarios is given in terms of floating authorizations, addressed in this paper as first class entities of a process calculus model, encompassing the notions of domain, accounting and delegation. We present the operational semantics of the model in two equivalent alternative ways, and report on a preliminary investigation of the behavioral semantics, addressing fundamental properties and informing on the specific nature of our authorizations. We also introduce a typing discipline to single out systems that never get stuck due to lacking authorizations, addressing configurations where authorization assignment is not statically prescribed in the system specification. Finally, we present a refinement of the type system which paves the way for obtaining a more efficient type checking procedure. © 2019 Elsevier Inc. All rights reserved.
1. Introduction Despite the continuous increase of computational resources, their usage will always nevertheless be subject to accessibility and availability. Regardless whether such resources are of hardware or software in nature, they might have finite or virtually infinite capabilities. Physical examples, that can be mapped to finite capabilities directly, include devices such as printers or cell phones, and components of a computing system such as memory or processors. Virtual examples, such as a shared memory cell or a web service, can be more easily seen as having infinite potential but often their availability is also finitely constrained. In general, ensuring proper resource usage is a crucial yet non-trivial task, given the highly dynamic nature of access requests and the flexibility necessary to handle such requests, while ensuring secure and efficient system operation. For security purposes it is crucial to control that access is granted only to authorized users, but also to enforce that access granting is subject to availability. Concrete examples include a wireless access point that has a given access policy and a limited capacity on the number of connected devices, and a software application that is licensed to be used by an institution in a bounded way. Both examples address limited capabilities that are accessible in a shared way to authorized users. We thus identify a notion of floating authorization, adopting the terminology from the licensing realm, where access
✩ This paper is a revised and extended version of the paper [20], presented in the Proceedings of the 38th IFIP WG 6.1 International Conference on Formal Techniques for Distributed Objects, Components, and Systems (FORTE 2018). Corresponding authors. ´
[email protected] (J. Pantovic), ´
[email protected] (H.T. Vieira). E-mail addresses:
[email protected] (I. Prokic),
*
https://doi.org/10.1016/j.jlamp.2019.06.002 2352-2208/© 2019 Elsevier Inc. All rights reserved.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
137
to resources can be granted to any authorized user in a given domain up to the point the capacity is reached. We also identify a notion of implicit granting since users may be granted access directly when using the resource (e.g., running the licensed software). Considering the licensing setting, we find further examples that inform on the dynamic nature of authorizations. For example, a user deploys a software application on the cloud and provides the license himself (cf. Bring Your Own License [11]), potentially losing access to run the application locally given the capacity constraints. We identify here a notion of authorization delegation, where the intention to yield or obtain an authorization is explicit. We therefore distill the following dimensions in a floating authorizations model: domain so as to specify where access may be (implicitly) granted; accounting so as to capture capacity; and delegation so as to model (explicit) authorization granting. In this paper, we present a model that encompasses these dimensions, developed focusing on a process calculus tailored for communication centered systems. In our model the only resources considered are communication channels, so our exploration on authorization control is carried out considering authorizations refer to channels and their usage (for communication) is controlled. Our development builds on the π -calculus [21], which provides the basis to model communicating systems including name passing, and on a calculus for authorizations [15], from where we adopt the language constructs for authorization domain scope and delegation. We adapt here the interpretation for authorization domains so as to encompass accounting, which thus allows us to model floating authorizations. To the best of our knowledge, ours is the first process calculus model that addresses floating resources (in our case authorizations) as first class entities. Naturally, this does not mean our language cannot be represented in more canonical models, only that we are unaware of existing approaches that offer abstractions that support reasoning on floating resources in a dedicated way. After presenting the model and reporting on some preliminary results regarding the behavioral semantics, we show a typing discipline that ensures systems never incur in authorization errors, i.e., that never evolve to systems that involve active but non-authorized communicating pairs. Our type analysis addresses systems for which the authorization assignment is not statically given in the system specification, in particular when authorizations for (some) received names are already held by the receiving parties, a notion that we call contextual authorizations, which we believe has not been explored in previous works. We also present a refinement of the type system which improves the efficiency of the induced type-checking procedure. We start by discussing some simple examples that informally introduce our model, and leave towards the end of the paper a more interesting example involving the notion of Bring Your Own License, which also allows to place our development in a relevant domain in practice. For the sake of their systematic presentation, we summarize the contributions of this work as follows:
• We present a model that encompasses dimensions of domain, accounting, implicit and explicit granting of floating authorizations, focusing on communication centered systems.
• We also present a preliminary investigation of the behavioral semantics of the model, which in particular allows to formally characterize some of the design principles of the model, namely the accounting dimension.
• We introduce a type analysis that addresses systems that relying on their own (contextual) authorizations can be deemed safe even when the authorization assignment is not statically prescribed.
• We also introduce a refinement of the type system which paves the way to a more efficient type-checking procedure, by providing a more operational characterization of authorization assignment.
• We show an example based on the notion of Bring Your Own License inspired from the licensing setting, which also allows to showcase our technical development.
• We discuss an application of our language principles by pointing towards a possible extension of the Go programming language.1
1.1. Model preview We present our language by resorting to the licensing setting for the sake of a more intuitive reading, starting by focusing on the novel central notion of our approach. Authorization domain (scope). First of all, to model authorization domains we consider a (non-binding) scoping construct, and we write
(license)University to represent that the University domain holds one license. This means that the usage of license within University is authorized only for a single user. In particular, if University comprises two students that are simultaneously active, which we dub Alice and Bob, we may write
(license)(Alice | Bob) 1
https://golang.org.
138
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
in which case either Alice or Bob can be granted the license that is floating, but not both of them. The notation for the authorization scope is inspired by one of name restriction (ν a), which will be presented later, since on the one hand both are scoping operators, while on the other hand we elide ν since the authorization scope is non-binding. Counting authorizations. The idea is to support a notion of accounting, so when one of the students uses the license the scope is confined accordingly. For example, if Bob uses the license and evolves to LicensedBob then the system evolves to
Alice | (license)LicensedBob
(1)
where the change in the scope denotes that license is not available to Alice anymore. We remark that usage in our model is given in terms of communication primitives and we are assuming Bob specifies a communication action (i.e., Bob is a prefixed process and LicensedBob is the continuation process). The evolution of the system is such that the authorization is directly confined to LicensedBob so as to model implicit granting. At this point Alice cannot implicitly grab the authorization and gets “stuck” if she tries to use license. Hence, name license may be shared between Alice and Bob, so the (change of) scoping does not mean the name is privately held by LicensedBob, just the authorization. We remark this interpretation of accounting is novel to our approach. Our model supports a form of fairness and does not allow a “greedy” usage of resources. For example, in the configuration
(license)(Alice | (license)LicensedBob) the user LicensedBob can only be granted the closest (license) first, not interfering with Alice, but can be also granted the top-level license if he needs both licenses. Authorization sharing (delegation). Now consider that Bob and Carol want to explicitly exchange an authorization, which can be carried out by a delegation mechanism supported by two communication primitives. We write
authlicense.UnlicensedBob to represent the explicit delegation of one authorization for license via communication channel auth, after which activating configuration UnlicensedBob. Instead, by
auth(license).LicensedCarol we represent the dual primitive that allows to receive one authorization for license via channel auth after which activating configuration LicensedCarol. So by
(license)(auth)authlicense.UnlicensedBob | (auth)auth(license).LicensedCarol we represent a system where the authorization for license can be transferred leading to
(auth)UnlicensedBob | (auth)(license)LicensedCarol where the scope of the authorization for license changes accordingly. The underlying communication is carried out by a synchronization on channel auth, for which we remark the respective authorizations (auth) are present. In fact, in our model channels are the only resources and their usage is (always) subject to the authorization granting mechanism. Name passing. We remark that no name passing is involved in the authorization delegation mechanism and that name license is known to both ends in the first place. Instead, name passing is supported by dedicated primitives, namely
(comm)comm!license.Alice | (comm)comm?x.Dylan represents a system where the name license can be passed via a synchronization on channel comm, leading to the activation of Alice and Dylan where, in the latter, the placeholder x is instantiated by license. Notice that the synchronization can take place since the authorizations to use channel comm are given, one for each endpoint. This is also the case in
(comm)(comm)(comm!license.Alice | comm?x.Dylan) hence the synchronization may occur, however it is not possible in (comm)(comm!license.Alice | comm?x.Dylan) since there is only one authorization.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
139
On the separation of authorization delegation and name passing. Name passing allows to model systems where access to channels changes dynamically (since the communicated names refer to channels) but, as hinted in the previous examples, knowing a name does not mean being authorized to use it. So, for instance, (comm)comm?x.x!reply.0 specifies a reception in (authorized) comm where the received name is then used to output reply, leading to an inactive state (denoted by 0). Receiving license in channel comm leads to (comm)license!reply.0 where the authorization for comm is still present but no authorization for license is acquired as a result of the communication. Hence the output specified using license is not authorized and cannot take place. We remark that an authorization for reply is not required, hence communicating a name does not entail usage for the purpose of authorization control. By separating name passing and authorization delegation we are then able to model systems where unauthorized intermediaries (e.g., brokers) may be involved in forwarding names between authorized parties without ever being authorized to use such names. For example (comm)comm?x.(forward)forward!x.0. which requires no further authorizations. Configuration
(comm)comm?x.(auth)auth(x).LicensedDylan shows a possible pattern for authorizing received names where, after the reception on comm, an authorization reception for the received name (using placeholder x) via auth is specified, upon which the authorization to use the received name is acquired. Another possibility for enabling authorizations for received names is to use the authorization scoping, e.g.,
(comm)comm?x.(x)LicensedDylan where the authorization (x) is instantiated by the received name. This example hints on the fact that the authorization scoping is a powerful mechanism that may therefore be reserved in some circumstances to the Trusted Computing Base, resorting to authorization delegation elsewhere. We remark that albeit the above mechanism seems to capture authorization reception, there is no direct way to represent authorization delegation (the delegating party actually loses the respective authorization as discussed above). Name creation and replication. To introduce the last constructs of our language, consider the system
!(license)license?x.(x)licensex.0 | (ν fresh)(license)license!fresh.license(fresh).0 where a licensing server is specified on the left hand side, used in the specification given on the right hand side. By (ν fresh)Domain we represent the creation of a new name which is private to Domain, in contrast with authorization scoping (cf. discussion after (1)). The specification on the right hand side can be read as first create a name, then send it via channel license, after which receive the authorization to use the fresh name via channel license and then terminate (the received authorization is not actually used in this simple example). On the left hand side, we find a replicated (i.e., repeatably available) reception on channel license, after which an authorization scope for the received name is specified that may then be delegated away. Type system. We now return to the university scenario so as to present our type analysis. Consider process
(exam)(minitest)(alice)alice?x.x!task.0 where there are available authorizations for exam and for minitest, and where alice is waiting to receive the channel on which she will send task. Assuming that she can only receive exam or minitest the authorizations specified are sufficient. Which authorization will actually be used depends on the received name, so the authorization is implicitly taken when the received channel is used. However, if a name viva is sent then the provided authorizations do not suffice. In order to capture the fact that the above configuration is authorization safe, provided it is inserted in a context that matches the assumptions described previously, our type analysis records the names that can be safely communicated. For instance, we may say that only names exam and minitest can be communicated in channel alice. Also, consider that exam and minitest can only receive values that are not subject to authorization control. We then denote by {alice}({exam, minitest}(∅)) the type of channel alice in such circumstances, i.e., that it is not subject to replacement (we will return to this point), and that it can be used to communicate exam and minitest that in turn cannot be used for communication (typed with ∅), reading from left to right. Using this information, we can ensure that the specification given for alice above is safe, since all names that will possibly be used in communications are contextually authorized. To analyze the use of the input variable x we then take into account that it can be instantiated by either exam or minitest (which cannot be used for channel communication) so the type of x is {exam, minitest}(∅). Hence the need to talk about possible replacements of a name, allowing us to uniformly address names that are bound in inputs. Our types, denoted γ ( T ), are then built out of two parts, one addressing possible replacements of the name identity itself (γ ), and the other informing on the (type of the) names that may be exchanged in the channel (T ). The typing assumption
alice : {alice}({exam, minitest}(∅))
140
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Table 1 Syntax of processes. P ::= 0 (Inaction) P | P (Parallel) (ν a) P (Restriction)
a!b. P (Output) a?x. P (Input) (a) P (Authorization)
(Send authorization) ab. P a(b). P (Receive authorization) !(a)a?x. P (Replicated input)
informs on the possible contexts where the system above can be safely used. For instance, it is safe to compose with the system (alice)alice!minitest where minitest is sent to alice, since the name to be sent belongs to the names expected on alice. Instead, consider configuration
(exam)(minitest )((alice)alice?x.x!task.0 | (bob)bob?x.x!task.0)
(2)
which is also safe and addressed by our typing analysis considering typing assumptions
alice : {alice}({exam}(∅)) and bob : {bob}({minitest}(∅)). The assumptions in a typing judgment allow to specify what a process expects from a (typed) context. Therefore, we may also type the process (2) with assumptions
alice : {alice}({minitest}(∅)) and bob : {bob}({exam}(∅)). Notice that which authorization will actually be used by each student is not statically prescribed in the system (since the authorizations scope both students), but considering that both exam and minitest are used by the two students we may ensure that the system is authorization safe (given that the authorization scopes can be confined accordingly, one per each student). The typing specification (given in the assumptions above) ensures that both exam and minitest are received by the students, while clearly providing a specific association between which name is received by each student (i.e., that Alice will receive exam and that Bob will receive minitest, or with the order reversed). Outline. In Section 2 we present the operational semantics of our language considering two equivalent alternatives, and in Section 3 we present a preliminary investigation of the behavioral semantics of the model, including some fundamental results and behavioral (in)equalities that inform on the specific nature of our authorizations. The typing analysis shown in Section 4 addresses configurations where authorizations for received names may be provided by the context, refined in Section 5 so as to allow for a more applicable procedure. In Section 6 we present an extended example inspired by the Bring Your Own License notion, while in Section 7 we discuss possible programming language applications of our formal framework for authorization control, namely by considering an extension of the Go programming language. This paper extends previous work [20] with the investigation of the behavioral semantics (Section 3), the refinement of the type system (Section 5), the extended example (Section 6), and the discussion on the extension of the Go language (Section 7), besides including more examples and discussions as well as the proofs of the results in the appendix. 2. A model of floating authorizations In this section, we present our process calculus, which builds on previous work on process calculi for authorizations [14, 15]. In [15], the authors presented a typed process calculus for the analysis of multiparty interactions with dynamic role authorization and delegation, relying on the conversation type analysis presented in [5]. The syntax of the process algebra introduced in [15] was additionally simplified in [14], focusing exclusively on the authorization dimension. Our calculus syntax is directly adopted from [14], but semantically it departs in the accounting principle, which is crucial to enable us to capture the floating nature of the authorizations investigated in this paper. We will point to the similarities/differences of the two process algebras throughout the presentation. The syntax of the language is given in Table 1, assuming a countable set of names N , ranged over by a, b, c , . . ., x, y , z, . . . We briefly present the constructs adopted from the π -calculus. An inactive process is represented by 0. By P | P we represent two processes simultaneously active, that may interact via synchronization in channels. The name restriction construct (ν a) P specifies the creation of a channel name a that is known only to the process P . The output prefixed process a!b. P sends the name b on channel a and proceeds as P , and the input prefixed process a?x. P receives a name on channel a and replaces name x in P with the received name. The remaining constructs involve authorization specifications and are adopted from [14]. Term (a) P is the authorization scoping, representing that process P has one authorization to use channel a for multiple actions that are composed sequentially. In contrast with name restriction, in (a) P name a is not private to P . Term ab. P represents the process that delegates one authorization for name b along name a and proceeds as P . Term a(b). P represents the dual, i.e., a process which receives one authorization for name b along name a and proceeds as (b) P . Term !(a)a?x. P allows to specify infinite behavior: the process receives the name along (authorized) name a and substitutes x in P with the received name, which is activated in parallel with the original process. We adopt a simple form of infinite processes, but we remark that a general replication construct can be encoded following standard lines using replicated input, as discussed later.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
141
In (ν x) P , a?x. P and !(a)a?x. P the name x is binding with scope P . As usual, we use fn( P ) and bn( P ) to denote the sets of free and bound names in P , respectively. In (a) P occurrence of the name a is free and occurrences of names a and b in processes ab. P and a(b). P are also free. We remark that in our model authorization scope extrusion is not applicable since a free name is specified, unlike name restriction, and constructs to send and receive authorizations only affect the scope of authorizations. For the rest of presentation we use the following abbreviations: αa stands for a!b, a?x, ab or a(b) (including when b = a) and (ν a˜ ) stands for (ν a1 ) . . . (ν an ). As in the π -calculus, the essence of the behavior of processes can be seen as communication. In addition, in our model two processes ready to synchronize on a channel must be authorized to use the channel. Before formally introducing operational semantics, we first motivate it by examples that illustrate some simple configurations where communication is either enabled or disabled. Example 1 (Authorized communications). 1. We consider that processes
(a)a!b. P | (a)a?x. Q
and
(a)(a)(a!b. P | a?x. Q )
can both evolve to (a) P | (a) Q {b/x}, since all their sending and receiving actions are authorized. 2. Another aspect of our language is authorization delegation. For example, in
(a)(b)ab. P | (a)a(b). Q both actions along name a are authorized and the delegating process has the authorization on b, hence the delegation can take place, leading to (a) P | (a)(b) Q where the authorization scope for b changes. If actions along name a are not authorized or the process delegating lacks the authorization for b, then the synchronization is not possible. 3. As it can be noticed in the previous two examples, authorizations are not consumed by communication, they can further authorize actions in the continuation. For example, process
(a)a!b.a? y .0 | (a)a?x.a!c .0 that can evolve to (a)a? y .0 | (a)a!c .0 can further evolve to (a)0 | (a)0. Example 2 (Unauthorized communications).
1. In contrast, processes
(a)a!b. P | a?x. Q
and
(a)(a!b. P | a?x. Q )
cannot evolve due to lacking authorizations. The former process lacks the proper authorization on the receiving end, hence the synchronization cannot occur. The latter one lacks the proper authorizations since only one is available, while two are required for the synchronization to occur, one per endpoint. We remark that the latter process can evolve by the operational semantics in [14,15], where both communication ends are considered to be authorized by (a), due to a different interpretation of the accounting principle. 2. In
(a)ab. P | (a)a(b). Q delegation is not authorized since the lhs process lacks an authorization for b. The following example shows a key difference between operational semantics of the process algebra in [15] and the present one. Example 3 (On authorization accounting). The process algebra considered in [15] (and [14]) embeds the structural congruence rule (a)( P | Q ) ≡ (a) P | (a) Q . By this rule, the scoping of (a) ranging over the two threads can equivalently be considered as having the given authorization (a) for each thread (and vice versa). Under that interpretation of authorization scope, we have that
(b)((a)ab. P |(a)a(b). Q ) ≡ (b)(a)ab. P |(b)(a)a(b). Q → (a) P |(b)(b)(a). Q where the global authorization for b is grabbed by the process on the lhs upon delegation, while the process on the rhs receives the delegated authorization and retains the originally available one.
142
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Table 2 LTS rules.
(l-out)
(l-out-a)
(l-in)
(a)a!b
a!b. P −−−→ (a) P
(l-par) α P− →Q
a?b
!(a)a?x. P −−→ (a) P {b/x} | !(a)a?x. P
α
a = b
(a) (ν b)a!b
P −−−→ Q
τω
(a) P −→ Q
(a)σa
σa
(a) P −→ Q
(ν b) P −−−−−−→ Q
(l-scope) α P− → Q τω(a) = α = (a)σa
τω(a)
P −−−→ Q
i
(ν a) P − → (ν a) Q
(l-scope-ext)
(l-scope-int)
(a)i a!b
P −−−−→ Q
α
bn(α ) ∩ fn( R ) = ∅
P|R− →Q |R
(l-open) a∈ / n(α )
(a)a(b)
a(b). P −−−−→ (a)(b) P
ab. P − −−−−−→ (a) P
(l-in-rep)
(l-res) α P− →Q
(l-in-a)
(a)(b)ab
(a)a?b
a?x. P − −−−→ (a) P {b/x}
(l-comm) (a) a!b P −−−−→ P i
α
(a) j a?b
Q −−−−→ Q τω
(a) P − → (a) Q
P | Q −→ P | Q
ω = (a)i + j
(l-close) (b) (ν a)b!a P −−−−−−→ P i
(b) j b?a
Q −−−−→ Q
ω = (b)i + j a ∈/ fn( Q )
τω
P | Q −→ (ν a)( P | Q )
(l-auth) (b)k (a)i ab
P− −−−−−−→ P
(a) j a(b)
Q − −−−−→ Q
ω = (a)i + j (b)k
τω
P | Q −→ P | Q
Such a structural congruence rule is excluded from the present process algebra for the purpose of our authorization accounting principle, since it directly allows changing the number of authorizations in the system (cf. the discussion in the beginning of Section 2.2 and Proposition 3). In our interpretation, we have that process
(b)((a)ab. P |(a)a(b). Q ) can evolve in one step to (a) P |(b)(a) Q where, upon delegation, the only authorization for b is confined to the process on the rhs. We formally define the behavior of processes by means of a labeled transition system and afterwards by means of a reduction semantics, which are shown equivalent but inform in somewhat different ways on the specific nature of authorizations in our model. For instance, we believe our authorization accounting principle can be explained in a more appropriate way when considering the reduction semantics (in particular when addressing the structural congruence relation), so we leave a more detailed account of this principle (including the main difference w.r.t. [15]) for the beginning of Section 2.2. 2.1. Action semantics Before introducing the labeled transition system (LTS), we first characterize the observable labels. Definition 1 (Observable actions). The set of observable actions, ranged over by
α , is defined as follows:
α ::= (a)i a!b | (a)i a?b | (a)i (b) j ab | (a)i a(b) | (a)i (ν b)a!b | τω where
ω is of the form (a)i+ j (b)k and i , j , k ∈ {0, 1} and it may be the case that a = b.
We may recognize the communication action prefixes placed together with annotations that capture carried/lacking authorizations and bound names. Intuitively, a communication action tagged with (a)0 represents the action does not lack an authorization on a, while (a)1 represents the action lacks an authorization on a. In the case for authorization delegation two such annotations are present, one for each name involved. As in the π -calculus, (ν b) denotes that the name in the object of the output is bound. In the case of internal steps, the ω identifies the lacking authorizations, and we use τ to abbreviate τ(a)0 (b)0 where no authorizations are lacking. By n(α ), fn(α ) and bn(α ) we denote the set of all, free and bound names of α . The transition relation is the least relation included in P × A × P , where P is the set of all processes and A is the set of all actions, that satisfies the rules in Table 2, which we now briefly describe.
• Rules (l-out), (l-in), (l-out-a), (l-in-a) capture the actions that correspond to the communication prefixes. In each rule the continuation is activated under the scope of the proper authorizations required for the action (and provided in case of
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
143
Table 3 Structural congruence.
(sc-par-inact) P |0≡ P (sc-res-swap) (ν a)(ν b) P ≡ (ν b)(ν a) P (sc-alpha) P ≡α Q =⇒ P ≡ Q
• • • • •
• • • • •
(sc-par-comm) P|Q ≡Q |P
(sc-par-assoc) (P | Q ) | R ≡ P | (Q | R)
(sc-res-extr) P | (ν a) Q ≡ (ν a)( P | Q ) (a ∈ / fn( P )) (sc-auth-swap) (a)(b) P ≡ (b)(a) P
(sc-auth-inact) (a)0 ≡ 0
(sc-res-inact) (ν a)0 ≡ 0
(sc-rep) !(a)a?x. P ≡ !(a)a?x. P | (a)a?x. P (sc-scope-auth) (a)(ν b) P ≡ (ν b)(a) P
if a = b
authorization reception), so as to realize confinement. The labels are decorated with the corresponding authorizations, representing that the actions are lacking authorizations. Rule (l-in-rep) corresponds to replicated input, which is authorized by construction. That is the reason why the label is not decorated with the authorization, omitting the (a)0 annotation. Rule (l-par) lifts the actions of one of the branches while avoiding unintended name capture. Rule (l-res) says that actions of P are also actions of (ν a) P , provided that the restricted name is not specified in the action. Rule (l-open) captures the bound output case, opening the scope of the restricted name a, thus allowing for scope extrusion (all three adopted from the π -calculus). Rule (l-scope-int) shows the case of a synchronization that lacks an authorization on a, so in the conclusion the action exhibited no longer lacks the respective authorization and leads to a state where the authorization scope is no longer present. We use ω(a) to abbreviate (a)2 (b)k , (a)1 (b)k , and (b)i + j (a)1 , for a given b (including the case b = a), in which case ω is obtained by the respective exponent decrement for a. We remark that in contrast to the extrusion of a restricted name via bound output, where the scope floats up to the point a synchronization (rule (l-close) explained below), authorization scopes actually float down to the level of communication prefixes (cf. rules (l-out), (l-in), (l-out-a), (l-in-a)), so as to capture confinement. Rule (l-scope-ext) follows similar lines as (l-scope-int) as it also refers to lacking authorizations, specifically for the case of an external action. We use σa to denote both an action that specifies a as communication subject (αa ), including bound output (ν b)a!b, and of the form (b)i ba where i ∈ {0, 1} (which includes (a)1 aa). Rule (l-scope) captures the case of an action that is not lacking an authorization on a, in which case the action crosses seamlessly the authorization scope for a. Rule (l-comm) refers to synchronization of parallel processes, where one process is able to send and other to receive a name b along name a so the synchronization may take place. If the sending and receiving actions are not carrying the appropriate authorizations, then the transition label τω specifies the lacking authorizations. Rule (l-close) refers to synchronization of parallel processes, where one process is able to send a bound name a and the other to receive it, along name b, so the synchronization may occur leading to a configuration where the restriction scope is specified (avoiding unintended name capture) so as to finalize the scope extrusion. Rule (l-auth) expresses the authorization delegation, where an extra annotation for ω is considered given the required authorization for the delegated authorization. Carried authorization annotations, considered here up to permutation, thus identify, in a compositional way, the requirements for a synchronization to occur.
Symmetric cases of rules (l-comm), (l-close), (l-auth) and (l-par) are omitted. 2.2. Reduction semantics Reduction is defined as a binary relation between processes, denoted →, so P → Q specifies that process P evolves to process Q in one computational step. In order to identify processes which differ syntactically but have the same behavior, we introduce the structural congruence relation ≡, which is the least congruence relation between processes satisfying the rules given in Table 3. Most rules are standard considering structural congruence of the π -calculus. In addition we adopt rules introduced previously [15] that address authorization scopes, including (sc-auth-inact) that allows to discard unused authorizations, while we depart from previous work in the principle explained after Example 4 so as to be able to capture the notion of floating authorizations. We can now point out on another crucial difference between notions (a) and (ν a), that is reflected in the structural congruence relation. One can notice that there exists a standard rule for extrusion of the scope of (ν a), namely (sc-res-extr), while there is no such rule for the scope of (a). We discuss this difference by means of an example. Example 4 (On authorization scope extrusion). Let us consider the process
(b)b?x.x!c .0 | (ν a)(a)(b)b!a.0 that creates on the rhs a fresh name a and one authorization for it. In the π -calculus (as well as here) the scope extrusion axiom (sc-res-extr) allows to extend the scope of bound variable a, implying that the following equivalence holds
144
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
(b)b?x.x!c .0 | (ν a)(a)(b)b!a.0 ≡ (ν a) ((b)b?x.x!c .0 | (a)(b)b!a.0) On the other hand, there is no such axiom for the authorization scope of a, giving the inequality
(ν a) ((b)b?x.x!c .0 | (a)(b)b!a.0) ≡ (ν a)(a) ((b)b?x.x!c .0 | (b)b!a.0) The previous property is required, since the lhs process evolves (by the standard
π -calculus rule for communication) to
(ν a) ((b)a!c .0 | (a)(b)0) with an unauthorized action on channel a, while the rhs process evolves to the process
(ν a)(a) ((b)a!c .0 | (b)0) where the action on a is authorized. Regarding authorization scoping, we remark there is no rule which relates authorization scoping and parallel composition. Adopting a rule of the sort (a)( P | Q ) ≡ (a) P | (a) Q would represent introducing/discarding one authorization, thus interfering with authorization accounting. Hence, we distinguish (a)( P | Q ) where the authorization is shared between P and Q and (a) P | (a) Q where two authorizations are specified, one for each process. Another approach to capture confinement could be a rule of the sort (a)( P | Q ) ≡ P | (a) Q , which, however, may also affect the computational power of a process. For example, processes a!b.0 | (a)0 and (a)(a!b.0 | 0) are clearly not to be deemed equal. Contrary to [15], due to the lack of such a structural congruence rule, we do not see how we may obtain a normal form characterization of processes. Structural congruence is therefore not expressive enough to isolate two authorized processes willing to synchronize, which brings us to a novel development of a non-standard approach. To define the reduction relation we introduce an auxiliary notion of static contexts with one and two holes and operation drift that allows to single out configurations where communication can occur. Intuitively, reduction is possible if two processes have active prefixes ready for synchronization and each is properly authorized. Definition 2 (Static contexts). Static contexts with one and two holes are defined as follows:
C [·] ::= · | ( P | C [·]) | (a)C [·]
C [·1 , ·2 ] ::= (C [·1 ] | C [·2 ]) | ( P | C [·1 , ·2 ]) | (a)C [·1 , ·2 ]
We use ·1 and ·2 notation to avoid ambiguity, i.e., when C [·1 , ·2 ] = C [·1 ] | C [·2 ] then C [ P , Q ] = C [ P ] | C [ Q ]. Note that there is no case for the name restriction construct (ν a), which allows to single out specific names and avoid unintended name capture. Remaining cases specify holes can occur in parallel composition and underneath the authorization scope, the only other contexts underneath which processes are deemed active. We omit the symmetric cases for parallel composition since contexts are used up to structural congruence. Operator drift plays a double role: on the one hand, it is defined only when the hole/holes is/are under the scope of the appropriate number of authorizations in the context; on the other hand, when defined, it yields a context obtained from the original one by removing specific authorizations (so as to capture confinement). In our model, the specific authorizations that are removed for the sake of confinement are the ones nearest to the occurrence of the hole for the purpose of fairness. Drift for contexts with one hole. Operator drift for contexts with one hole is defined inductively on the structure of contexts by the rules prefixed with c- shown in Table 4. For the one hole case,
drift(C [·]; ρ ; ρ ) takes a context and multisets of names ρ and ρ , in which the same name can appear more than once. The first multiset carries the names of authorizations that are to be removed and the second carries the names of authorizations that have already been removed. We briefly comment on the rules shown in Table 4, reading from conclusion to premises. – Rule (c-end) is defined only if the first mulitiset is empty. This implies that the operator is defined only when all authorizations from the first multiset are actually removed from the context up to the point the hole is reached. – Rule (c-rem), where the authorization is removed from the context, specifies that the name is passed from the “to be removed” multiset to the “has been removed” multiset, where we use ρ {a} (or simply ρ a) to represent the addition operation for multisets which sums the frequencies of the elements, also used to single-out an occurrence as usual. – Rule (c-skip), where the authorization is preserved in the context, serves to check if the name is not in the second multiset, hence only authorizations that were not already removed proceeding towards the hole can be preserved, ensuring that the removed authorizations are the ones nearest to the hole. For example, drift((a) · ; ∅; {a}) is undefined since neither rule (c-rem) can be applied (a is not in the multiset of names that are to be removed) nor rule (c-skip) can be applied (a is in the multiset of names that have already been removed by the operator).
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
145
Table 4 drift rules.
(c-end) drift( · ; ∅; ρ ) = ·
(c-rem) drift(C [·]; ρ ; ρ {a}) = C [·] drift((a)C [·]; ρ {a} ; ρ ) = C [·]
(c-par) drift(C [·]; ρ ; ρ ) = C [·] drift(C [·] | R ; ρ ; ρ ) = C [·] | R
(c-skip) drift(C [·]; ρ ; ρ ) = C [·] a ∈ / ρ drift((a)C [·]; ρ ; ρ ) = (a)C [·]
(c2-spl) drift(C1 [·1 ]; ρ1 ; ρ1 ) = C1 [·] drift(C2 [·2 ]; ρ2 ; ρ2 ) = C2 [·] drift(C1 [·1 ] | C2 [·2 ]; ρ1 ; ρ2 ; ρ1 ; ρ2 ) = C1 [·1 ] | C2 [·2 ]
(c2-rem-l) drift(C [·1 , ·2 ]; ρ1 ; ρ2 ; ρ1 {a}; ρ2 ) = C [·1 , ·2 ]
drift((a)C [·1 , ·2 ]; ρ1 {a}; ρ2 ; ρ1 ; ρ2 ) = C [·1 , ·2 ]
(c2-skip) drift(C [·1 , ·2 ]; ρ1 ; ρ2 ; ρ1 ; ρ2 ) = C [·1 , ·2 ] a ∈ / ρ1 ρ2 drift((a)C [·1 , ·2 ]; ρ1 ; ρ2 ; ρ1 ; ρ2 ) = (a)C [·1 , ·2 ]
(c2-rem-r) drift(C [·1 , ·2 ]; ρ1 ; ρ2 ; ρ1 ; ρ2 {a}) = C [·1 , ·2 ]
drift((a)C [·1 , ·2 ]; ρ1 ; ρ2 {a}; ρ1 ; ρ2 ) = C [·1 , ·2 ]
(c2-par) drift(C [·1 , ·2 ]; ρ1 ; ρ2 ; ρ1 ; ρ2 ) = C [·1 , ·2 ]
drift(C [·1 , ·2 ] | R ; ρ1 ; ρ2 ; ρ1 ; ρ2 ) = C [·1 , ·2 ] | R
– Rule (c-par) for parallel composition is straightforward. Note that when defining the operator for some context C [·] and some multiset of names context, no authorizations have been removed and the respective multiset ρ is empty.
ρ that are to be removed from the
Example 5 (drift for contexts with one hole). We next show possible applications of the drift operator for some simple examples.
drift((a) · ; a; ∅) = · drift((a)((a) · | R ); a; ∅) = (a)( · | R ) drift( · ; a; ∅) is undefined drift((a)(a) · ; a, a; ∅) = · drift((a) · ; a, b; ∅) is undefined drift((a) · | (b)0; a, b; ∅) is undefined. Example 6 (drift derivation). We next illustrate the derivation for the second example above, i.e.,
drift((a)((a) · | R ); a; ∅) = (a)( · | R ), so as to provide further intuition on the definition of drift. Starting from the top of the derivation, we may observe that (the only) axiom (c-end) says that any derivation using the rules in Table 4 is defined only if the first multiset is empty at the root. We may also notice that the result of adding the two (parameter) multisets is preserved invariant in the rules. Hence, necessarily the derivation for the example above is rooted by drift (·; ∅; a) = · by axiom (c-end). We then consider the authorization (a) that directly scopes the hole, and by (c-rem) we derive
drift( · ; ∅; a) = · drift((a) · ; a; ∅) = · Notice that since a is in the second multiset, rule (c-skip) could not be applied instead. Then, by (c-par) we get
drift((a) · ; a; ∅) = · drift((a) · | R ; a; ∅) = · | R We may then conclude by (c-skip) that
drift((a) · | R ; a; ∅) = · | R drift((a)((a) · | R ); a; ∅) = (a)( · | R ) which completes the derivation. Notice that (starting from the bottom of the derivation) we could try to rely on (c-rem) to conclude drift((a)((a) · | R ); a; ∅) = C [·], for some C . This would mean proceeding by moving a from the first to the second list and deriving drift((a) · | R ; ∅; a) = C [·], for some C , which is not possible since neither (c-rem) nor (c-skip) can be applied for the authorization that directly scopes the hole (because the first multiset is already empty and the second multiset already contains a, respectively).
146
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Table 5 Reduction rules.
(r-comm) drift(C [·1 , ·2 ]; a; a) = C [·1 , ·2 ]
(r-auth) drift(C [·1 , ·2 ]; a, b; a) = C [·1 , ·2 ]
C [a!b. P , a?x. Q ] → C [(a) P , (a) Q {b/x}]
C [ab. P , a(b). Q ] → C [(a) P , (a)(b) Q )]
(r-stru) P ≡ P → Q ≡ Q P→Q
(r-newc) P→Q (ν a) P → (ν a) Q
Consider that the only derivations we are interested in specify in the conclusion that the second multiset is empty and in the root that the first multiset is empty. Hence, all the names are transferred from the first to the second multiset, between conclusion and axiom, by means of rule (c-rem). Furthermore, usages of rule (c-rem), for a given name, are necessarily above in the derivation tree with respect to usages of rule (c-skip), since in the former the derivation proceeds upwards considering the name is in the second multiset and the latter cannot be applied in that case. Drift for contexts with two holes. Operator drift for contexts with two holes is defined inductively on the structure of contexts by the rules prefixed with c2- shown in Table 4. Similarly as in the case of contexts with one hole,
drift(C [·1 , ·2 ]; ρ1 ; ρ2 ; ρ1 ; ρ2 ) takes a context with two holes, two multisets of names ρ1 and ρ2 representing the names of authorizations which are to be removed and two multisets of names ρ1 and ρ2 representing names of authorizations already removed. Multisets ρ1 and ρ1 refer to the ·1 hole while ρ2 and ρ2 refer to the ·2 hole. Rule (c2-spl) describes the case for two contexts with one hole each, in which case the respective operator is used to obtain the resulting context, considering the multisets of names ρ1 and ρ1 for the context on the left hand side and ρ2 and ρ2 for the context on the right hand side. The remaining rules follow exactly the same lines of the ones for contexts with one hole, where authorization removal addresses left and right hole in a dedicated way. Example 7 (drift for contexts with two holes). We show possible applications of the drift operator for some simple examples of contexts with two holes and suitable pairs of multisets.
drift((b)(a)(a)( ·1 | ·2 ); a, b; a; ∅; ∅) = ·1 | ·2 drift((b)(a)( ·1 | (a) ·2 ); a, b; a; ∅; ∅) = ·1 | ·2 drift((a)(a) ·1 | (a) ·2 ; a, a; a; ∅; ∅) = ·1 | ·2 drift((b)(a)( ·1 | ·2 ); a, b; a; ∅; ∅) is undefined. drift((a) ·1 | (a)(b) ·2 ; a, b; a; ∅; ∅) is undefined. drift((b)( ·1 | (a)(a) ·2 ); a, b; a; ∅; ∅) is undefined. The derivation for the case of two holes relies on the derivations for the cases of one hole and is possible only if the axioms for empty contexts hold. Thus, the operator is undefined if the proper authorizations are lacking. As before, multisets ρ1 and ρ2 are used only internally by the operator. Therefore, we abbreviate drift(C [·]; ρ ; ∅) with drift(C [·]; ρ ) and drift(C [·1 , ·2 ]; ρ1 ; ρ2 ; ∅; ∅) with drift(C [·1 , ·2 ]; ρ1 ; ρ2 ). Reduction rules. We may now present the reduction rules, shown in Table 5. – Rule (r-comm) states that two processes can synchronize on name a, passing name b from emitter to receiver, only if both processes are under the scope of, at least one per each process, authorizations for name a. The yielded process considers the context where the two authorizations have been removed by the drift operator, and specifies the confined authorizations for a which scope only over the continuations of the communication prefixes P and Q . – Rule (r-auth), analogously to (r-comm), states that two process can exchange authorization (b) on a name a only if the first process is under the scope of authorization b and if both processes are authorized to perform an action on name a. As before, the yielded process considers the context where the authorizations have been removed by the drift operator. The authorization for b is removed for the delegating process and confined to the receiving process so as to model the exchange. – Rule (r-stru) closes reduction under structural congruence. – Rule (r-newc) closes reduction under the restriction construct (ν a). Note there are no rules that close reduction under parallel composition and authorization scoping, as these constructs are already addressed by the contexts in (r-comm) and (r-auth). There is also no rule dedicated to replicated input since, thanks to structural congruence rule (sc-rep), a single copy of replicated process may be distinguished and take a part in a synchronization captured by (r-comm).
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
147
Remark 1 (On adding choice). We believe non-deterministic (external) choice can be added to our development following standard lines. For simplicity, we chose not to include such an operator for starters, in particular considering that the interplay between choice and authorization scope is the same with respect to the one between communication prefixes and authorization scope (i.e., that a summation is authorized in the same way a prefix is in this work, and that the evolution triggered by one of the summation branches involves the confinement as defined here for the prefix). The key relation that is addressed in this work in a central way is the one between parallel composition and authorization scope, so as to capture the desired notion of accounting. Remark 2 (On general replication). As mentioned previously, we may represent a general form of replication, that we may abbreviate with ! P , as
(ν a)((a)( P | a!a.0) | !(a)a?x.( P | a!a.0)) where a ∈ / fn( P ), since in one step it reduces to
P | (ν a)((a)( P | a!a.0) | !(a)a?x.( P | a!a.0)) where both a copy of P and the original process are active. Notice that the usage of name a is controlled, and that the process (a)( P | a!a.0) does not require any further authorizations on a. Authorization error. Synchronizations in our model are tightly coupled with the notion of authorization, in the sense that in the absence of the proper authorizations the synchronizations cannot take place. We characterize such undesired configurations, referred to as error processes, by identifying the redexes singled-out in the reduction semantics which are stuck due to the lack of the necessary authorizations. This is the case when the premise of the reduction rules does not hold, hence when the drift operator is not defined. Definition 3 (Error). Process P is an error if P ≡ (ν c˜ )C [αa . Q , αa . R ] and 1. 2.
αa = a!b, αa = a?x and drift(C [·1 , ·2 ]; a; a) is undefined, or αa = ab, αa = a(b) and drift(C [·1 , ·2 ]; a, b; a) is undefined.
Notice that the definition is aligned with that of reduction, where structural congruence is used to identify a configuration that directly matches one of the redexes given for reduction, but where the respective application of drift is undefined. We remark that error processes can be alternatively characterized as processes that exhibit a certain form of τω transitions, namely when ω is different from (a)0 (b)0 . This is formalized in the following result. τω
Proposition 1 (Error transitions). Process P is an error iff P −→ Q for some Q and τω = τ . Proof. Follows by auxiliary results (see Appendix A).
2
We adopt Definition 3 since we rely on reduction for the purpose of our typing analysis, which is nevertheless equated with the LTS in the following result. Harmony result. We may show that (fully authorized)
τ transitions match reductions.
τ
Theorem 1 (Harmony). P → Q if and only if P − →≡ Q . Proof. The proof of the ⇒ direction follows by induction on the derivation P → Q , and the ⇐ direction by induction on τ
the derivation of P − → Q (see Appendix A).
2
Both presentations of the semantics inform differently on our model. On the one hand, the labeled transition system is more explicit in what concerns authorization manipulation; on the other hand, the reduction semantics identifies the pairs of processes that may synchronize, and is therefore useful to identify communication errors in a direct way and more amenable to use in the proofs of our typing results. Comparing with the previous works for authorizations, we remark that reduction semantics of [15] requires less technical machinery, or at least relies on a more standard one. In the other direction, we may argue that the LTS of [15] is more complex than the one presented in this section. Our definition of reduction involves non-standard technical machinery so as to cope with the notion of accounting we explore here. This is further characterized by the technical insights in Section 3 that lead us to think we cannot state a standard normal form result (in contrast with [15]).
148
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
3. Behavioral semantics In this section, we present a preliminary investigation of the behavioral semantics of our model, relying on the observational equivalence induced by the labeled transition system introduced in the previous section. Intuitively, the relation defined next, dubbed strong bisimulation, identifies processes that exhibit the same behavior, i.e., where each (observable) action of one process can be reproduced by the other process, and vice versa, leading again to equivalent processes. Definition 4 (Strong bisimulation). A binary relation R is a strong bisimulation on processes if R is a symmetric relation and for all ( P , Q ) ∈ R the following holds: α → P , for some If P −
α
α and P where bn(α ) ∩ fn( Q ) = ∅, then Q − → Q for some Q such that ( P , Q ) ∈ R.
The relation we are interested in to capture the behavioral semantics is the largest strong bisimulation, i.e., the one that contains all strong bisimulations. We may show that the union of all strong bisimulations is a strong bisimulation. Hence, the definition of the largest strong bisimulation follows directly from the previous observation. Definition 5 (Strong bisimilarity). Strong bisimilarity, noted with ∼, is the union of all strong bisimulations. Strong bisimilarity is reflexive (immediate from the definition) and symmetric (since it is a strong bisimulation), and transitivity, up to α -equivalence, may be showed in expected lines. Therefore we may prove that strong bisimilarity is an equivalence relation. We may also inform on the relation between structural congruence and strong bisimilarity. Proposition 2 (Strong bisimilarity includes structural congruence). ≡ ⊆ ∼. Proof. The proof proceeds by coinduction on the definition of strong bisimulation (see Appendix B).
2
Proposition 2 can be seen as a sanity check for our reduction semantics since it shows that processes that are structurally congruent indeed exhibit the same behavior. For a further sanity check we may show that strong bisimilarity is preserved under context closure, considering a universal instantiation principle for input. Theorem 2 (Congruence). Let P , Q and R be arbitrary processes, and a, b arbitrary names. Then the following equalities hold. 1. 2. 3. 4. 5. 6. 7. 8.
If If If If If If If If
P ∼ Q then P | R ∼ Q | R. P ∼ Q then (ν a) P ∼ (ν a) Q . P ∼ Q then a!b. P ∼ a!b. Q . P {b/x} ∼ Q {b/x}, for all b, then a?x. P ∼ a?x. Q . P {b/x} ∼ Q {b/x}, for all b, then !(a)a?x. P ∼!(a)a?x. Q . P ∼ Q then (a) P ∼ (a) Q . P ∼ Q then ab. P ∼ ab. Q . P ∼ Q then a(b). P ∼ a(b). Q .
Proof. The proof is by coinduction on the definition of strong bisimulation (see Appendix B).
2
Theorem 2 says that if two bisimilar processes are placed in the same language context then the obtained processes are also bisimilar. Hence, we may say that each language construct is a proper function of behavior, as their composition with equivalent (object) behaviors yields equivalent (image) behaviors. We may use strong bisimilarity relation to formally state some principles that we previously intuitively described, namely, that the relation between authorization scope construct and parallel composition, where by P Q we represent that P and Q are not bisimilar. Proposition 3 (Behavioral inequalities). For each of the next inequalities there exist processes P and Q and name a that witness them. 1. 2. 3. 4. 5.
(a)( P | Q ) (a) P | (a) Q . (a)(a)( P | Q ) (a) P | (a) Q . (a)( P | Q ) P | (a) Q if a ∈ / fn( P ). (a)(a) P (a) P . (a) P P if a ∈ / fn( P ).
Proof. We show the inequalities by presenting the appropriate witnesses (see Appendix B).
2
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
149
In Proposition 3, statements 1. and 3. provide formal evidence of the unsoundness of the structural congruence laws mentioned previously (see Section 2.2) that relate authorization scoping and parallel composition constructs. No matter whether authorization scoping over parallel composition is distributed to both branches or to a single one (even if the name does not appear in one of the branches), the resulting process can exhibit a different behavior. Notice that 3. directly entails (a)( P | Q ) P | (a) Q , together when a ∈ fn( P ) in which case we can find witnesses in a more direct way. In 2. we see that even in the presence of two authorizations, the symmetric distribution over parallel composition may affect the behavior of the process. Statement 4. provides formal evidence of our accounting authorizations principle, since a process that has a different number of the same authorization may exhibit different behavior consequently. The last one reflects the fact that the authorization scoping construct is a non-binder, hence authorizations for names not free in the process may eventually be used (as a result of name passing). Notice that the statement 1. attests the main difference with respect to operational semantics of the process calculus in [15], where (a)( P | Q ) ∼ (a) P | (a) Q . Statement 3. shows the difference with respect to the operator (ν a), which obeys the scope extrusion rule. We can also show some behavioral equations that inform on the relation between authorization scoping and active prefixes. Proposition 4 (Behavioral (in)equalities). 1. 2. 3. 4. 5.
For any process P , names a, b and prefix αb such that b = a and αb = ba we have that (a)αb . P ∼ αb .(a) P . There exist process P , name a and prefixes αb , αc , where a does not occur, such that (a)αb .αc . P αb .αc .(a) P . For any process P , name a and prefix αb such that αb = aa, we have that (a)(a)αb . P ∼ (a)αb .(a) P . For any process P and name a we have that (a)(a)(a)aa. P ∼ (a)(a)aa.(a) P . For any process P , names a, b, c 1 , . . . , cn we have that (c 1 ) . . . (cn )(a)(b)ab. P ∼ (a)(b)ab.(c 1 ) . . . (cn ) P .
Proof. Follows by coinduction on the definition of strong bisimulation and for the second statement by presenting the appropriate witnesses (see Appendix B). 2 Statements 1., 3. and 4. identify principles useful towards a (semantic) normal form characterization of action prefixed processes. Namely, that authorization scoping can be pushed and pulled across the active prefixes leaving at most one authorization, except in the case of authorization delegation (e.g., case 4.), where two are needed. Considering also 2. we may conclude that authorizations can only be pushed across the immediately active prefix (even for arbitrary prefixes that do not mention the name for which the authorization is provided). These results are then generalized in 5., which says that when the required authorizations are present, all others can be pushed across. Overall, the presented inequalities hint that characterizing processes in our model by means of a normal form following usual lines does not seem possible to obtain, in particular, due to the inability of rewriting authorization scoping specifications. Even though the equalities shown in Proposition 4 provide us with some ability to manipulate authorizations over active prefixes, the inequalities given in Proposition 3 inform on the difficulty in manipulating authorization scoping over parallel composition. 4. Type system In this section, we present a type discipline that allows to statically identify safe processes, hence that do not exhibit unauthorized actions (cf. Definition 3). As mentioned before, our typing analysis addresses configurations where authorizations can be granted contextually. Before presenting the type language, we introduce auxiliary notions that cope with name generation, namely symbol annotations and well-formedness. Since the process model includes name restrictions and types contain name identities, we require a symbolic handling of bound names when they are included in type specifications. Without loss of generality, we refine the process model for the purpose of the type analysis adding an explicit symbolic representation of name restrictions. In this way, we avoid a more involved handling of bound names in typing environments. Formally, we introduce a countable set of symbols S ranged over by r, s, t, . . . , disjoint with the set of names N , and symbol κ not in N ∪ S . Also, in order to introduce a unique association of restricted names and symbols, we refine the syntax of the name creation construct (ν a) P in two possible ways, namely
(ν a : r) P
and
(ν a : κ ) P
decorated with symbol from S or with symbol κ , respectively. We use sym( P ) to denote a set of all symbols from S in process P . Names associated with symbols from S may be provided contextual authorizations, while names associated with symbol κ may not. For the purpose of this section we adopt the reduction semantics, adapted here considering refined definitions of structural congruence and reduction. In particular for structural congruence, we omit axiom (sc-res-inact) (ν a)0 ≡ 0 and we decorate name restriction accordingly in rules (sc-res-swap), (sc-res-extr) and (sc-scope-auth)—e.g., P | (ν a : r) Q ≡ (ν a : r)( P | Q )
150
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Table 6 Typing rules.
(t-stop) ρ 0
(t-par) ρ1 P 1 ρ2 P 2 sym( P 1 ) ∩ sym( P 2 ) = ∅ ρ1 ρ2 P 1 | P 2
(t-new) , a : {a}( T ) ρ P
(t-auth) ρ {a} P ρ (a) P
= {r/a} r ∈ / sym( P ) a ∈ / ρ , names( T ) ρ (ν a : r) P
(t-new-rep) , a : κ ( T ) ρ P a ∈ / ρ , names( T , ) ρ (ν a : κ ) P
(t-out) ρ P (a) = γ (γ ( T )) (b) = γ ( T ) γ ⊆ γ a ∈ /ρ ⇒γ ⊆ρ ρ a!b. P
(t-in) , x : T ρ P
(a) = γ ( T ) x ∈ / ρ , names() a ∈ /ρ ⇒γ ⊆ρ ρ a?x. P
(t-rep-in) , x : T {a} P
(a) = γ ( T ) x ∈ / ρ , names() sym( P ) = ∅ ρ !(a)a?x. P
(t-deleg) ρ P (a) = γ ( T ) a ∈ /ρ ⇒γ ⊆ρ ρ {b} ab. P
(t-recep) ρ {b} P
(a) = γ ( T ) a ∈ /ρ ⇒γ ⊆ρ ρ a(b). P
and P | (ν a : κ ) Q ≡ (ν a : κ )( P | Q ) keeping the condition a ∈ / fn( P ). We remark that the omission of (sc-res-inact) is used in process models where name restriction is decorated with typing information (cf. [1]). The annotations with symbols from S allow to yield a unique identification of the respective restricted names. Definition 6 (Well-formedness). A process is well-formed if it has unique occurrences of symbols from S , and no occurrences of symbols from S in the body of replicated inputs. We may show that well-formedness is preserved under (adapted) structural congruence and reduction (see Appendix C), and that typable processes are well-formed (see Proposition 5). Type language. We may now introduce the type language, whose syntax is given by
γ ::= ϕ | κ
and
T ::= γ ( T ) | ∅
where ϕ ⊂ N ∪ S . Types inform on safe instantiations of names that are subject to contextual authorizations, when γ is a set of names from N and of symbols from S (denoted ϕ ), and when names are not subject to contextual authorizations (κ ). In γ ( T ) type T characterizes the names that can be communicated in the channel, and type ∅ represents names that cannot be used for communication. A typing environment is a set of typing assumptions of the form a : T . We denote by names( T ) the set of names that occur in T and by names() the set of names that occur in all entries of . Typing rules. The type system is defined by the rules given in Table 6. A typing judgment ρ P states that P uses channels as prescribed by and that P can only be placed in contexts that provide the authorizations given in ρ , which is a multiset of names (from N ). The use of a multiset can be motivated by considering process a!b.0 | a?x.0 that can be typed as a : {a}({b}(∅)), b : {b}(∅) ρ a!b.0 | a?x.0 where necessarily ρ contains {a, a} specifying that the process can only be placed in contexts that offer two authorizations on name a (one is required per communicating prefix). We briefly discuss the typing rules. – Rule (t-stop) says that the inactive process is typable using any and ρ . – Rule (t-par) states that if processes P 1 and P 2 are typed under the same environment , then P 1 | P 2 is typed under as well. Also if P 1 and P 2 own enough authorizations when contexts provide authorizations ρ1 and ρ2 , respectively, then P 1 | P 2 will have enough authorizations when the context provides the sum of authorizations from ρ1 and ρ2 . The condition sym( P 1 ) ∩ sym( P 2 ) = ∅ is necessary to ensure well-formedness. – Rule (t-auth) says that (a) P and P are typed under the same environment , due to the fact that scoping is a nonbinding construct. If P owns enough authorizations when the context provides ρ {a}, then (a) P can be safely placed in a context that provides ρ . – Rule (t-new) states that if P is typable under an environment that contains an entry for a, then (ν a : r) P is typed under the environment removing the entry for a and where each occurrence of name a in is substituted by the symbol r.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
–
–
–
–
151
By {r/a} we denote the environment obtained by replacing occurrences of a by r in every assumption in , hence in every type, excluding when a has an entry in . Condition r ∈ / sym( P ) is necessary to ensure well-formedness and a∈ / ρ , names( T ) says that the context cannot provide authorization for name a and ensures consistency of the typing assumption. In rule (t-new-rep) the difference with respect to rule (t-new) is that no substitution is performed, since the environment must already refer to symbol κ in whatever pertains to the restricted name. For example to type process (ν b : κ )(a)a!b.0 the type of a must be γ (κ ( T )), for some γ and T , where κ identifies the names communicated in a are never subject to contextual authorizations. Rule (t-out) considers that P is typed under an environment where types of names a and b are such that all possible replacements for name b (specified in γ ) are safe to be communicated along name a (which is formalized by γ ⊆ γ , where γ is given in the type of a), and also that T (the carried type of b) matches the specification given for a. In such case, the process a!b. P is typed under the same environment. There are two possibilities to ensure name a is authorized, namely: the context may provide directly the authorization for name a (e.g., in (b)b?a.(a)a!c .0, hence, regardless of name replacements); or it may provide authorizations for all replacements of name a (e.g., assuming a can be instantiated only by d, processes (b)b?a.(d)a!c .0 and (b)(d)b?a.a!c .0 are safe, while (b)b?a.(e )a!c .0 and (b)(e )b?a.a!c .0 / ρ ⇒ γ ⊆ ρ . Notice this latter option is crucial to address contextual authorizations and that are not), formalized as a ∈ in such case γ does not contain symbols, since ρ by definition does not. Rule (t-in) is readable under the light of principles explained in the previous rule. Rule (t-rep-in) considers the continuation is typed with an assumption for the input bound name x and that the expected context provides authorizations only for name a. In such a case, the replicated input is typable considering the environment obtained by removing the entry for x, which must match the carried type of a, provided that x∈ / ρ , names() since it is bound to this process. Also, the fact that process P does not contain any symbol from S is necessary to ensure the unique association of symbols and names when copies of the replicated process are activated (see the discussion on example (6) in Section 4.1). In that case, process !(a)a?x. P can be placed in any context that conforms with and provides (any) ρ . We believe our approach can be extended to address restricted names that are subject to contextual authorizations in the context of infinite behavior, for instance considering generated symbols are not exposed in the communication interface (i.e., sym( P ) ∩ sym() = ∅ instead of sym( P ) = ∅). However, this would require further tuning of the process model to ensure uniqueness of symbols. Rules (t-deleg) and (t-recep) consider the typing environment is the same in premises and conclusion. The handling of the subject of the communication (a) is similar to, e.g., rule (t-out) and the way in which the authorization is addressed in rule (t-recep) follows the lines of rule (t-auth). In rule (t-deleg), the authorization for b is added to the ones expected from the context. Notice that in such way no contextual authorizations can be provided for delegation, but the generalization is direct.
We may notice that the symbolic representation of a bound name in the typing environment enables us to avoid the case when a restricted (unforgeable) name could be sent to a process that expects to provide a contextual authorization for the received name. For example, consider process (a)(d)a?x.x!c .0 | (ν b : r)(a)a!b.0 where a contextual authorization for d is specified, a configuration excluded by our type analysis since the assumption for the type of channel a carries a symbol (e.g., a : {a}({r}(∅))) for which no contextual authorizations can be provided. Notice that the typing of the process in the scope of the restriction uniformly handles the name, which leaves open the possibility of considering contextual authorizations for the name within the scope of the restriction. Results. For the sake of presenting the results, we introduce a notion of well-typed processes. Definition 7 (Well-typed processes). We say process P is well-typed if ∅ P and only contains assumptions of the form a : {a}( T ) or a : κ ( T ). At top level the typing assumptions address the free names of the process, which are not subject to instantiation. Free names are either characterized by a : {a}( T ) which says that a is the (final) instantiation, or by a : κ ( T ) which says that a cannot be granted contextual authorizations. For example, process (a)a!b.0 | (a)(b)a?x.x!c .0 is typable under the assumption that name b has type {b}({c }(∅)), while it is not typable under the assumption κ ({c }(∅)). The fact that no authorizations are provided by the context (ρ = ∅) means that the process P is self-sufficient in terms of authorizations. We may now present our results, starting by mentioning some fundamental properties. We may show (see Appendix C) that typing derivations enjoy standard properties (Weakening and Strengthening) and that typing is preserved under structural congruence (Subject Congruence). As usual, to prove typing is preserved under reduction we may also show an auxiliary result that addresses name substitution. Lemma 1 (Substitution). Let , x : γ ( T ) ρ P and x ∈ / names(). Then 1. If (a) = {a}( T ) and a ∈ γ then ρ {a/x} P {a/x}.
152
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
2. If (a) = κ ( T ) and κ = γ then ρ {a/x} P {a/x}. Proof. The proof is by induction on the depth of the derivation ρ P (see Appendix C).
2
Noticeably, even though subtyping is not present, the result uses an inclusion principle (a ∈ γ ) that already hints on substitutability. Our first main result says that typing is preserved under reduction. Theorem 3 (Subject reduction). If P is well-typed, ∅ P and P → Q then ∅ Q . Proof. The proof follows by induction on the derivation of P → Q (See Appendix C).
2
Not surprisingly, since errors involve redexes, the proof of Theorem 3 is intertwined with the proof of the error absence property, given in our second main result which captures the soundness of our typing analysis. Proposition 5 (Type soundness). 1. If ρ P then P is well-formed. 2. If P is well-typed then P is not an error. Proof. Immediate from auxiliary result (see Appendix C).
2
As usual, the combination of Theorem 3 and Proposition 5 yields type safety, stating that any configuration reachable from a well-typed one is not an error. Corollary 1 (Type safety). If P is well-typed and P →∗ Q then Q is not an error. Hence type safety ensures that well-typed processes will never incur in a configuration where the necessary authorizations to carry out the communications are lacking. 4.1. Illustrating typing principles by examples We extend the example shown in the Introduction to illustrate some of the typing principles:
(alice)alice!exam.0 | (exam)(minitest)(alice)alice?x.x!task.0
(3)
Considering assumption alice : {alice}({exam, minitest}({task}(∅))), and assuming that the type of exam is {exam}({task}(∅)), by rule (t-out) we conclude that it is safe to send name exam along alice, since the (only) instantiation of exam is contained in the carried type of alice. Now let us place process (3) in a context restricting exam:
(ν exam : r)((alice)alice!exam.0 | (exam)(minitest)(alice)alice?x.x!task.0)
(4)
To type this process, the assumption for alice specifies type {alice}({r, minitest}({task}(∅))), representing that in alice a restricted name can be communicated. Hence, the process shown in (4) cannot be composed with others that rely on contextual authorizations for names exchanged in alice, and can only be composed with processes like (alice)alice?x.(x)x!task or that use authorization delegation. Now consider process:
!(license)license?x.(ν exam : r)((x)x!exam.0 | (x)(exam)x? y . y !task.0)
(5)
that models a server that receives a name and afterwards is capable of both receiving (on the lhs) and sending (a fresh name, on the rhs) along the received name. Our typing analysis excludes this process since it specifies a symbol (r) in the body of a replicated input. In fact, the process may incur in an error, as receiving alice twice leads to:
(ν exam1 : r)((alice)alice!exam1 .0 | (exam1 )(alice)alice? y . y !task.0) | (ν exam2 : r)((alice)alice!exam2 .0 | (exam2 )(alice)alice? y . y !task.0)
(6)
where two copies of the replicated process are active in parallel, and where two different restricted names can be sent on alice, hence the error is reached when the contextual authorization does not match the received name (e.g., (exam2 )(alice)exam1 !task.0). In order to address name generation within replicated input, we use distinguished symbol κ that types channels that are never subject to contextual authorizations, even within the restriction scope. Hence replacing the r annotation by κ in the
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
153
process shown in (5) does not yield it typable, since a contextual authorization is expected for name exam and may lead to an error like before. However, process:
!(license)license?x.(ν exam : κ )(alice)alice!exam.0
(7)
is typable, hence may be composed with contexts compliant with alice : {alice}(κ ({task}(∅)), i.e., that do not rely on contextual authorizations for names received on alice. Notice that the carried type {task}(∅) is handled uniformly regardless of type κ , hence channels sent on alice may only be used to communicate task. Consider also the following infinite authorization generator:
!(public)public?x.((x)publicx.0 | (public)public!x.0) which allows for an unbounded number of authorizations to be available for a given (received) name via delegation on channel public. The generator composed in parallel with (public)public!comm.0 results in a process that may yield infinite copies of (public)(comm)publiccomm.0 thus allowing for channel comm to be available for anyone authorized to use public. The generator may be typed considering public : {public}(γ ( T )) and if comm ∈ γ we may also type the composition considering comm : {comm}( T ). 5. Towards a type checking procedure Our typing rules allow to single out processes that are not (and do not evolve to) errors, but the induced type-checking procedure leaves some open questions to what concerns applicability. In this section, we present a type system that addresses some of the issues and we prove correspondence of the typing analysis. First of all, “guessing” (inferring) the type of each bound name in rules (t-new) and (t-new-rep) is, at least for now, out of the scope of this work and we adopt the usual solution of adding the necessary type annotations to name restrictions. Hence, instead of (ν a : r) and (ν a : κ ) we write
(ν a : r( T )) and (ν a : κ ( T )), respectively. Secondly, also “guessing” the splitting of the multiset ρ in rule (t-par) so as to check the parallel branches raises questions of efficiency, and we address this problem by refining the typing rules. Our development follows similar lines to [23] where also a type-system and a refinement towards type-checking are presented. Intuitively, instead of splitting the multiset ρ in two, we verify the left branch considering the entire ρ . Then, after typing the left branch, we verify the right branch considering the part of ρ that was not used in the verification of the left branch. A first implementation of this idea is to consider the extension of the typing judgment ρ P to ρ P ; ρ , where ρ is a multiset of names that represents the “output” of the algorithm, i.e., ρ is part of ρ that is unused when verifying P . Now let us try to type-check process (a)((b)0 | P ). Since both authorizations (a) and (b) are scoping over the left branch and none of them are used by process 0, both names (a and b) would be part of the output when verifying 0 and passed to the verification of the right branch of the parallel composition (process P ), even though authorization (b) is not scoping over process P . To this end, we need to further refine the typing judgment to ; ρ1 : ρ2 P ; ρ , where ρ1 is a multiset of names of authorizations that are subject to be passed as unused, while names of authorizations in ρ2 cannot (leaving ρ as before). Considering again the same process (a)((b)0 | P ) we have that while type-checking process 0, name a is in ρ1 , while b is in ρ2 , hence the resulting ρ is a. We resort to a similar reasoning so as to verify the sets of symbols used in parallel branches are disjoint—see (t-par) . We further refine the typing judgment to
; ρ1 : ρ2 ; ξ P ; ρ ; ξ , where ξ is a set that incrementally collects all used symbols from S , and ξ represents the output of the algorithm, hence the set of symbols effectively used. When type-checking the parallel composition, we consider the set of symbols that have been discovered by the algorithm to that point in the verification of the left branch. Then, we consider the output set obtained in the verification of the left branch (which consists in the starting set of symbols together with the symbols used in the left branch) to verify the right branch, which result is also the one for the parallel composition process. Note that, compared to the typing discipline introduced in the previous section, there are no changes in interpretation of the typing environment (). The type-checking rules rely on an auxiliary operation that transfers names between multisets dubbed move, which we define next. We denote by move(ρ1 : ρ2 , b) the transfer (move of) name b from multiset ρ1 to multiset ρ2 , provided the name is not already contained in ρ2 in the first place, otherwise the operation is idempotent. The operation is defined only if the name is contained in the multisets, i.e., if b ∈ ρ1 ρ2 . Definition 8 (Operator move). Operator move takes as arguments a pair of multisets follows
move(ρ1 : ρ2 , b) = ρ1 \ ({b} \ ρ2 ) : ρ2 ({b} \ ρ2 ) if b ∈ ρ1 ρ2
ρ1 : ρ2 and a name b and is defined as
(undefined otherwise).
154
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Table 7 Type-checking rules.
(a-stop) ; ρ1 : ρ2 ; ξ 0; ρ1 ; ξ
(a-auth) ; ρ1 : ρ2 {a}; ξ P ; ρ ; ξ
; ρ1 : ρ2 ; ξ (a) P ; ρ ; ξ (a-par) ; ρ1 ρ2 : ∅; ξ P 1 ; ρ3 ; ξ ; ρ3 : ∅; ξ P 2 ; ρ4 ; ξ
; ρ1 : ρ2 ; ξ P 1 | P 2 ; ρ1 ∩ ρ4 ; ξ (a-new) , a : {a}( T ); ρ1 : ρ2 ; ξ ∪ r P ; ρ ; ξ = {r/a} r ∈ /ξ a∈ / ρ1 , ρ2 , names( T ) ; ρ1 : ρ2 ; ξ (ν a : r( T )) P ; ρ ; ξ (a-new-rep) , a : κ ( T ); ρ1 : ρ2 ; ξ P ; ρ ; ξ a ∈ / ρ1 , ρ2 , names( T , ) ; ρ1 : ρ2 ; ξ (ν a : κ ( T )) P ; ρ ; ξ (a-out-1) ; ρ1 : ρ2 ; ξ P ; ρ ; ξ (a) = γ (γ ( T )) (b) = γ ( T ) γ ⊆ γ
a ∈ ρ2 ∨ γ ⊆ ρ2
; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ
(a-out-2) ; ρ1 : ρ2 ; ξ P ; ρ ; ξ (a) = γ (γ ( T )) (b) = γ ( T ) γ ⊆ γ
a∈ / ρ2 ∧ γ ρ2
β =a∨β =γ
; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ
(a-in-1) , x : T ; ρ1 : ρ2 ; ξ P ; ρ ; ξ (a) = γ ( T ) x ∈ / ρ1 , ρ2 , names()
ρ1 : ρ2 = move(ρ1 : ρ2 , β)
a ∈ ρ2 ∨ γ ⊆ ρ 2
; ρ1 : ρ2 ; ξ a?x. P ; ρ ; ξ
(a-in-2) , x : T ; ρ1 : ρ2 ; ξ P ; ρ ; ξ (a) = γ ( T ) x ∈ / ρ1 , ρ2 , names()
a∈ / ρ2 ∧ γ ρ 2
β =a∨β =γ
; ρ1 : ρ2 ; ξ a?x. P ; ρ ; ξ
ρ1 : ρ2 = move(ρ1 : ρ2 , β)
(a-rep-in) , x : T ; ∅ : {a}; ∅ P ; ∅; ∅ (a) = γ ( T ) x ∈ / ρ1 , ρ2 , names() ; ρ1 : ρ2 ; ξ !(a)a?x. P ; ρ1 ; ξ (a-deleg-1) ; ρ1 : ρ2 ; ξ ρ P ; ρ ; ξ (a) = γ ( T ) ρ1 : (ρ2 {b}) = move(ρ1 : ρ2 , b)
a ∈ ρ2 ∨ γ ⊆ ρ2
; ρ1 : ρ2 ; ξ ab. P ; ρ ; ξ
(a-deleg-2) ; ρ1 : ρ2 ; ξ ρ P ; ρ ; ξ (a) = γ ( T ) ρ1 : (ρ2 {b}) = move(ρ1 : ρ2 , b)
a∈ / ρ2 ∧ γ ρ2
β =a∨β =γ
; ρ1 : ρ2 ; ξ ab. P ; ρ ; ξ
ρ1 : ρ2 = move(ρ1 : ρ2 , β)
(a-recep-1) ; ρ1 : ρ2 {b}; ξ P ; ρ ; ξ (a) = γ ( T ) a ∈ ρ2 ∨ γ ⊆ ρ2 ; ρ1 : ρ2 ; ξ ρ a(b). P ; ρ ; ξ (a-recep-2) ; ρ1 : ρ2 {b}; ξ P ; ρ ; ξ (a) = γ ( T ) a ∈ / ρ2 ∧ γ ρ2 β =a∨β =γ ; ρ1 : ρ2 ; ξ ρ a(b). P ; ρ ; ξ
ρ1 : ρ2 = move(ρ1 : ρ2 , β)
Operator move is directly generalized for the case of transferring a set of names γ , by transferring it name by name, namely if γ = b, γ then for arbitrary multisets ρ1 and ρ2 , we write move(ρ1 : ρ2 , γ ) = move(move(ρ1 : ρ2 , b), γ ). The type-checking rules are given in Table 7, briefly discussed next reading from conclusion to premises. – Rule (a-stop) specifies that multiset of names ρ1 and the set of symbols ξ are passed as the output (discarding ρ2 ). – In (a-auth) the authorization is scoping over process P , hence it is placed in multiset ρ2 since after type-checking the process P the authorization should not be considered as available outside of this scope. – Rule (a-par) is the most interesting rule and the that desired introduction of the mentioned refinements. Here, both multisets of names of authorizations (ρ1 and ρ2 ) that are scoping over the parallel composition are passed to the verification of the left branch (process P 1 ) as authorizations that can be passed (to the right branch), while the second multiset of names (regarding authorizations that refer exclusively to the left-branch) is empty. Likewise, the starting set of symbols ξ is also passed to process P 1 . The part of ρ1 ρ2 that is unused in the verification of process P 1 is given in ρ3 and is thus passed to the verification of the right branch (process P 2 ). Also, the set of symbols ξ , which is ξ enlarged with symbols from P 1 , is passed to the verification of P 2 . Finally, the output of the verification of the parallel composition consists in: a multiset of names determined by ρ1 ∩ ρ4 , hence those unused by both P 1 and P 2 obtained in the verification of the right branch (ρ4 ), which are originally specified as subject to be passed as unused for the parallel composition process (ρ1 ); the set of symbols ξ , which is ξ enlarged with symbols from P 1 and P 2 , is obtained by the result of the verification of the right branch. – Rules (a-new) and (a-new-rep), except for type annotations, comprise the novelty that in the former, the symbol r is registered in the set ξ as one of the used symbols.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
155
– Rule (a-out-1) covers the case when the names of authorizations required to perform the output, i.e., a or γ , are already contained in the multiset of names of authorizations that are considered as used (ρ2 ), hence no changes on multisets ρ1 and ρ2 are necessary. If the names of the authorizations required to perform the output are not contained in ρ2 , but contained in ρ1 ρ2 , rule (a-out-2) is applied. In this case, name a or (a subset of) names γ , originally contained in ρ1 \ ρ2 , must now be considered as used, and hence must be transferred from multiset ρ1 to multiset ρ2 by operator move (see Definition 8). Hence, in rule (a-out-2) for the case when β = a, the name is transferred from ρ1 to ρ2 , and for the case when β = γ , only names from γ that are in ρ1 but are not in ρ2 are transferred from ρ1 to ρ2 . – Rule (a-out-2) is non-deterministic when a and also (a subset) of γ are in ρ1 \ ρ2 , since when both options are available (move is defined in both cases) which one of them is actually transferred is left open (β = a ∨ β = γ ). Notice also this is only an issue when the two options are distinct (i.e., {a} = γ ), hence it is never an issue for names that are not subject to instantiation (e.g., typed with a : {a}( T )). Also the associated condition a ∈ / ρ ⇒ γ ∈ ρ in rule (t-out) of the original type system allows for the two options, the difference here is that we actually need to commit to one of them so as to respectively “mark” which names are used. For the purpose of the induced verification procedure, we need to check both possibilities in every application of the rule, up to the point the verification is successful or all options have been explored. – Rules (a-in-1) and (a-in-2) should be clear in the light of the explanations for (a-out-1) and (a-out-2). – Rule (a-rep-in) says that the process P is checked considering only one authorization (a) is provided. The input and the output set of symbols for P are both empty, reflecting that in P there are no symbols from S . The output of the original process then consists in the multiset of names ρ1 , that are initially considered for passing, and the starting set of symbols ξ . – Rules (a-deleg-1) and (a-deleg-2) check that the name of the delegated authorization is present in ρ1 or ρ2 by considering operator move, which moves the name from ρ1 to ρ2 if it was not already present in the former. The name of the authorization is then taken out from the last multiset, since the authorization is to be considered as no longer available (due to the delegation). Then, the rest of the conditions in the rules are applied in the same way as in (a-out-1) and (a-out-2). – Rules (a-recep-1) and (a-recep-2) also follow the same lines as (a-out-1) and (a-out-2), except that the name of the received authorization is added to the multiset of names that are not subject to be considered as unused, like in rule (a-auth) . Remark 3 (On the efficiency improvement). The type-checking procedure induced by the rules shown in Table 7 is more efficient than the one induced by the rules shown in the previous section, namely considering that rule (t-par) of Table 6 entails the exploration of all possible decompositions of ρ (hence a direct implementation is exponential on the size of ρ ). However, the rules in Table 7 still involve some exploration due to the premise β = a ∨ β = γ in rules (a-out-2), (a-in-2), (a-deleg-2) and (a-recep-2). For these rules, we would need to “guess” β when move is defined for both a and for γ , in the sense that both options must be explored in order to determine typability (instead if move is defined only in one case no further exploration is necessary). So we can only ensure a program is not typable if all such options have been explored, like for the decompositions of rule (t-par), and hence we can expect exponential complexity. Nevertheless the efficiency improvement can be informally justified as follows: consider that at most we have to consider the two options for β in the mentioned rules (1) once for each name in between applications of the rule for parallel composition, which (2) is strictly included in the decompositions of ρ . The former (1) is a consequence of relying on rule (a-out-1) when a choice has already been taken. The latter (2) is given directly by the decompositions of the set {a} ∪ γ which is necessarily contained in ρ . Thus, exploring the options for decomposing ρ is less efficient w.r.t. exploring the options for β . Furthermore, moving away from the worst case analysis, since we are only interested in well-typed processes (see Definition 7), we have that at top level all assumptions in are of the form a : a( T ) or a : κ ( T ) and also that rules (a-new) and (a-new-rep) only introduce such assumptions. We also have that typing prefixes with subject names with types of the form a : a( T ) or a : κ ( T ) do not involve such exploration (since β = γ = a in one case and in the other case κ is not a valid option). Hence, only when typing a prefix with a variable x as a subject may originate the exploration, and only in very specific cases. In particular, only when construct (x) and/or a(x) are present in addition to authorizations for all possible instantiations for x (given by the type), of which some are scoping over parallel composition(s). Consider also that even in the case when (x) and/or a(x) and authorizations for all instantiations for x are present, but none of these are scoping over a parallel composition, the operator move is idempotent so no exploration is necessary. Remark 4 (Towards a type-checking procedure). Perhaps more importantly with respect to the efficiency improvement discussed above, is that the rules of Table 7 pave the way for a polynomial type-checking procedure. A pragmatical (type-safe) interpretation for the issue mentioned above is to change the rules by specifying which is the only option to be considered regardless if both are available. We believe the impact on the expressiveness is marginal, but fails our purpose here to precisely capture the original type system. As an informal support for the expectable polynomial complexity consider the following: apart from premise β = a ∨ β = γ the rules of Table 7 are syntax-directed, where all elements in the premises are operationally obtained considering the elements in the conclusion and where rules are mutually exclusive. Notice that rules for prefixes have contrasting premises, e.g., a ∈ ρ2 ∨ γ ⊆ ρ2 in rule (a-in-1) and a ∈ / ρ2 ∧ γ ρ2 in rule (a-in-2). Furthermore, all operations (such as environment access and update, as well as (multi)set union, intersection and inclusion) may be implemented with polynomial complexity.
156
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
We now show that the type system introduced here for the purpose of type-checking is equivalent to the type system introduced in the previous section. Since the syntax is refined here by introducing full type specifications in the name restriction constructs, in the following result we use function erase( P ) that removes the extra annotations. Definition 9 (Erasing type annotations). Function erase is defined as a homomorphism except for
erase((ν a : r( T )) P ) = (ν a : r)erase( P ) and erase((ν a : κ ( T )) P ) = (ν a : κ )erase( P ) Theorem 4 (Typing correspondence). ρ erase( P ) if and only if ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , for any ρ1 , ρ2 and ξ such that ρ1 ρ2 = ρ and ξ \ ξ = sym( P ). Proof. The proof follows from the auxiliary results presented in Appendix D.
2
Notice that given and ρ and a type annotated process P we may rely on ; ∅ : ρ ; ∅ P ; ∅; sym( P ) so as to conclude ρ erase( P ), since, considering the notation used in the statement, we may take ρ1 = ∅ and ρ2 = ρ (for which we directly have ∅ ρ = ρ ) and ξ = ∅ (in which case ξ \ ∅ = sym( P )) and given that ρ ⊆ ρ1 (cf. Appendix D). Theorem 4 thus attests that the verification procedure induced by the type rules presented here perfectly captures the type system presented in the previous section, while yielding a more efficient implementation. We leave for future work a precise complexity analysis so as to characterize the efficiency improvement, and, perhaps more importantly, a precise characterization of the loss of expressiveness that results from the pragmatical (polynomial time) option. 6. Extended example In this section, we model a scenario inspired by the Bring Your Own License (BYOL) notion, so as to reinforce the intuition provided by the examples shown previously and to point to a relevant domain in practice. The BYOL concept has emerged in the development of cloud-based services which can be used for deploying and running applications, including database storage and other functionalities. The essence of BYOL is that it enables a user to deploy a software application in the cloud using the license owned by the user, hence involving a form of delegation of the existing license. Let us consider a scenario involving a Company that wishes to deploy a query service (for instance involving some intensive computation) in the cloud and to use a cloud-based database, e.g., Microsoft Azure SQL Database, which we abbreviate with SQL. Furthermore, the company may consider offers from different cloud service providers, such as, e.g., Amazon Web Service and IBM Cloud, which we dub AWS and IBM, respectively. Considering all processes run concurrently, the scenario may be modeled as
Company | AWS | IBM | SQL and the communication protocol of the cloud service providers may be represented as
AWS =!(aws)aws?service.aws(service).service!data.0 IBM =!(ibm)ibm?service.ibm(service).service!data.0 denoting that the providers are repeatably available to receive a service name, after which the respective authorization is received, allowing the provider to send some data along the same service name. We abstract here from the computation task itself, given that we focus exclusively on the communication pattern, so running the service amounts to sending the data. The company comprehends two managers that decide which service providers are to be used and two workers that interact with the providers, according to the managers decisions. Hence, we have
Company = (query)2 (ibm)2 (aws)2 (Manager | Manager | Worker | Worker) which specifies that the company owns authorizations to communicate with service providers IBM and AWS and with the database center SQL (via query). We use exponents to abbreviate that the company has two of such authorizations each. The managers take the decision of which service provider is to be used depending on some condition, e.g., quality of service (qos), and each decision is sent to a worker along channel choice. To model this process, we consider a simple extension of our language with a conditional statement “if then else”, and we write
Manager = (choice) if (qos) then choice!aws else choice!ibm.0 Each worker receives a name of the chosen service provider and replaces it for the placeholder csp, and then sends to the provider the name query and the authorization to use the channel
Worker = (choice)choice?csp.csp!query.cspquery.0
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
157
Notice that the authorization to use query is originally held by the Company, so in order to allow the provider to use query the Workers after sending the name query also send the respective authorization. Notice also that, since the Managers can choose any of the providers both aws and ibm can be used zero, one or two times, hence the need for the Company to hold two authorizations on each. The query is used exactly twice (one per each Worker). The cloud database is repeatably available to receive a query request, which we model with
SQL =!(query)query?x.0 To keep the example simple we abstract away from possible results and replies, since modeling them in a more accurate way requires ensuring isolation, for instance, by using dedicated (private) channels. Example transitions. Consider now possible transitions of the system. First, one of the Managers makes a decision on which service provider will be used and sends the name to one of the Workers. Consider the name sent is ibm, so assuming an extension of the LTS with rules to deal with the conditional statement in a usual way (the conditional may evolve, exhibiting a τ transition, to the then branch when the condition is true, and otherwise to the else branch) combined with LTS rules (l-out) and (l-scope-ext), we have the following transitions τ
choice!ibm
Manager − →−−−−−−→ (choice)0 One of the Workers may receive the decision, a behavior obtained by combining rules (l-in) and (l-scope-ext), choice?ibm
Worker −−−−−−→ Worker where Worker = (choice)ibm!query.ibmquery.0, so we may observe a synchronization at the level of parallel composition, as specified in rule (l-comm), and write τ
τ
Manager | Worker − →− → (choice)0 | Worker At this point, Worker may send the request to the provider, as expressed in rule (l-out), (ibm)ibm!query
Worker − −−−−−−−−→ Worker where Worker = (choice)(ibm)ibmquery.0. Notice that the action is pending an authorization for name ibm, that is confined to Worker as the result of the transition. The authorization “floating” at the level of company may authorize the action, hence,
(query)2 (ibm)2 (aws)2 (Manager | (choice)0 | Worker | Worker) ibm!query
−−−−−→ (query)2 (ibm)(aws)2 (Manager | (choice)0 | Worker | Worker) by rules (l-scope-ext), (l-par) and (l-scope). Process Worker can delegate the authorization, by means of rule (l-out-a), (query)ibmquery
Worker −−−−−−−−−−→ (choice)(ibm).0 At the level of Company, the action may be authorized, hence using the rules (l-par), (l-scope-ext) and (l-scope), we may derive
(query)2 (ibm)(aws)2 (Manager | (choice)0 | Worker | Worker) ibmquery
−−−−−−→ (query)(ibm)(aws)2 (Manager | (choice)0 | (choice)(ibm)0 | Worker) where one authorization for query is delegated, leaving the Company with one less authorization. The authorization may be received by process IBM, after receiving name query, i.e., using the rules (l-in-rep), (l-in-a), (l-scope-ext) and (l-par) we may derive ibm?query
ibm(query)
IBM −−−−−−→−−−−−−→ IBM , where IBM = IBM | (query)(ibm)query!data.0. After that, the service provider IBM may send the data to SQL.
158
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Type analysis illustration. We may now use our typing discipline to statically certify the absence of errors in the presented scenario, assuming an extension that addresses the conditional statement in a standard way: if both branches have the same type then the conditional has the type of a(ny) branch. Let us consider typing environment
= aws : {aws}( T ), ibm : {ibm}( T ), query : T , choice : {choice}({aws, ibm}( T )) where T = {query}({data}(∅)). We can check that
∅ Company | AWS | IBM | SQL, hence, the system is well-typed and will never get stuck on lacking authorizations. Let us show that
ρ Worker where
ρ = {query, ibm, aws}. Recall that Worker = (choice)choice?csp.csp!query.cspquery.0.
Since the inactive process may be typed under any assumptions by rule (t-stop) we may obtain
, csp : {aws, ibm}( T ) ρ1 0 where
ρ1 = {choice, ibm, aws}. By rule
(t-deleg), we may derive
, csp : {aws, ibm}( T ) ρ1 ,{query} cspquery.0 where we check that all replacements for csp are contained in ρ1 (hence if {aws, ibm} ⊆ {choice, ibm, aws}), which is enlarged in the conclusion with query (that is to be delegated). This way we make sure that, in order to authorize the delegation, the process must be placed in a context that will provide all the necessary authorizations. We may now apply rule (t-out) and conclude
, csp : {aws, ibm}( T ) ρ1 ,{query} csp!query.cspquery.0 where we again have the same check for csp (now considering ρ1 , {query}), and we also check that all possible replacements for query, which is only query itself, are contained in the carried type of csp, which holds since T = {query}({data}(∅)). Then, by (t-in) we may derive
ρ1 ,{query} choice?csp.csp!query.cspquery.0 where we check that choice is in we get
ρ1 , {query} and that the type of csp is equal to the carried type of choice. Finally, by (t-auth)
ρ Worker where ρ is obtained by removing choice from ρ1 , {query}, and registers the fact that each Worker is safe if placed in a context that provides authorizations for names query, ibm, and aws. Even though ibm and aws will not be both actually needed, given that any one of them can be received in choice, to ensure any possible evolution of the system is safe, the authorizations for both ibm and aws must be provided. 7. Towards programming language support for authorizations In this section, we discuss how our approach can be exploited in a practical setting, in particular considering the perspective of programming language extensions that embed the principles presented in this work. It is often the case that security concerns such as authorizations are handled separately with respect to the application layer. However, when such concerns are entangled with the application domain, it is not trivial in general to establish the correspondence between application requirements and security layer guarantees. For instance, consider when resource management is tightly coupled with the application logic (e.g., due to service contracts that are subject to optimization by the application business logic), where it seems natural to provide programming language (direct) support for the resource management. Under this view, we believe introducing programming language support for the notion of authorization presented in this work may be worthwhile in practice.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
159
package main import "fmt" func main() { choice := make(chan chan string) aws := make(chan string) ibm := make(chan string) // MANAGER go func() { auth(choice) // Language extension choice <- aws choice <- ibm }() auth(ibm) // Language extension auth(aws) // Language extension // WORKER 1 go func() { auth(choice) // Language extension csp := <-choice csp <- "worker1" }() // WORKER 2 go func() { auth(choice) // Language extension csp := <-choice csp <- "worker2" }() auth(aws) // Language extension msg1 := <-aws fmt.Println("aws", msg1) auth(ibm) // Language extension msg2 := <-ibm fmt.Println("ibm", msg2) }
Fig. 1. Example extended Go program.
For the sake of illustration, consider the code given in Fig. 1 where we extend a program written in Go with a construct
auth( ) that represents our authorization scoping construct (used in lines 12, 17, 18, 22, 29, 34, and 38, all distinguished with the comment // Language extension). The idea is to reproduce the structure of the Company process described in the previous section, where one manager thread sends to two worker threads the channel they can use to communicate. For simplicity, we only use anonymous goroutines for which the intended authorization scoping is given directly by the syntax. The program starts by creating three channels choice, aws, and ibm with the appropriate type declarations (lines 6-8), namely that choice carries messages of type chan string so as to capture that choice is used to communicate channel endpoints (which, in turn, are used to communicate strings), and that both aws and ibm are used to communicate strings. Then, a goroutine representing the manager thread is defined and directly invoked (lines 11-15) so as to spawn a thread that will run the code given in the body of the routine (lines 12-14). Namely, an authorization for using channel choice is created (line 12), after which channel endpoints first for aws (line 13) and then for ibm (line 14) are sent via channel choice. Notice that since both communications are carried out using channel choice the manager thread only requires the respective authorization. The main thread continues to the creation of authorizations for both aws and ibm (lines 17-18), and then proceeds to the definition and invocation of goroutines for the two worker threads (lines 21-25 and 28-32). The code for the workers specifies the creation of an authorization for channel choice (lines 22 and 29), after which the reception of a channel via channel choice (lines 23 and 30) and finally the emission of a text message on the received channel (lines 24 and 31). The remaining code for the main thread (lines 34-40) carries out the receptions of the text messages (considering the respective authorizations) and their onscreen display. Notice that on channel choice the workers receive the aws and ibm endpoints sent by the manger, hence the workers output the text messages (lines 24 and 31) on the aws and ibm channels. The idea here is that the authorizations created in the main thread (lines 17-18) are floating over both worker threads spawned by the goroutine invocation, so each one of
160
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
the authorizations can be confined to either one of the threads. Notice that each worker thread receives a different channel and which one is not prescribed by the code, so "worker1" can be sent on aws and "worker2" on ibm or the other way around. In both cases, the respective floating authorization can be confined to the thread at the moment it uses the channel, so the floating authorizations for the two channels suffice for both threads and hence we may say that the program is authorization safe. Now consider refinements of the resource management in the context of the simple example shown. If channel endpoints are subject to a strict accounting for instance according to an established service contract (e.g., with a third parties such as Amazon or IBM where the number of active channel endpoints may be specified), it is important to have language mechanisms that give direct support to abide to the service contract. On the one hand, the creation of the authorizations in lines 17-18 give a precise operational specification of the resources available. Notice that we could also reason on authorization reception replacing the creation in lines 17-18 so as to, for instance, rely on communications with the service provider to establish the authorizations. On the other hand, the flexibility provided by floating authorizations allows for the resources to be accessible among concurrent threads while keeping track of the resource control. Building on our typing analysis we can devise static verification techniques that ensure programs like the one shown never get stuck due to lacking authorizations. However, we remark that a direct application of our typing principles excludes the example discussed above, as the message type of channel choice would specify that both aws and ibm can be communicated, hence to ensure that both workers do not lack authorizations we would require two authorizations (instead of only one) for each aws and ibm. We conceive that our typing analysis can be extended so as to address this configuration and, moreover, that our language principles can already be used as the basis for runtime verification techniques that would allow to transparently run the example program. We also conceive that our language principles can be embedded in a programming language by means of a specialized API, instead of a proper extension, relying on the appropriate library calls for authorization creation and resource usage, up to some ingenuity for authorization scoping. We do retain the necessity of considering specialized language constructs for the sake of the dedicated theoretical investigation presented in this paper. 8. Concluding remarks In the literature, we find a plethora of techniques that address resource usage control, ranging from locks that guarantee mutual exclusion in critical code blocks to communication protocols (e.g., token ring). Several typing disciplines have been developed to ensure proper resource usage, such as [10,17,22], where capabilities are specified in the type language, not as a first class entity in the model. Therefore in such approaches it is not possible to separate resource and capability like we do, e.g., we may communicate a resource without granting the capabilities, that may be yielded separately, like in the “unauthorized” intermediaries (brokers) mentioned in the Introduction. We distinguish an approach that considers accounting [10], in the sense that the types specify the number of messages that may be exchanged, therefore related to the accounting presented here. We also find proposals of models that include capabilities as first class entities, addressing usage of channels and of resources as communication objects, such as [9,16,19,24]. More specifically, constructs for restricting (hiding and filtering) the behaviors allowed on channels [16,24], usage specification in a (binding) name scope construct [19], and authorization scopes for resources based on given access policies [9]. We distinguish our approach from [16,24] since the proposed constructs are static and are not able to capture our notion of a floating resource capability. As for [19], the usage specification directly embedded in the model resembles a type and is given in a binding scoping construct, which contrasts with our non-binding authorization scoping. Also in [9] the provided detailed usage policies are associated with the authorization scopes for resources. In both [9,19] the models seem less adequate to capture our notion of floating authorizations as access is granted explicitly and controlled via the usage/policy specification, and for instance, our notion of confinement does not seem to be directly representable. We also distinguish our approach from previous work [15] since the models capture different notions of authorization. Namely, the principle of authorization distribution captured by the equivalence (a)( P | Q ) ≡ (a) P | (a) Q is a key contrast, excluded here for the purpose of authorization accounting (cf. the discussion in the beginning of Section 2.2 and Proposition 3), while it is embedded in the structural congruence relation in [15]. Our particular notion of authorization, dubbed floating, may be used to model resource capabilities subject to bounded concurrent use (e.g., licenses), which cannot be represented in a direct way in the work presented in [15]. We also presented a preliminary investigation of the behavioral semantics of the model that reports on some fundamental properties and informs on the particular nature of authorizations in our model, on the one hand validating informal principles and, on the other hand, including insights on the difficulty of obtaining a normal form characterization of processes. We remark that adding choice can be carried out in expected lines. More interesting would be to consider non-consumptive authorizations, that return to their original scope after (complete) use. We introduced a typing analysis that addresses contextual authorizations, which we also believe is unexplored in other approaches in the form we present it here. Our typing rules induce a decidable type-checking procedure, since rules are syntax directed, provided as usual that a (carried) type annotation is added to name restrictions. Considering such annotations are present, we also present a refinement of our typing rules that induce a more efficient type-checking procedure. A notion of substitutability naturally arises in our typing analysis and we leave to future work a detailed investigation of a subtyping relation that captures such notion. We believe our approach can be extended by considering some form of usage
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
161
specifications like the ones mentioned above [9,19], by associating to each authorization scoping more precise capabilities in the form of behavioral types [18]. This would also allow us to generalize our approach addressing certain forms of infinite behavior, namely considering recursion together with linearity constraints that ensure race freedom. Another direction for generalizing our typing analysis, namely to address names created in the body of replicated input in a uniform way, is to consider the approach presented in [12] that supports the unique identification of private names also in the presence of replicated processes. It would also be interesting to resort to refinement types [13] to carry out our typing analysis, given that our types can be seen to some extent as refinements on the domain of names. Albeit the work presented here is clearly of a theoretical nature, we hope the principles developed here may be conveyed to, e.g., the licensing domain where we have identified related patents [3,6,11] for the purpose of certifying license usage. Another such direction for future work targets the recently introduced permissioned blockchain systems such as Hyperledger Fabric [2]. We believe it would be interesting to provide high-level descriptions and prove properties of the Membership Service Provider (MSP), the part of the Fabric system which is responsible for issuing node credentials (used for authorization and authentication). We intend to pursue this idea, starting by aiming at the formal verification of smart contracts (chaincode) in Fabric, exploiting recently introduced developments for smartcontracts [4,8] in the context of contract-oriented programming [7]. In particular, we have already identified notions of active contract [8], which encompasses a running balance, and of authorizations to perform operations, hence where we expect to also find the dimensions of domain, accounting and delegation. Declaration of Competing Interest There is no competing interest. Acknowledgements This work has been partially supported by the Ministry of Education and Science of the Republic of Serbia, project ON174026, and EU COST Action IC1405 (Reversible Computation). Appendix A. Proofs from Section 2 α
Lemma A.1 (Inversion on labeling). Let P − → Q. 1. 2. 3. 4. 5.
If α = (a)i a!b then a, b ∈ fn( P ). If α = (a)i (ν b)a!b then a ∈ fn( P ) and b ∈ bn( P ). If α = (a)i a?b then a ∈ fn( P ). If α = (a)i (b) j ab then a, b ∈ fn( P ). If α = (a)i a(b) then a, b ∈ fn( P ). α
Proof. The proof is by induction on the inference of P − → Q . We comment just the first and the second assertions. (a)a!b
1. The base case for P −−−→ Q is the rule (l-in), then P = a!b. Q and a, b ∈ fn( P ). We comment only the case when (a)a!b
(a)a!b
the last applied rule is (l-res): (ν c ) P −−−→ (ν c ) Q is derived from P −−−→ Q , where c ∈ / {a, b} and by the induction hypothesis a, b ∈ fn( P ), which implies a, b ∈ fn( P ) \ {c } = fn((ν c ) P ). The base case for (a)a!b derived from P −−−→ Q by (l-scope-ext). Then, by the first part of the proof a, b (a)i (ν b)a!b
a!b
α = a!b is when (a) P −−→ Q is
∈ fn( P ), thus a, b ∈ fn((a) P ). (a)i a!b
2. We only comment the base case: (ν b) P −−−−−−→ Q is derived from P −−−−→ Q , where a = b, by the rule (l-open), then from the first assertion of this Lemma we get a, b ∈ fn( P ). From this it directly follows a ∈ fn((ν b) P ) and b ∈ bn((ν b) P ). 2 α
α
Lemma A.2 (LTS closure under structural congruence). If P ≡ P and P − → Q , then there exists some Q such that P − → Q and Q ≡ Q . Proof. The proof is by induction on the length of the derivation of P ≡ P . We detail only the case when the last applied rule is (sc-res-extr) P 1 | (ν a) P 2 ≡ (ν a)( P 1 | P 2 ) if a ∈ / fn( P 1 ). We have two possible transitions for (ν a)( P 1 | P 2 ), by (l-res) and (l-open): α
α
• (l-res): Assume that (ν a)( P 1 | P 1 ) − → (ν a) R, where a ∈ / n(α ) is derived from ( P 1 | P 2 ) − → R. Then, possible transitions for P 1 | P 2 are: α α → P 1 | P 2 , where bn(α ) ∩ fn( P 1 ) = ∅ is derived from P 2 − → P 2 . Since a ∈ / n(α ), by (l-res) we get -(l-par): P 1 | P 2 − α
α
α
(ν a) P 2 − → (ν a) P 2 and by (l-par) P 1 | (ν a) P 2 − → P 1 | (ν a) P 2 . If P 1 | P 2 − → P 1 | P 2 , where bn(α ) ∩ fn( P 2 ) = ∅ is derived α
α from P 1 − → P 1 , then, since fn((ν a) P 2 ) ⊆ fn( P 2 ), by (l-par) we get P 1 | (ν a) P 2 − → P 1 | (ν a) P 2 .
162
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
α2
α1
α
-(l-comm): P 1 | P 2 − → P 1 | P 2 and α = τω , where ω = (b)i + j is derived from P 1 −→ P 1 and P 2 −→ P 2 , for α1 , α2 ∈ i j / fn( P 1 ) we get b = a. Then, we have two cases: {(b) b!c , (b) b?c }. By Lemma A.1 we get b ∈ fn( P 1 , P 2 ). Thus from a ∈ (b) (ν a)b!a τω * if c = a and α2 = (b)i b!a. Then, by (l-open) (ν a) P 2 −−−−−−→ P 2 and by (l-close) P 1 | (ν a) P 2 −→ (ν a)( P 1 | P 2 ); i
α2 τω * if c = a, then by (l-res) (ν a) P 2 −→ (ν a) P 2 and by (l-comm) P 1 | (ν a) P 2 −→ P 1 | (ν a) P 2 .
α2 α1 α → (ν c )( P 1 | P 2 ) and α = τω , where ω = (b)i + j is derived from P 1 −→ P 1 and P 2 −→ P 2 , for - (l-close): P 1 | P 2 − α1 , α2 ∈ {(b)i (ν c )b!c , (b) j b?c }. By Lemma A.1 we get b ∈ fn( P 1 , P 2 ) and c ∈ bn( P 1 , P 2 ). Since a ∈/ fn( P 1 ) and assumα2
τω
/ {b, c }. Thus, by (l-res) (ν a) P 2 −→ (ν a) P 2 and by (l-close) P 1 | (ν a) P 2 −→ ing all bound names are different, we get a ∈ (ν c )( P 1 | (ν a) P 2 ). α2
α1
α
- (l-auth): P 1 | P 2 − → P 1 | P 2 and α = τω , where ω = (b)i + j (c )k is derived from P 1 −→ P 1 and P 2 −→ P 2 , for i k α1 , α2 ∈ {(b) (c ) bc , (b) j b(c )}. By Lemma A.1 we get c , b ∈ fn( P 1 , P 2 ). Since a ∈/ fn( P 1 ) we get a ∈/ {b, c }. Thus, by (l-res)
α2
τω
(ν a) P 2 −→ (ν a) P 2 and by (l-auth) P 1 | (ν a) P 2 −→ P 1 | (ν a) P 2 . (b) (ν a)b!a
(b)i b!a
i
• (l-open): Assume that (ν a)( P 1 | P 2 ) −−−−−−→ R, is derived from P 1 | P 2 −−−−→ R, where a = b. Since a ∈ / fn( P 1 ) and by (b) b!a (b) b!a Lemma A.1 we get that P 1 | P 2 could be only derived using (l-par) P 1 | P 2 −−−−→ P 1 | P 2 from P 2 −−−−→ P 2 . By (l-open) i
(b)i (ν a)b!a
i
(b)i (ν a)b!a
(ν a) P 2 −−−−−−→ P 2 and by (l-par) we get P 1 | (ν a) P 2 −−−−−−→ P 1 | P 2 . 2 Lemma A.3 (Inversion on LTS). Let P and Q be processes. (a)a!b
1. If P −−−→ Q then P ≡ (ν d˜ )C [a!b. P ] and Q ≡ (ν d˜ )C [(a) P ] and drift(C [·]; a) is undefined; a!b
−→ Q then P ≡ (ν d˜ )C [a!b. P ] and Q ≡ (ν d˜ )C − [(a) P ], for C − [·] = drift(C [·]; a); 2. If P − (a)(ν b)a!b
3. If P −−−−−−→ Q then P ≡ (ν d˜ )(ν b)C [a!b. P ] and Q ≡ (ν d˜ )C [(a) P ] and drift(C [·]; a) is undefined; (ν b)a!b
4. If P −−−−→ Q then P ≡ (ν d˜ )(ν b)C [a!b. P ] and Q ≡ (ν d˜ )C − [(a) P ], for C − [·] = drift(C [·]; a); (a)a?b
5. If P − −−−→ Q then P ≡ (ν d˜ )C [a?x. P ] and Q ≡ (ν d˜ )C [(a) P {b/x}] and drift(C [·]; a) is undefined; 6. If P −−→ Q then P ≡ (ν d˜ )C [a?x. P ] and Q ≡ (ν d˜ )C − [(a) P {b/x}], for C − [·] = drift(C [·]; a); a?b
(b)ab
7. If P −−−−→ Q then P ≡ (ν d˜ )C [ab. P ] and Q ≡ (ν d˜ )C − [(a) P ], for C − [·] = drift(C [·]; a) and drift(C [·]; a, b) is undefined; (a)ab
8. If P −−−−→ Q then P ≡ (ν d˜ )C [ab. P ] and Q ≡ (ν d˜ )C − [(a) P ], for C − [·] = drift(C [·]; b) and drift(C [·]; a, b) is undefined; ab
9. If P −−→ Q then P ≡ (ν d˜ )C [ab. P ] and Q ≡ (ν d˜ )C − [(a) P ], for C − [·] = drift(C [·]; a, b); (a)a(b)
10. If P −−−−→ Q then P ≡ (ν d˜ )C [a(b). P ] and Q ≡ (ν d˜ )C [(a)(b) P ] and drift(C [·]; a) is undefined; a(b)
11. If P −−→ Q then P ≡ (ν d˜ )C [a(b). P ] and Q ≡ (ν d˜ )C − [(a)(b) P ], for C − [·] = drift(C [·]; a); τ
12. If P − → Q then either – P ≡ (ν d˜ )C [a!b. P , a?x. P ] and Q ≡ (ν d˜ )C − [(a) P , (a) P {b/x}], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; a), or – P ≡ (ν d˜ )C [ab. P , a(b). P ] and Q ≡ (ν d˜ )C − [(a) P , (a)(b) P ], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a, b; a); τ(a)
13. If P −−→ Q then either – P ≡ (ν d˜ )C [a!b. P , a?x. P ] and Q ≡ (ν d˜ )C − [(a) P , (a) P {b/x}], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; ∅), or C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; ∅; a), and drift(C [·1 , ·2 ]; a; a) is undefined, or – P ≡ (ν d˜ )C [ab. P , a(b). P ] and Q ≡ (ν d˜ )C − [(a) P , (a)(b) P ], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a, b; ∅), or C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; b; a), and drift(C [·1 , ·2 ]; a, b; a) is undefined, or – P ≡ (ν d˜ )C [ba. P , b(a). P ] and Q ≡ (ν d˜ )C − [(b) P , (b)(a) P ], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; b; b) and drift(C [·1 , ·2 ]; b, a; b) is undefined. τ(a)(a)
14. If P −−−→ Q then either – P ≡ (ν d˜ )C [a!b. P , a?x. P ] and Q ≡ (ν d˜ )C [(a) P , (a) P {b/x}] and drift(C [·1 , ·2 ]; a; a) is undefined, or – P ≡ (ν d˜ )C [ab. P , a(b). P ] and Q ≡ (ν d˜ )C − [(a) P , (a)(b) P ], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; b; ∅), and drift(C [·1 , ·2 ]; a,b; a) is undefined, or – P ≡ (ν d˜ )C [aa. P , a(a). P ] and Q ≡ (ν d˜ )C − [(a) P , (a)(a) P ], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; ∅; a) or C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; ∅), and drift(C [·1 , ·2 ]; a, a; a) is undefined. τ(a)(b)
15. If P −−−→ Q and a = b then P ≡ (ν d˜ )C [ab. P , a(b). P ] and Q ≡ (ν d˜ )C − [(a) P , (a)(b) P ], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; ∅) or C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; ∅; a), and drift(C [·1 , ·2 ]; a, b; a) is undefined. τ(a)2 (b)
16. If P −−−−→ Q then P ≡ (ν d˜ )C [ab. P , a(b). P ] and Q ≡ (ν d˜ )C [(a) P , (a)(b) P ] and drift(C [·1 , ·2 ]; a, b; a) is undefined. α
→ Q . We comment just the first two assertions. Proof. The proof is by induction on the inference of P −
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
163
(a)a!b
1. Suppose P −−−→ Q and let us show: P ≡ (ν d˜ )C [a!b. P ] and Q ≡ (ν d˜ )C [(a) P ] and drift(C [·]; a) is undefined. We (a)a!b
get the base case by rule (l-out) a!b P −−−→ (a) P . Here, a!b P = C [a!b P ] and (a) P = C [(a) P ], where C [·] = ·. The operator drift(C [·]; a) is undefined, since the second parameter of the operator is not an empty multiset. For induction steps we have next cases of the last applied rule: (l-res), (l-scope) and (l-par). If the last applied rule is (l-res), we immediately get (a)a!b
(a)a!b
the result from the induction hypothesis. If the last applied rule is (l-scope), we get P −−−→ Q from the (c ) P −−−→ (c ) Q , where c = a. By induction hypothesis P ≡ (ν d˜ )C [a!b. P ] and Q ≡ (ν d˜ )C [(a) P ] and drift(C [·]; a) is undefined. Considering all free and bound names are different, by (sc-scope-auth) we get (c ) P ≡ (ν d˜ )(c )C [a!b. P ] and (c ) Q ≡ (ν d˜ )(c )C [(a) P ]. For C [·] = (c )C [·] we get that (c ) P ≡ (ν d˜ )C [a!b. P ] and (c ) Q ≡ (ν d˜ )C [(a) P ] and drift(C [·]; a) is undefined since c = a. Case (l-par) we get by similar reasoning. a!b
(a)a!b
a!b
2. Consider now P − −→ Q . We get the base case by rule (l-scope-int): (a) P −−→ Q is derived from P −−−→ Q . By the first part of the proof we get P ≡ (ν d˜ )C [a!b. P ] and Q ≡ (ν d˜ )C [(a) P ] and drift(C [·]; a) is undefined. By Lemma A.1 we ˜ By (sc-scope-auth) we get (a) P ≡ (ν d˜ )(a)C [a!b. P ]. For C [·] = (a)C [·], we get drift(C [·]; a) = C [·], get a ∈ fn( P ), thus a ∈ / d. which implies Q ≡ (ν d˜ )C [(a) P ]. Again, for the inductions steps we have same possibilities for the last applied rule : (l-res), (l-scope) and (l-par), all three cases are similar as in the first part of the proof. 2 Lemma A.4. 1. If drift(C [·]; a) is undefined then (a)a!b
– C [a!b. P ] −−−→ C [ P ], and (a)a?b
– C [a?x. P ] − −−−→ C [ P {b/x}], and (a)a(b)
– C [a(b). P ] −−−−→ C [(a)(b) P ]. 2. If drift(C [·]; a, b) is undefined then either
(a)(b)ab
−−−−−→ C [(a) P ], or – drift(C [·]; a) is undefined and drift(C [·]; b) is undefined and C [ab. P ] − (a)ab
– drift(C [·]; a) is undefined and C [ab. P ] −−−−→ C − [(a) P ], where C − [·] = drift(C [·]; b), or (b)ab
– drift(C [·]; b) is undefined and C [ab. P ] −−−−→ C − [(a) P ], where C − [·] = drift(C [·]; a). Proof. The proof is by induction on the structure of C [·].
2
Lemma A.5. (i) If drift(C [·1 , ·2 ]; a; a) is undefined and drift(C [·1 , ·2 ]; a; ∅) is undefined and drift(C [·1 , ·2 ]; ∅; a) is undefined then τω
C [a!b. P , a?x. P ] −→ Q for some Q and ω = (a)(a). τω (ii) If drift(C [·1 , ·2 ]; a; a) is undefined and one of drift(C [·1 , ·2 ]; a; ∅) or drift(C [·1 , ·2 ]; ∅; a) is defined then C [a!b. P , a?x. P ] −→ Q for some Q and ω = (a). Proof. The proof proceeds by induction on the structure of context C [·1 , ·2 ].
• C [·1 , ·2 ] = C1 [·1 ] | C2 [·2 ]: We will show only the case when both drift(C1 [·1 ], a) and drift(C2 [·2 ], a) are undefined (other cases, contained in (ii ), are similar). By Lemma A.4, we conclude that (a)a!b
(a)a?b
C1 [a!b. P ] −−−→ C1 [ P ] and C2 [a?x. P ] − −−−→ C2 [ P {b/x}]. By rule (l-comm), we get τ(a)(a)
C1 [a!b. P ] | C2 [a?x. P ] −−−→ C1 [ P ] | C2 [ P {b/x}]. One should notice that in the other two cases (those included in (ii )) we get ω = (a). • C [·1 , ·2 ] = C1 [·1 , ·2 ] | R: According to (c-par), drift(C1 [·1 , ·2 ] | R ; a; a) is undefined if drift(C1 [·1 , ·2 ]; a; a) is undeτω fined. By induction hypothesis, C1 [a!b. P , a?x. P ] −→ Q for some Q and ω ∈ {(a), (a)(a)}. Finally, we derive τω C1 [a!b. P , a?x. P ]| R −→ Q | R, by (l-par). • C [·1 , ·2 ] = (c )C1 [·1 , ·2 ] and a = c: If drift((c )C1 [·1 , ·2 ]; a; a) is undefined, then drift(C1 [·1 , ·2 ]; a; a) is undefined. By inτω duction hypothesis, C1 [a!b. P , a?x. P ] −→ Q for some Q and ω ∈ {(a), (a)(a)}. The proof completes with application of (l-scope).
• C [·1 ,·2 ] = (a)C1 [·1 ,·2 ]: If drift((a)C1 [·1 ,·2 ]; a; a) is undefined then drift(C1 [·1 ,·2 ]; a; a) is undefined and drift(C1 [·1 ,·2 ]; a; ∅) and drift(C1 [·1 , ·2 ]; ∅; a) are both undefined and, by induction hypothesis, τω
C1 [a!b. P , a?x. P ] −→ Q for some Q and ω = (a)(a). By
τ(a) (l-scope-int), (a)C1 [a!b. P , a?x. P ] −−→ Q .
2
164
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
τω
Lemma A.6. If drift(C [·1 , ·2 ]; a, b; a) is undefined then C [ab. Q , a(b). R ] −→ Q and ω = (a)i (b) j , where i + j ≥ 1. Proof. The proof follows a similar reasoning as the proof of Lemma A.5.
2
τω
Proposition 1. Process P is an error iff P −→ Q for some Q and τω = τ . Proof. (⇐) The proof follows directly from cases 13.-16. of Lemma A.3. (⇒) If P is an error, then, by Definition 3, P ≡ (ν c˜ )C [αa . P , αa . P ], where we distinguish two cases: 1.
τ
ω αa = a!b, αa = a?x and drift(C [·1 , ·2 ]; a; a) is undefined. By Lemma A.5 we get C [a!b. P , a?x. P ] −→ Q for some Q and ω ∈ {(a), (a)(a)}. By successive application of (l-res) we get
τω
(ν c˜ )C [a!b. P , a?x. P ] −→ (ν c˜ ) Q , τω
and by Lemma A.2 we conclude P −→ Q for some Q such that Q ≡ (ν c˜ ) Q . 2. αa = ab, αa = a(b) and drift(C [·1 , ·2 ]; a, b; a) is undefined. Follows the same reasoning as the previous case, by application of Lemma A.6. 2 Proposition A.1 (Inversion on drift). 1. If drift(C [·1 , ·2 ]; a; a) is defined and C [·1 , ·2 ] = C [C1 [·] | C2 [·]] then: – (case (a) in C1 and C2 ): C1 [·] = C1 [(a)C1 [·]] and C2 [·] = C2 [(a)C2 [·]], where drift(C1 [·]; a) and drift(C2 [·]; a) are undefined, or – (case (a) in C1 and not in C2 ): C1 [·] = C1 [(a)C1 [·]] and C [·] = C3 [(a)C3 [·]], where drift(C1 [·]; a), drift(C2 [·]; a) and drift(C3 [·]; a) are undefined, or – (case (a) not in C1 and it is in C2 ): C2 [·] = C2 [(a)C2 [·]] and C [·] = C3 [(a)C3 [·]], where drift(C2 [·]; a), drift(C1 [·]; a) and drift(C3 [·]; a) are undefined, or – (case (a) not in C1 and not in C2 ): C [·] = C3 [(a)C3 [·]] and C3 [·] = C4 [(a)C4 [·]], where drift(C1 [·]; a), drift(C2 [·]; a), drift(C4 [·]; a, a) and drift(C4 [·]; a) are undefined. 2. If drift(C [·1 , ·2 ]; a, b; a) is defined and C [·1 , ·2 ] = C [C1 [·] | C2 [·]] then: – (case (a), (b) in C1 and (a) in C2 ): C1 [·] = C11 [(a)C12 [·]] and C12 [·] = C13 [(b)C14 [·]], and C2 [·] = C2 [(a)C2 [·]], where drift(C12 [·]; a), drift(C14 [·]; b) and drift(C2 [·]; a) are undefined, or – (case (a), (b) in C1 and (a) in C2 ): C1 [·] = C11 [(b)C12 [·]] and C12 [·] = C13 [(a)C14 [·]], and C2 [·] = C2 [(a)C2 [·]], where drift(C12 [·]; b), drift(C14 [·]; a) and drift(C2 [·]; a) are undefined, or – (case (a), (b) in C1 and (a) not in C2 ): C1 [·] = C11 [(a)C12 [·]] and C12 [·] = C13 [(b)C14 [·]], and C [·] = C3 [(a)C3 [·]], where drift(C12 [·]; a), drift(C14 [·]; b), drift(C2 [·]; a) and drift(C3 [·]; a) are undefined, or – (case (a), (b) in C1 and (a) not in C2 ): C1 [·] = C11 [(b)C12 [·]] and C12 [·] = C13 [(a)C14 [·]] and C [·] = C3 [(a)C3 [·]], where drift(C12 [·]; b), drift(C14 [·]; a), drift(C2 [·]; a) and drift(C3 [·]; a) are undefined, or – the rest of 10 cases are analogous. τ
Lemma A.7 (Harmony - LTS). If P → Q then there is Q such that Q ≡ Q and P − → Q . Proof. The proof is by induction on the derivation P → Q . We obtain two base cases:
• (r-comm): Let C [a!b. P , a?x. Q ] → C − [(a) P , (a) Q {b/x}], for C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; a). By rules (l-out) and (l-in) (a)a!b
(a)a?b
we get a!b. P −−−→ (a) P and a?x. Q − −−−→ (a) Q {b/x}. By Proposition A.1 we distinguish four cases for the structure of the context C [·1 , ·2 ] = C [C1 [·] | C2 [·]]. We comment only the case when C1 [·] = C1 [(a)C1 [·]] and C2 [·] = C2 [(a)C2 [·]], where drift(C1 [·]; a) and drift(C2 [·]; a) are undefined, thus in contexts C1 [·] and C2 [·] the holes are not in the scope of authorizations (a). Proceeding by induction on contexts C1 [·] and C2 [·] using rules (l-par) and (l-scope) we get (a)a!b
(a)a?b
C1 [a!b. P ] −−−→ C1 [(a) P ] and C2 [a?x. Q ] −−−−→ C2 [(a) Q {b/x}]. By a!b
(l-scope-ext) we get
a?b
(a)C1 [a!b. P ] −−→ C1 [(a) P ] and (a)C2 [a?x. Q ] −−→ C2 [(a) Q {b/x}]. Again, by induction on contexts C1 [·] and C2 [·] using rules (l-par) and (l-scope) we get a!b
a?b
C1 [(a)C1 [a!b. P ]] −−→ C1 [C1 [(a) P ]] and C2 [(a)C2 [a?x. Q ]] −−→ C2 [C2 [(a) Q {b/x}]]. By (l-comm)
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
165
τ
C1 [(a)C1 [a!b. P ]] | C2 [(a)C2 [a?x. Q ]] − → C1 [C1 [(a) P ]] | C2 [C2 [(a) Q {b/x}]]. By induction on the structure of context C [·] and using rules (l-par) and (l-scope) again, we get τ
C [a!b. P , a?x. Q ] − → C [C1 [C1 [(a) P ]] | C2 [C2 [(a) Q {b/x}]]]. Now we just need to note that drift (C [·1 , ·2 ]; a; a) = C [C1 [C1 [·]] | C2 [C2 [·]].
• (r-auth) apply similar reasoning.
For the induction step we have two possible last applied rules: (r-newc): Assume that (ν a) P → (ν a) Q is derived from P → Q . By induction hypothesis P τ (l-res) we get (ν a) P − → (ν a) Q . By contextually of ≡, from Q ≡ Q we get (ν a) Q ≡ (ν a) Q .
τ
− → Q where Q ≡ Q . By τ
→ Q is derived from P ≡ P → Q ≡ Q . From the induction hypothesis P − → Q , where Q ≡ τ Q . By Lemma A.2 we get P − → Q , where Q ≡ Q . Since the structural congruence is equivalence relation we get Q ≡ Q ≡ Q ≡ Q . 2 (r-stru): Assume that P
τ
Lemma A.8 (Harmony - reduction). If P − → Q then P → Q . τ
Proof. The proof is by induction on the derivation P − → Q . The base cases are obtained by: τ
α
α
• (l-comm): If P 1 | Q 1 − → P 2 | Q 2 is derived from P 1 − → P 2 and Q 1 − → Q 2 , where α , α ∈ {a!b, a?b}. By Lemma A.3, one possibility is, up to the structural congruence
P 1 , Q 1 ∈ {(ν d˜1 )C1 [a!b. P 1 ], (ν d˜2 )C2 [a?b. Q 1 ]} and
P 2 , Q 2 ∈ {(ν d˜ )C1− [(a) P 1 ], (ν d˜2 )C2− [(a) Q 1 {b/x}]} where C1− = drift(C1 [·]; a) and C2− = drift(C2 [·]; a).
By (sc-res-extr) we have (ν d˜1 )C1 [a!b. P 1 ] | (ν d˜2 )C2 [a?b. Q 1 ] ≡ (ν d˜1 , d˜2 )(C [a!b. P 1 , a?b. Q 1 ]) and
(ν d˜1 )C1− [(a) P 1 ] | (ν d˜2 )C2− [(a) Q 1 {b/x}] ≡ (ν d˜1 , d˜2 )C − [(a) P 1 , (a) Q 1 {b/x}], where C [·1 , ·2 ] = C1 [·1 ] | C2 [·2 ] and C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; a). By (r-comm) and (r-newc) we get
(ν d˜1 , d˜2 )C [a!b. P 1 , a?b. Q 1 ] → (ν d˜1 , d˜2 )C − [(a) P 1 , (a), Q 1 {b/x}]. The proof is analogous if
P 1 , Q 1 ∈ {(ν d˜1 )C1 [a!b. P 1 ], (ν d˜2 )C2 [!(a)a?b. Q 1 ]} and
P 2 , Q 2 ∈ {(ν d˜1 )C1− [(a) P 1 ], (ν d˜2 )C2− [(a) Q 1 {b/x} | !(a)a?b. Q 1 ]}, where C1− [·] = drift(C1 [·]; a) and C2− [·] = drift(C2 [·]; ∅) = C2 [·]. • (l-close) and (l-auth) we get by the similar reasoning, where for the second we apply (r-auth) instead of rule (r-comm). For the induction step, the last applied rule is one of the following: τ
τ
• (l-res): (ν a) P − → (ν a) Q is derived from P − → Q . By induction hypothesis P → Q and by (r-newc) (ν a) P → (ν a) Q . τ(a)
τ
• (l-scope-ext): (a) P − → Q is derived from P −−→ Q . By Lemma A.3, we have three cases, we detail only the case when P ≡ (ν d˜ )C [a!b. P , a?x. P ] and Q ≡ (ν d˜ )C − [(a) P , (a) P {b/x}], where C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; ∅), or C − [·1 ; ·2 ] = drift(C [·1 , ·2 ]; ∅; a), and drift(C [·1 , ·2 ]; a; a) is undefined. Using rule (sc-scope-auth) we get (a) P ≡ (ν d˜ )(a)C [a!b. P , a?x. P ]. Then drift((a)C [·1 , ·2 ]; a, a) = C − [·1 , ·2 ]. Thus, by (r-comm), (r-newc) and (r-stru) we get the proof. τ
τ
τ
τ
• (l-scope): (c ) P − → (c ) Q is derived from P − → Q , or P | R − → Q | R is derived from P − → Q . By induction hypothesis P → Q . Then P ≡ (ν d˜ )C [a!b. P 1 , a?b. P 2 ] and Q ≡ (ν d˜ )C − [(a) P 1 , (a) P 2 {b/a}], where C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a; a) or P ≡ (ν d˜ )C [ab. P 1 , a(b). P 2 ] and Q ≡ (ν d˜ )C − [(a) P 1 , (a)(b) P 2 ], where C − [·1 , ·2 ] = drift(C [·1 , ·2 ]; a, b; a). Thus, by (sc-scope-auth) we get (c ) P ≡ (ν d˜ )(c )C [a!b. P 1 , a?b. P 2 ] or (c ) P ≡ (ν d˜ )(c )C [ab. P 1 , a(b). P 2 ] where in the former case we get the proof by (r-comm), (r-newc) and (r-stru), and in the latter case we get the proof by (r-auth), (r-newc) and (r-stru).
166
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
• (l-par): by similar reasoning as for (l-scope). 2 τ
Theorem 1 (Harmony). P → Q if and only if P − →≡ Q . Proof. The proof follows directly from Lemma A.7 and Lemma A.8.
2
Appendix B. Proofs from Section 3 Proposition 2 (Strong bisimilarity includes structural congruence). ≡ ⊆ ∼. Proof. The proof proceeds by coinduction on the definition of strong bisimulation, showing that relation
R = {( P , Q ) | P ≡ Q } α is a strong bisimulation, hence R ⊆∼. Let ( P , Q ) ∈ R. By Lemma A.2 we have that if P ≡ Q and P − → P , then there exists α
some Q such that Q − → Q and P ≡ Q . Thus, R is a strong bisimulation relation.
2
Theorem 2 (Congruence). Let P , Q and R be arbitrary processes, and a, b arbitrary names. Then the following equalities hold. 1. 2. 3. 4. 5. 6. 7. 8.
If If If If If If If If
P ∼ Q then P | R ∼ Q | R. P ∼ Q then (ν a) P ∼ (ν a) Q . P ∼ Q then a!b. P ∼ a!b. Q . P {b/x} ∼ Q {b/x}, for all b, then a?x. P ∼ a?x. Q . P {b/x} ∼ Q {b/x}, for all b, then !(a)a?x. P ∼!(a)a?x. Q . P ∼ Q then (a) P ∼ (a) Q . P ∼ Q then ab. P ∼ ab. Q . P ∼ Q then a(b). P ∼ a(b). Q .
Proof. The proof is by coinduction on the definition of strong bisimulation. 1. Follows by coinduction considering the relation
R = {((ν a˜ )( P | R ), (ν a˜ )( Q | R )) | P ∼ Q }, and showing that it is a strong bisimulation, i.e., R ⊆∼. Let ((ν a˜ )( P | R ), (ν a˜ )( Q | R )) ∈ R and let α
(ν a˜ )( P | R ) − → P1
(B.1) α
α , where bn(α ) ∩ fn((ν a˜ )( Q | R )) = ∅. We show that then there is some Q 1 such that (ν a˜ )( Q | R ) − → α Q 1 and ( P 1 , Q 1 ) ∈ R. The proof is analogous when showing that if (ν a˜ )( Q | R ) − → Q 1 and bn(α ) ∩ fn((ν a˜ )( P | R )) = ∅ α then (ν a˜ )( P | R ) − → P 1 where again ( P 1 , Q 1 ) ∈ R. We consider three distinct cases for deriving (B.1), either it is derived for some P 1 and
from the observation on P or on R or from the synchronization between P and R. -Observation on P : In this case we have α
(ν a˜ )( P | R ) − → (ν a˜ )( P | R ) is derived from
α P −→ P
where either
α = α and a˜ = a˜ or α = (b)i (ν c )b!c and α = (b)i b!c and a˜ = a˜ , c. By bn(α ) ∩ fn( Q ) = ∅ and P ∼ Q we α
conclude that Q −→ Q where P ∼ Q . Thus, we can derive α
(ν a˜ )( Q | R ) − → (ν a˜ )( Q | R ) and we conclude ((ν a˜ )( P | R ), (ν a˜ )( Q | R )) ∈ R. -Observation on R: Follows similar lines. -Synchronization between P and R: We give only the case when (B.1) is derived by (l-close), since other cases, including the symmetric case for (l-close), follows the similar lines. Consider
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
167
τω
(ν a˜ )( P | R ) −→ (ν a˜ )(ν b)( P | R ) is derived from (ν b )σ1 P −−−−→ P
and
σ1 R− −→ R . (ν b)σ1
Since without loss of generality we can assume b ∈ / fn( Q ), by P ∼ Q we have Q −−−−→ Q and P ∼ Q . Thus, τ
ω (ν a˜ )( Q | R ) −→ (ν a˜ )(ν b)( Q | R )
and we conclude ((ν a˜ )(ν b)( P | R ), (ν a˜ )(ν b)( Q | R )) ∈ R. 2. Follows the similar lines by showing that relation
R = {((ν a) P ∼ (ν a) Q ) | P ∼ Q } ∪ ∼ is contained in ∼ by conduction on the definition of strong bisimulation. 3. Follows by showing that relation
R = {(a!b. P , a!b. Q ) | P ∼ Q } ∪ ∼ is the contained in ∼ by coinduction on the definition of strong bisimulation. Notice that pair of processes that are in relation R are either in ∼, in which case we get the proof directly, or have only the same output observable, in which case the pair of continuing processes is in ∼. 4. Follows the similar lines as 3., considering relation
R = {(a?x. P , a?x. Q ) | (∀b) P {b/x} ∼ Q {b/x}} ∪ ∼ . Notice that if (a?x. P , a?x. Q ) ∈ R two processes have only input observable which lead to P {b/x} and Q {b/x}, for some b, which are bisimilar by the assumption. 5. Follows by showing that relation
R = {( R | !(a)a?x. P , S | !(a)a?x. Q ) | R ∼ S ∧ (∀b) P {b/x} ∼ Q {b/x}} is a strong bisimulation, i.e., R ⊆∼. Let ( R | !(a)a?x. P , S | !(a)a?x. Q ) ∈ R and let α R | !(a)a?x. P − → P
(B.2)
for some P and α such that bn(α ) ∩ fn( S | !(a)a?x. Q ) = ∅. We consider three distinct cases for deriving (B.2), either it is derived from the observation on R or on !(a)a?x. P or from the synchronization between R and !(a)a?x. P . Observation on R: In this case: α
R | !(a)a?x. P − → R | !(a)a?x. P α α is derived from R − → R . Since bn(α ) ∩ fn( S ) = ∅ and R ∼ S it follows that S − → S . By bn(α ) ∩ fn(!(a)a?x. Q ) = ∅ we get
α S | !(a)a?x. Q − → S | !(a)a?x. Q
and ( R | !(a)a?x. P , S | !(a)a?x. Q ) ∈ R. Observation on !(a)a?x. P : In this case a?b
R | !(a)a?x. P −−→ R | (a) P {b/x} | !(a)a?x. P a?b
is derived from !(a)a?x. P −−→ (a) P {b/x} | !(a)a?x. P . Then we can also derive a?b
S | !(a)a?x. Q −−→ S | (a) Q {b/x} | !(a)a?x. Q and we only have to show that R | (a) P {b/x} ∼ S | (a) Q {b/x}. Since P {b/x} ∼ Q {b/x} for any b, by statement 6. of this Theorem, we get (a) P {b/x} ∼ (a) Q {b/x}. Using R ∼ S, statement 1. of this Theorem and transitivity and commutativity of strong bisimilarity we have R | (a) P {b/x} ∼ S | (a) Q {b/x}. Synchronization between R and !(a)a?x. P : We will detail only the case when the synchronization is derive using rule (l-close). In this case τω
R | !(a)a?x. P −→ (ν b)( R |(a) P {b/x}) | !(a)a?x. P is derived from
168
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
(a)i (ν b)a!b
R −−−−−−→ R
and
a?b
!(a)a?x. P −−→ (a) P {b/x}) | !(a)a?x. P
(a) (ν b)a!b Since without loss of generality we can assume b ∈ / fn( S | !(a)a?x. Q ), by R ∼ S we derive S −−−−−−→ S , where R ∼ S . Then, we can also derive i
τω
S | !(a)a?x. Q −→ (ν b)( S |(a) Q {b/x}) | !(a)a?x. Q . Similarly as in the previous case we can derive R |(a) P {b/x} ∼ S |(a) Q {b/x}, and by statement 2. of this Theorem we can derive (ν b)( R |(a) P {b/x}) ∼ (ν b)( S |(a) Q {b/x}), which finishes the proof. 6. Follows by showing that relation
R = {((a) P , (a) Q ) | P ∼ Q } ∪ ∼ is contained in ∼ by coinduction on the definition of strong bisimulation. Let ((a) P , (a) Q ) ∈ R and let α
(a) P − → P . There are three cases for the last applied rule while deriving the latter, we detail only the case when the last applied τω(a)
τa
τω(a)
rule is (l-scope-int). Then (a) P −→ P is derived from P −−−→ P . By P ∼ Q we get Q −−−→ Q where P ∼ Q . By τa
−→ Q , which finishes the proof.
(l-scope-int) we have (a) Q
7. Follows by showing that relation
R = {(ab. P , ab. Q ) | P ∼ Q } ∪ ∼ is contained in ∼ by coinduction on the definition of strong bisimulation. Note that both process ab. P and ab. Q have only one observable action leading them to processes (a) P and (a) Q , which are bisimilar by P ∼ Q and statement 6. of this Theorem. 8. Follows similar lines as 7., with witnessing relation
R = {(a(b). P , a(b). Q ) | P ∼ Q } ∪ ∼ . 2 Proposition 3 (Behavioral inequalities). There exist processes P and Q and name a such that the following inequalities hold: 1. 2. 3. 4. 5.
(a)( P | Q ) (a) P | (a) Q , (a)(a)( P | Q ) (a) P | (a) Q , (a)( P | Q ) P | (a) Q if a ∈ / fn( P ), (a)(a) P (a) P , (a) P P if a ∈ / fn( P ).
Proof. To prove each inequality we give a proper counter-example. 1. Consider processes P = a!b.0 and Q = a?x.0. Then process (a) P | (a) Q has
τ -transition
τ
(a)a!b.0 | (a)a?x.0 − → (a)0 | (a)0, while process (a)( P | Q ) has only
τ -transition with pending authorization
τ(a)
(a)(a!b.0 | a?x.0) −−→ (a)0 | (a)0. 2. Consider for example P = aa.0 and Q = 0. Then aa
(a)(a)( P | Q ) −−→ (a)0 | 0, while the only possible action for (a) P | (a) Q is (a)aa
(a) P | (a) Q −−−−→ (a)0 | (a)0. 3. Consider processes P = b?x.x!c .0 and Q = 0. Then we have (b)b?a
a!c
(a)( P | Q ) −−−−→ (a)((b)a!c .0 | 0) −−→ (b)(a)0 | 0, while the only possible action for P | (a) Q after receiving a on b is pending on authorization (a) (b)b?a
(a)a!c
P | (a) Q − −−−→ (b)a!c .0 | (a)0 −−−→ (b)(a)0 | (a)0.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
169
4. Consider P = aa.0. Then aa
(a)aa
(a)(a) P −−→ (a)0 while (a) P −−−−→ (a)0. 5. Consider again processes P = b?x.x!c .0. Then a!c
(b)b?a
(a) P −−−−→ (a)(b)a!c .0 −−→ (b)(a)0. On the other hand (a)a!c
(b)b?a
P− −−−→ (b)a!c .0 −−−→ (b)(a)0.
2
Proposition 4 (Behavioral (in)equalities). 1. 2. 3. 4. 5.
For any process P , names a, b and prefix αb such that b = a and αb = ba we have that (a)αb . P ∼ αb .(a) P . There exist process P , name a and prefixes αb , αc , where a does not occur, such that (a)αb .αc . P αb .αc .(a) P . For any process P , name a and prefix αb such that αb = aa, we have that (a)(a)αb . P ∼ (a)αb .(a) P . For any process P and name a we have that (a)(a)(a)aa. P ∼ (a)(a)aa.(a) P . For any process P , names a, b, c 1 , . . . , cn we have that (c 1 ) . . . (cn )(a)(b)ab. P ∼ (a)(b)ab.(c 1 ) . . . (cn ) P .
Proof.
1. Follows by showing that relation
R = {((a)α . P , α .(a) P ) | α ∈ / {a!b, a?x, !(a)a?x, ab, ba, a(b)}} ∪ ∼ is contained in ∼ by coinduction on the definition of strong bisimulation. Note that the only action of both processes (a)α . P and α .(a) P is determined by the prefix α , and that the action is not pending on the authorization (a). Each action of one process can be mimicked by the other leading to the same process, hence the proof follows by the reflexivity of strong bisimilarity. 2. Consider α = b?x and β = x!c. Then one possible transition for the first process is (b)b?a
a!c
(b)b?a
(a)a!c
(a)α .β. P −−−−→ (a)(b)a!c . P {a/x} −−→ (b)(a) P {a/x}, while
α .β.(a) P −−−−→ (b)a!c .(a) P {a/x} −−−→ (b)(a) P {a/x}. 3. Follows similar lines as 1., where witnessing relation in this case is
R = {((a)(a)α . P , (a)α .(a) P ) | α ∈ {a!b, a?x, ac , c a, a(b)}, c = a} ∪ ∼ . 4. Again, follows similar lines as 1., with witnessing relation
R = {((a)(a)(a)aa. P , (a)(a)aa.(a) P )} ∪ ∼ . 5. Follows directly from statements 1., 2., and 4. of this Proposition, Theorem 2 and Proposition 2.
2
Appendix C. Proofs from Section 4 Proposition C.1 (Preservation of well-formedness). If P is well-formed and P ≡ Q or P → Q then Q is also well-formed and sym( P ) = sym( Q ). Proof. The proof is by induction on the last applied structural congruence or reduction rule. We detail only the case when the last applied reduction rule is (r-newc). Let P = (ν a : r) P , Q = (ν a : r) Q , and P → Q be derived from P → Q . Since P is well-formed r ∈ / sym( P ) and P is well-formed. By induction hypothesis we get Q is well-formed and sym( P ) = sym( Q ). Thus, r ∈ / sym( Q ), Q is well-formed and sym( P ) = sym( Q ). 2 Lemma C.1 (Inversion on typing). 1. 2. 3. 4. 5.
If ρ If ρ If ρ If ρ If ρ
(ν a : r) P then , a : {a}( T ) ρ P , where = {r/a} and r ∈ / sym( P ) and a ∈ / ρ , names( T ). (ν a : κ ) P then , a : κ ( T ) ρ P , where a ∈ / ρ , names( T , ). (a) P then ρ {a} P . a!b. P then ρ P , where (a) = γ (γ ( T )), (b) = γ ( T ), γ ⊆ γ and if a ∈ / ρ then ω ⊆ ρ . a?x. P then , x : T ρ P , where (a) = ω( T ), x ∈ / ρ , names() and if a ∈ / ρ then ω ⊆ ρ .
170
6. 7. 8. 9.
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
If ρ !(a)a?x. P then , x : T {a} P where sym( P ) = ∅ and (a) = ω( T ) and x ∈ / ρ , names(). / ρ then ω ⊆ ρ . If ρ ab. P then ρ P , (a) = ω( T ), where ρ = ρ {b} and if a ∈ / ρ then ω ⊆ ρ . If ρ a(b). P then ρ {b} P , where (a) = ω( T ) and if a ∈ If ρ P 1 | P 2 then ρ1 P 1 and ρ2 P 2 , where ρ = ρ1 ρ2 and sym( P 1 ) ∩ sym( P 2 ) = ∅.
The following two results (weakening and strengthening properties) are fundamental to prove Subject Congruence, which in turn is crucial to prove Subject Reduction. We write a ↔ r or a ↔ κ depending on whether the name a is bound in the process, or the process is in a context where the name a is bound, with (ν a : r) or (ν a : κ ), respectively. Lemma C.2 (Weakening). 1. Let ρ P and a ∈ / fn( P ) ∪ ρ . Then / sym( P ) and = {a/r} then , a : {a}( T ) ρ P ; 1. if a ↔ r and r ∈ 2. if a ↔ κ then , a : κ ( T ) ρ P . 2. If ρ P then ρ ρ P . Proof. The proof is by induction on the depth of the derivation ρ P . 1. We detail only two cases when the last applied rule is (t-out) or (t-rep-in).
• (t-out): Let ρ b!c . P be derived from ρ P , where (b) = γ (γ ( T )), (c ) = γ ( T ), γ ⊆ γ , and if b ∈ / ρ then ω ⊆ ρ . Then, we have two cases: -If a ↔ r and r ∈ / sym( P ) and = {a/r}, by induction hypothesis , a : {a}( T ) ρ P . Since (b) = (γ (γ ( T ))){a/r}, (c ) = (γ ( T )){a/r}, then γ {a/r} ⊆ γ {a/r}. Since from b ∈ / ρ it follows ω ⊆ ρ , then if r ∈ ω it follows b ∈ ρ . If r ∈ /ω then ω{a/r} = ω . Thus, by (t-out) we get , a : {a}( T ) ρ b!c . P . -If a ↔ κ then by induction hypothesis , a : κ ( T ) ρ P . Since does not change we get the result directly by (t-out). • (t-rep-in): Let ρ !(b)b?xP be derived from , x : T {b} P , with (b) = γ ( T ), where without loss of generality we can assume that x = a. Again, we have two cases: / sym( P ) and = {a/r}, by induction hypothesis , x : T {a/r}, a : {a}( T ) {b} P . Since (b) = -If a ↔ r and r ∈ (γ ( T )){a/r} by (t-rep-in) we get , a : {a}( T ) ρ !(b)b?xP . -If a ↔ κ then by induction hypothesis , x : T , a : κ ( T ) {b} P . Again, we get the result directly by (t-rep-in). 2. We detail only the case when the last applied rule is (t-in). Let ρ a?x. P be derived from , x : T ρ P , where (a) = ω( T ), x ∈ / ρ , names() and if a ∈ / ρ then ω ⊆ ρ . By induction hypothesis , x : T ρ ρ P . Without loss of generality we can assume that x is new to ρ , i.e. x ∈ / ρ . Since we can conclude that if a ∈ / ρ ρ then ω ⊆ ρ ρ , by (t-in) we get ρ ρ a?x. P . 2 Lemma C.3 (Strengthening). 1. If , a : {a}( T ) ρ P and a ∈ / fn( P ) ∪ ρ and a ↔ r and r ∈ / sym( P ) then ρ P , where = {r/a}. / fn( P ) ∪ ρ then ρ P . 2. If , a : κ ( T ) ρ P and a ∈ Proof. The proof is by induction on the depth of the derivation ρ P . We comment only the case when the last applied rule is (t-in). We have two cases: / sym( P ) and = {r/a}, and , a : {a}( T ) ρ b?x. P . From a ∈ / fn(b?xP ), without loss of generality, we -If a ↔ r and r ∈ can conclude a = b and a = x. By Lemma C.1 we get , a : {a}( T ), x : T ρ P , (b) = ω( T ), and if b ∈ / ρ then ω ⊆ ρ . By induction hypothesis , x : T {r/a} ρ P . Since a ∈ / ρ then if a ∈ ω it follows b ∈ ρ . If a ∈ / ω then ω{r/a} = ω . Thus, using (t-in) we get ρ b?x. P . -If a ↔ κ and , a : {a}( T ) ρ b?x. P . Using the same arguments we can again assume a = b and a = x. By Lemma C.1 we get , a : κ ( T ), x : T ρ P , (b) = ω( T ), and if b ∈ / ρ then ω ⊆ ρ . By induction hypothesis , x : T ρ P . Thus, using (t-in) we get ρ b?x. P . 2 Lemma C.4 (Subject congruence). If ρ P and P ≡ Q then ρ Q . Proof. The proof is by induction on the depth of the derivation P ≡ Q . We comment only three cases when the last applied rule is (sc-par-inact), (sc-res-extr) or (sc-rep): 1. P | 0 ≡ P . From ρ P | 0 by Lemma C.1 we get ρ1 P and ρ2 0, where ρ P . If ρ P , by (t-stop) we get ∅ 0 and by (t-par) we conclude ρ P | 0.
ρ1 ρ2 = ρ . By Lemma C.2 we get
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
171
2. P | (ν a : r) Q ≡ (ν a : r)( P | Q ) or P | (ν a : κ ) Q ≡ (ν a : κ )( P | Q ), if a ∈ / fn( P ). To show implication from right to the left we have two cases: -If a ↔ r then from ρ P | (ν a : r) Q by Lemma C.1 we get ρ1 P and ρ2 (ν a : r) Q , where ρ1 ρ2 = ρ and sym( P ) ∩ sym((ν a : r) Q ) = ∅. Applying Lemma C.1 we get , a : {a}(ϕ ) ρ2 Q where = {a/r} and a ∈ / ρ2 and r∈ / sym( Q ). From sym( P ) ∩ sym((ν a : r) Q ) = ∅ we get r ∈ / sym( P ) and from a ∈ / fn( P ) and a ∈ bn((ν a : r) Q ) without loss of generality can assume a ∈ / ρ1 . By Lemma C.2 we get , a : {a}(ϕ ) ρ1 P where = {a/r}. By (t-par) , a : {a}(ϕ ) ρ P | Q and by (t-new) ρ (ν a : r)( P | Q ). -If a ↔ κ then from ρ P | (ν a : κ ) Q by Lemma C.1 we get ρ1 P and ρ2 (ν a : κ ) Q , where ρ1 ρ2 = ρ . Applying Lemma C.1 again we get , a : κ (ϕ ) ρ2 Q where a ∈ / ρ2 . By Lemma C.2 we get , a : κ (ϕ ) ρ1 P . By (t-par) , a : κ (ϕ ) ρ P | Q and by (t-new-rep) ρ (ν a : κ )( P | Q ). To show implication from left to the right we again have two cases: -If a ↔ r then from ρ (ν a : r)( P | Q ) by Lemma C.1 we get , a : a( T ) ρ P | Q where = {a/r} and r∈ / sym( P | Q ) and a ∈ / ρ . By Lemma C.1 , a : {a}( T ) ρ1 P and , a : {a}( T ) ρ2 Q , where ρ1 ρ2 = ρ and sym( P ) ∩ sym( Q ) = ∅. Since a ∈ / fn( P ) ∪ ρ1 and r ∈ / sym( P ) by Lemma C.3 ρ1 P . Using r ∈ / sym( Q ) and a ∈ / ρ2 by (t-new) we get ρ2 (ν a : r) Q , and by (t-par) we get ρ P | (ν a : r) Q . / ρ . By Lemma C.1 -If a ↔ κ then from ρ (ν a : κ )( P | Q ) by Lemma C.1 we get , a : κ ( T ) ρ P | Q where a ∈ , a : {a}( T ) ρ1 P and , a : {a}( T ) ρ2 Q , where ρ1 ρ2 = ρ . Since a ∈ / fn( P ) ∪ ρ1 by Lemma C.3 ρ1 P . Using (t-new-rep) we get ρ2 (ν a : κ ) Q , and by (t-par) we get ρ P | (ν a : κ ) Q . 3. !(a)a?x. P ≡!(a)a?x. P | (a)a?x. P . We show only one implication. Suppose ρ !(a)a?x. P | (a)a?x. P . By Lemma C.1 we get ρ1 !(a)a?x. P and ρ2 (a)a?x. P , where ρ1 ρ2 = ρ . By the same Lemma we get sym( P ) = ∅ and , x : T {a} P , where (a) = γ ( T ) and x ∈ / ρ1 , names(). By (t-rep-in) we get ρ !(a)a?x. P . 2 Lemma 1 (Substitution). Let , x : γ ( T ) ρ P and x ∈ / names(). Then 1. If (a) = {a}( T ) and a ∈ γ then ρ {a/x} P {a/x}. 2. If (a) = κ ( T ) and κ = γ then ρ {a/x} P {a/x}. Proof. The proof is by induction on the depth of the derivation ρ P . We detail two cases:
• , x : γ (γ ( T )) ρ x!b. P . By Lemma C.1 , x : γ (γ ( T )) ρ P , where (b) = γ ( T ) and γ ⊆ γ and if x ∈ / ρ then γ ⊆ ρ . By induction hypothesis ρ {a/x} P {a/x}. If (a) = {a}(ω ( T )) and x ∈ ρ then a ∈ ρ {a/x} and if x ∈ / ρ then by γ ⊆ ρ we get a ∈ γ ⊆ ρ = ρ {a/x}. If (a) = κ (ω ( T )) then x ∈ ρ which implies a ∈ ρ {a/x}. By (t-out) we get ρ {a/x} (x!b. P ){a/x}. • , x : γ ( T ) ρ b!x. P . By Lemma C.1 , x : γ ( T ) ρ P , where (b) = γ (γ ( T )) and γ ⊆ γ and if b ∈ / ρ then γ ⊆ ρ . By induction hypothesis ρ {a/x} P {a/x}. If (a) = {a}( T ) then a ∈ γ ⊆ γ and if a : κ ( T ) then κ = γ ⊆ γ . Thus, by (t-out) we get ρ {a/x} (b!x. P ){a/x}. 2 Lemma C.5 (Authorization safety). If ∅ C [ P 1 , P 2 ] and ρ1 P 1 and ρ2 P 2 and a ∈ ρ1 ∩ ρ2 then drift(C [·1 , ·2 ]; a; a) is defined. Proof. By induction on the structure of C [·1 , ·2 ].
2
˜ ) to abbreviate (ν c 1 : 1 ) . . . (ν cn : n ), where ranges over symbols from S and Notation. We use (ν c˜ :
ν.
Lemma C.6 (Interaction safety).
˜ )C [a!b. P 1 , a?x. P 2 ] and P is well-typed with ∅ P then drift(C [·1 , ·2 ]; a; a) is defined and if C [·1 , ·2 ] = 1. If P ≡ (ν c˜ : ˜ )C [(a) P 1 , (a) P 2 {b/x}] then ∅ Q . drift(C [·1 , ·2 ]; a; a) and Q ≡ (ν c˜ : ˜ )C [ab. P 1 , a(b). P 2 ] and P is well-typed with ∅ P then drift(C [·1 , ·2 ]; a, b; a) is defined and if C [·1 , ·2 ] = 2. If P ≡ (ν c˜ : ˜ )C [(a) P 1 , (a)(b) P 2 ] then ∅ Q . drift(C [·1 , ·2 ]; a, b; a) and Q ≡ (ν c˜ : Proof. The proof is by induction on the structure of the context C [·1 , ·2 ]. We detail only the first statement. If ∅ P ˜ )C [a!b. P 1 , a?x. P 2 ] and by consecutive application of Lemma C.1. 1 and 2, we get ∅ by Lemma C.4 we get ∅ (ν c˜ : C [a!b. P 1 , a?x. P 2 ], where = , and for each c ∈ dom( ), (c ) = c ( T ) or (c ) = κ ( T ). By consecutive application of Lemma C.1. 3 and 9, we get
ρ1 a!b. P 1 and ρ2 a?x. P 2 , for some multisets of names
ρ1 , ρ2 . By the same Lemma again
ρ1 P 1 and , x : γ ( T ) ρ2 P 2 ,
172
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
where (a) = {a}(γ ( T )) or (a) = κ (γ ( T )) and thus a ∈ ρ1 , a ∈ ρ2 . Furthermore, (b) = {b}( T ) or (b) = κ ( T ), and b ∈ γ and x ∈ / ρ2 ∪ names( ). Hence we have ρ2 {b/x} = ρ2 , and by Lemma 1 we get ρ2 P 2 {b/x}. By (t-auth) we get
ρ1 (a) P 1 and ρ2 (a) P 2 {b/x}, where ρ1 = ρ1 {a} and ρ2 = ρ2 {a}. Since ∅ C [a!b. P 1 , a?x. P 2 ], and a ∈ ρ1 , a ∈ ρ2 by Lemma C.5 we conclude drift(C [·1 , ·2 ]; a; a) is defined. By Proposition A.1 we distinguish four cases for the structure of the context C [·1 , ·2 ] = C [C1 [·1 ] | C2 [·2 ]]. We comment only the case when C1 [·] = C1 [(a)C1 [·]] and C2 [·] = C2 [(a)C2 [·]], where drift(C1 [·]; a) and drift(C2 [·]; a) are undefined, thus in contexts C1 [·] and C2 [·] the holes are not in the scope of authorizations (a). By consecutive application of (t-par) and (t-auth) we get ρ (a)C1 [a!b. P 1 ] and ρ (a)C2 [a?x. P 2 ], but also ρ C1 [(a) P 1 ] and ρ C2 [(a) P 2 {b/x}], for some 1
1
2
ρ1 , ρ2 . Since C [·1 , ·2 ] = C [C1 [C1 [·1 ]] | C2 [C2 [·2 ]]], again by consecutive application of C [(a) P 1 , (a) P 2 {b/x}] then by consecutive application of By Lemma C.4 we get ∅ Q . 2
(t-new) and (t-new-rep) we get
2
∅ ˜ )C [(a) P 1 , (a) P 2 {b/x}]. ∅ (ν c˜ : (t-par) and (t-auth) we get
Theorem 3 (Subject reduction). If P is well-typed, ∅ P , and P → Q then ∅ Q . Proof. The proof follows by induction on the derivation of P → Q . We have two base cases, when the rules applied are (r-comm) or (r-auth), which both we get directly by Lemma C.6. For the induction steps we have two cases:
• If the last applied rule is (r-newc) then we have two cases – (ν a : r) P → (ν a : r) Q is derived from P → Q . Let ∅ (ν a : r) P . By Proposition C.1 we get (ν a : r) Q is wellformed, thus r ∈ / sym( Q ). By Lemma C.1 we get , a : {a}( T ) ∅ P , where r ∈ / sym( P ) and = {a/r}. By induction hypothesis we get , a : {a}( T ) ∅ Q , and by (t-new) we get ∅ (ν a : r) Q . – (ν a : κ ) P → (ν a : κ ) Q is derived from P → Q . Let ∅ (ν a : κ ) P . By Lemma C.1 we get , a : κ ( T ) ∅ P . By induction hypothesis we get , a : κ ( T ) ∅ Q , and by (t-new-rep) we get ∅ (ν a : κ ) Q . • If the last applied rule is (r-struc) then P → Q is derived from P → Q , where P ≡ P and Q ≡ Q . Let ∅ P . By Lemma C.4 we get ∅ P . By induction hypothesis ∅ Q and by Lemma C.4 we get ∅ Q . 2 Proposition 5 (Type soundness). 1. If ρ P then P is well-formed. 2. If P is well-typed then P is not an error. Proof. 1. Directly from the typing rules. 2. Immediate from Lemma C.6. 2 Corollary 1 (Type safety). If P is well-typed and P →∗ Q then Q is not an error. Proof. The proof follows directly from Theorem 3 and Proposition 5(2).
2
Appendix D. Proofs from Section 5 Lemma D.1 (Monotonicity). If ; ρ1 : ρ2 ; ξ P ; ρ ; ξ then 1. sym( P ) = ξ \ ξ and ξ ⊆ ξ , 2. ρ ⊆ ρ1 . Proof. The proof is by induction on the depth of the type checking derivation. 1. We detail only when the last applied rules is (a-new) or (a-rep-in). Case (a-new): Let ; ρ1 : ρ2 ; ξ (ν a : r( T )) P ; ρ ; ξ be derived from , a : {a}( T ); ρ1 : ρ2 ; ξ ∪ r P ; ρ ; ξ , where = {r/a}, r ∈ / ξ and a ∈ / ρ1 , ρ2 , names( T ). By induction hypothesis we have ξ \ (ξ ∪ r) = sym( P ) and ξ ∪ r ⊆ ξ . Then, ξ \ ξ = sym( P ) ∪ {r} = sym((ν a : r( T )) P ) and ξ ⊆ ξ . Case (a-rep-in): Let ; ρ1 : ρ2 ; ξ !(a)a?x. P ; ρ1 ; ξ be derived from , x : T ; ∅ : {a}; ∅ P ; ∅; ∅, where (a) = γ ( T ) and x∈ / ρ1 , ρ2 , names(). By induction hypothesis sym( P ) = ∅ \ ∅ = ∅ and since sym( P ) = sym(!(a)a?x. P ), we can conclude ξ \ ξ = ∅ = sym(!(a)a?x. P ). 2. We detail only when the last applied rule is (a-out-1), or (a-par).
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
173
Case (a-out-2): Let ; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ be derived from ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , where ρ1 : ρ2 = move(ρ1 : ρ2 ; β), (a) = γ (γ ( T )), (b) = γ ( T ), a ∈ / ρ2 ∧ γ ρ2 , β = a ∨ β = γ and γ ⊆ γ . By induction hypothesis we have ρ ⊆ ρ1 . By the definition of the operator move we may conclude ρ1 ⊂ ρ1 . Hence, ρ ⊆ ρ1 . Case (a-par): Directly, since ρ1 ∩ ρ4 ⊆ ρ1 . 2 Lemma D.2 (Typing correspondence - soundness). If ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , then ρ erase( P ), where ρ = (ρ1 ρ2 ) − ρ . Proof. The proof is by induction on the depth of the type checking derivation. The base case is given by rule (a-stop): ; ρ1 : ρ2 ; ξ 0; ρ1 ; ξ . By (t-stop) we can derive ρ2 0. For the inductive step, we detail only when the last applied rule is (a-par) or (a-rep-in). Case (a-par): Let ; ρ1 : ρ2 ; ξ P 1 | P 2 ; ρ1 ∩ ρ4 ; ξ be derived from
; ρ1 ρ2 : ∅; ξ P 1 ; ρ3 ; ξ and ; ρ3 : ∅; ξ P 2 ; ρ4 ; ξ . By Lemma D.1 we have sym( P 1 ) = ξ \ ξ and ξ ⊆ ξ and ρ3 ⊆ ρ1 ρ2 , but also sym( P 2 ) = ξ \ ξ and ξ ⊆ ξ and Hence, we may conclude that sym( P 1 ) ∩ sym( P 2 ) = ∅. By induction hypothesis we have
ρ4 ⊆ ρ3 .
(ρ1 ρ2 )−ρ3 erase( P 1 ) and ρ3 −ρ4 erase( P 2 ). Since sym( P 1 ) ∩ sym( P 2 ) = ∅, by (t-par) we get (ρ1 ρ2 )−ρ4 erase( P 1 | P 2 ). By Lemma C.2, we get
(ρ1 ρ2 )−(ρ1 ∩ρ4 ) erase( P 1 | P 2 ). Case (a-rep-in): Let ; ρ1 : ρ2 ; ξ !(a)a?x. P ; ρ1 ; ξ be derived from , x : T ; ∅ : {a}; ∅ P ; ∅; ∅. By Lemma D.1 we have sym( P ) = ∅. By induction hypothesis we get , x : T {a} erase( P ). Since sym( P ) = ∅, by (t-rep-in) follows ρ2 erase(!(a)a?x. P ). 2 Lemma D.3 (Weakening). If ; ρ1 : ρ2 ; ξ P ; ρ ; ξ then ; ρ1 ρ ; ρ2 ; ξ P ; ρ ρ ; ξ . Proof. The proof is by induction on the depth of the type checking derivation. The base case is given by (a-stop). If ; ρ1 : ρ2 ; ξ 0; ρ1 ; ξ , we also may conclude using the same rule that ; ρ1 ρ : ρ2 ; ξ 0; ρ1 ρ ; ξ . We detail only the case when the last rule applied is (a-par). Let ; ρ1 : ρ2 ; ξ P 1 | P 2 ; ρ1 ∩ ρ4 ; ξ be derived from
; ρ1 ρ2 ; ∅; ξ P 1 ; ρ3 ; ξ and ; ρ3 : ∅; ξ P 2 ; ρ4 ; ξ . By induction hypothesis we have
; ρ1 ρ2 ρ : ∅; ξ P 1 ; ρ3 ρ ; ξ and ; ρ3 ρ ; ∅; ξ P 2 ; ρ4 ρ ; ξ . Then, by (a-par) we derive
; ρ1 ρ : ρ2 ; ξ P 1 | P 2 ; (ρ1 ρ ) ∩ (ρ4 ρ ); ξ . Since (ρ1 ρ ) ∩ (ρ4 ρ ) = (ρ1 ∩ ρ4 ) ρ the proof follows.
2
Lemma D.4 (Typing correspondence - completeness). If ρ erase( P ) then for any ρ1 , ρ2 multisets of names and ξ, ξ sets of symbols from S , such that ρ1 ρ2 = ρ and ξ \ ξ = sym( P ), we have that ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , for some ρ . Proof. The proof is by induction on the type derivation. For the base case we have (t-stop), ρ 0. By (a-stop) we can derive ; ρ1 : ρ2 ; ξ 0; ρ1 ; ξ , for any ρ1 , ρ2 and ξ , such that ρ1 ρ2 = ρ . For the last applied rule we detail only the cases of (t-par) and (t-in). Case (t-par): Let ρ erase( P 1 | P 2 ) be derived from ρ erase( P 1 ) and ρ erase( P 2 ) where ρ ρ = ρ and sym( P 1 ) ∩ sym( P 2 ) = ∅. By induction hypothesis we have
; ρ : ∅; ξ1 P 1 ; ρ1 ; ξ2 and ; ρ : ∅; ξ2 P 2 ; ρ2 ; ξ3 , where ξ2 \ ξ1 = sym( P 1 ), ξ3 \ ξ2 = sym( P 2 ) and ξ1 ∩ sym( P 2 ) = ∅. This choice is indeed possible since ξ2 ∩ sym( P 2 ) = ∅ (by assumption sym( P 1 ) ∩ sym( P 2 ) = ∅). By Lemma D.3 we derive
; ρ : ∅; ξ1 P 1 ; ρ1 ρ ; ξ2 and ; ρ ρ1 : ∅; ξ2 P 2 ; ρ2 ρ1 ; ξ3 . By (a-par) we get
; ρ1 : ρ2 ; ξ1 P 1 | P 2 ; ρ1 ∩ (ρ2 ρ1 ); ξ3 .
174
I. Proki´c et al. / Journal of Logical and Algebraic Methods in Programming 107 (2019) 136–174
Case (t-out): Let ρ erase(a!b. P ) be derived from ρ P , where (a) = γ (γ ( T )), (b) = γ ( T ) and γ ⊆ γ , and if a∈ / ρ then γ ∈ ρ . By induction hypothesis, ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , where ξ \ ξ = sym( P ) and ρ1 ρ2 = ρ . Now we have to prove ; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ for any ρ1 and ρ2 such that ρ1 ρ2 = ρ . We distinguish four cases: (i) (ii) (iii) (iv)
if a ∈ ρ and a ∈ ρ2 we chose ρ2 = ρ2 and by (a-out-1) we get ; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ , if a ∈ ρ and a ∈ / ρ2 we chose ρ2 = ρ2 {a} and by (a-out-2) we get ; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ , if γ ∈ ρ and γ ∈ ρ2 we chose ρ2 = ρ2 and by (a-out-1) we get ; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ , if γ ∈ ρ and γ ∈ / ρ2 we chose ρ2 = ρ2 (γ \ ρ2 ) and by (a-out-2) we get ; ρ1 : ρ2 ; ξ a!b. P ; ρ ; ξ .
2
Theorem 4 (Typing correspondence). ρ erase( P ) if and only if ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , for any ρ1 , ρ2 and ξ such that ρ1 ρ2 = ρ and ξ \ ξ = sym( P ). Proof. (⇐) Let ; ρ1 : ρ2 ; ξ P ; ρ ; ξ , where by Lemma C.2 we get ρ erase( P ). (⇒) Directly by Lemma D.4. 2
ρ1 ρ2 = ρ . By Lemma D.2 we get (ρ1 ρ2 )−ρ erase( P ). Since ρ1 ρ2 = ρ ,
References [1] Lucia Acciai, Michele Boreale, Spatial and behavioral types in the pi-calculus, Inf. Comput. 208 (10) (2010) 1118–1153. [2] Elli Androulaki, Artem Barger, Vita Bortnikov, Christian Cachin, Konstantinos Christidis, Angelo De Caro, David Enyeart, Christopher Ferris, Gennady Laventman, Yacov Manevich, Srinivasan Muralidharan, Chet Murthy, Binh Nguyen, Manish Sethi, Gari Singh, Keith Smith, Alessandro Sorniotti, Chrysoula Stathakopoulou, Marko Vukolic, Sharon Weed Cocco, Jason Yellick, Hyperledger fabric: a distributed operating system for permissioned blockchains, in: Rui Oliveira, Pascal Felber, Y. Charlie Hu (Eds.), Proceedings of the Thirteenth EuroSys Conference, EuroSys 2018, Porto, Portugal, April 23-26, 2018, ACM, 2018, pp. 30:1–30:15. [3] William Joseph Armstrong, Naresh Nayar, Kevin Patrick Stamschror, Management of a concurrent use license in a logically-partitioned computer, October 25, 2005, US Patent 6,959,291. [4] Nicola Atzei, Massimo Bartoletti, Tiziana Cimoli, Stefano Lande, Roberto Zunino, Sok: unraveling bitcoin smart contracts, in: Lujo Bauer, Ralf Küsters (Eds.), Proceedings, Principles of Security and Trust - 7th International Conference, POST 2018, Held as Part of the European Joint Conferences on Theory and Practice of Software, ETAPS, 2018, Thessaloniki, Greece, April 14–20, 2018, in: Lecture Notes in Computer Science, vol. 10804, Springer, 2018, pp. 217–242. [5] Pedro Baltazar, Luís Caires, Vasco T. Vasconcelos, Hugo Torres Vieira, A type system for flexible role assignment in multiparty communicating systems, in: Revised Selected Papers, Trustworthy Global Computing - 7th International Symposium, TGC 2012, in: LNCS, vol. 8191, Springer, 2012, pp. 82–96. [6] Paolo Baratti, Paolo Squartini, License management system, June 3, 2003, US Patent 6,574,612. [7] Massimo Bartoletti, Roberto Zunino, A calculus of contracting processes, in: Proceedings of the 25th Annual IEEE Symposium on Logic in Computer Science, LICS 2010, Edinburgh, United Kingdom, 11–14 July 2010, IEEE Computer Society, 2010, pp. 332–341. [8] Massimo Bartoletti, Roberto Zunino, Bitml: a calculus for bitcoin smart contracts, IACR Cryptology ePrint Archive 2018 (2018) 122. [9] Chiara Bodei, Viet Dung Dinh, Gian Luigi Ferrari, Checking global usage of resources handled with local policies, Sci. Comput. Program. 133 (2017) 20–50. [10] Ankush Das, Jan Hoffmann, Frank Pfenning, Work analysis with resource-aware session types, in: Anuj Dawar, Erich Grädel (Eds.), Proceedings of the 33rd Annual ACM/IEEE Symposium on Logic in Computer Science, LICS 2018, Oxford, UK, July 9-12, 2018, ACM, 2018, pp. 305–314. [11] James M. Ferris, Gerry E. Riveros, Offering additional license terms during conversion of standard software licenses for use in cloud computing environments, June 9, 2015, US Patent 9,053,472. [12] Adrian Francalanza, Marco Giunti, António Ravara, Pointing to private names. EasyChair Preprint no. 439, EasyChair, 2018. [13] Timothy S. Freeman, Frank Pfenning, Refinement types for ML, in: David S. Wise (Ed.), Proceedings of the ACM SIGPLAN’91 Conference on Programming Language Design and Implementation (PLDI), Toronto, Ontario, Canada, June 26–28, 1991, ACM, 1991, pp. 268–277. [14] Silvia Ghilezan, Svetlana Jaksic, Jovanka Pantovic, Jorge A. Pérez, Hugo Torres Vieira, A typed model for dynamic authorizations, in: PLACES, in: EPTCS, vol. 203, 2015, pp. 73–84. ´ Jovanka Pantovic, ´ Jorge A. Pérez, Hugo Torres Vieira, Dynamic role authorization in multiparty conversations, Form. [15] Silvia Ghilezan, Svetlana Jakšic, Asp. Comput. 28 (4) (2016) 643–667. [16] Marco Giunti, Catuscia Palamidessi, Frank D. Valencia, Hide and new in the pi-calculus, in: Bas Luttik, Michel A. Reniers (Eds.), Proceedings of the Combined 19th International Workshop on Expressiveness in Concurrency and 9th Workshop on Structured Operational Semantics, EXPRESS/SOS 2012, Newcastle Upon Tyne, UK, September 3, 2012, in: EPTCS, vol. 89, 2012, pp. 65–79. [17] Daniele Gorla, Rosario Pugliese, Dynamic management of capabilities in a network aware coordination language, J. Log. Algebraic Program. 78 (8) (2009) 665–689. [18] Hans Hüttel, Ivan Lanese, Vasco T. Vasconcelos, Luís Caires, Marco Carbone, Pierre-Malo Deniélou, Dimitris Mostrous, Luca Padovani, António Ravara, Emilio Tuosto, Hugo Torres Vieira, Gianluigi Zavattaro, Foundations of session types and behavioural contracts, ACM Comput. Surv. 49 (1) (2016) 3:1–3:36. [19] Naoki Kobayashi, Kohei Suenaga, Lucian Wischik, Resource usage analysis for the p-calculus, Log. Methods Comput. Sci. 2 (3) (2006). [20] Jovanka Pantovic, Ivan Prokic, Hugo Torres Vieira, A calculus for modeling floating authorizations, in: Christel Baier, Luís Caires (Eds.), Proceedings, Formal Techniques for Distributed Objects, Components, and Systems - 38th IFIP WG 6.1 International Conference, FORTE 2018, Held as Part of the 13th International Federated Conference on Distributed Computing Techniques, DisCoTec 2018, Madrid, Spain, June 18-21, 2018, in: Lecture Notes in Computer Science, vol. 10854, Springer, 2018, pp. 101–120. [21] Davide Sangiorgi, David Walker, The Pi-Calculus - A Theory of Mobile Processes, Cambridge University Press, 2001. [22] Nikhil Swamy, Juan Chen, Ravi Chugh, Enforcing stateful authorization and information flow policies in fine, in: Andrew D. Gordon (Ed.), Proceedings, Programming Languages and Systems, 19th European Symposium on Programming, ESOP 2010, Held as Part of the Joint European Conferences on Theory and Practice of Software, ETAPS 2010, Paphos, Cyprus, March 20-28, 2010, in: Lecture Notes in Computer Science, vol. 6012, Springer, 2010, pp. 529–549. [23] Vasco T. Vasconcelos, Fundamentals of session types, Inf. Comput. 217 (2012) 52–70. [24] José-Luis Vivas, Nobuko Yoshida, Dynamic channel screening in the higher order pi-calculus, Electron. Notes Theor. Comput. Sci. 66 (3) (2002) 170–184.