Abstract 1 Introduction 2 Background: the 𝝅-Calculus Language 3 A Type System for Visibility 4 Labelled Semantics 5 Adding Well-Bracketing 6 Conclusions and Future Work References Appendix A Section 2: Definition of the Operational Semantics Appendix B Additional Material for Section 3 Appendix C Additional Material for Section 5

First-Order Store and Visibility in Name-Passing Calculi

Daniel Hirschkoff ORCID LIP, ENS de Lyon, France Iwan Quémerais ORCID LIP, ENS de Lyon, France Davide Sangiorgi ORCID Università di Bologna, Italy
INRIA, Sophia Antipolis, France
Abstract

The π-calculus is the paradigmatical name-passing calculus. While being purely name-passing, it allows the representation of higher-order functions and store.

We study how π-calculus processes can be controlled so that computations can only involve storage of first-order values. The discipline is enforced by a type system that is based on the notion of visibility, coming from game semantics. We discuss the impact of visibility on the behavioural theory. We propose characterisations of may-testing and barbed equivalence, based on (variants of) trace equivalence and labelled bisimilarity, in the case where computation is sequential, and in the case where computation is well-bracketed.

Keywords and phrases:
process calculi, behavioural equivalence, type system
Copyright and License:
[Uncaptioned image] © Daniel Hirschkoff, Iwan Quémerais, and Davide Sangiorgi; licensed under Creative Commons License CC-BY 4.0
2012 ACM Subject Classification:
Theory of computation Process calculi
Related Version:
Extended Version: https://doi.org/10.48550/arXiv.2504.17350 [4]
Acknowledgements:
We have benefited from discussions with G. Jaber and E. Prebet.
Funding:
Work partly supported by the MIUR-PRIN project “Resource Awareness in Programming: Algebra, Rewriting, and Analysis” (RAP, ID P2022HXNSC).
Editors:
Patricia Bouyer and Jaco van de Pol

1 Introduction

The π-calculus is one of the best known process calculi. It has a handful of operators  – parallelism, input, output, restriction being the main ones  – with which it achieves an amazing expressive power. Yet, it has a rich algebraic theory and a wide spectrum of proof techniques. In the π-calculus, computation is communication, by means of message-passing synchronisations between processes. Names are the communication units; new names may be created, and may themselves be exchanged in communications. When used for modelling, π-calculus is normally typed, so to be able to support structured data values, beginning with basic first-order values such as integers and booleans.

The π-calculus has been advocated as a model to interpret, and give semantics to, languages with higher-order features. For instance, the representation of functions as π-calculus processes has been widely studied, beginning with Milner’s seminal work [16]. Usually, higher-order languages include forms of store. It is therefore important to understand how expected semantic properties of store can be captured in a language for pure concurrency such as the π-calculus.

An aspect of store with strong semantic consequences is the distinction between higher-order and first-order store. The term “first-order store” refers to a memory model where variables can hold only basic data types such as integers and booleans. This contrasts with a higher-order store, where variables can also store functions, or code, or references to these. Limiting the store to first-order data makes it easier to reason about program behaviours, and verify behavioural properties. It may also enhance security and predictability guarantees by preventing unintended behaviours associated with dynamic function storage and code injection. A striking example of a property that may be broken with higher-order store is termination. For instance, the simply-typed λ-calculus is strongly normalising and therefore terminating. This property is maintained by the addition of first-order store, but not with higher-order store, as functions may recursively reference and invoke each other through the store. In game semantics of higher-order languages, the distinction between first-order and higher-order store has led to studying the concept of visibility. Intuitively, visibility ensures us that each move in a computational game is justified by prior interactions. With the introduction of higher-order store, the visibility condition has to be relaxed, reflecting the added complexity in tracking information flow within a program.

The goal of this paper is precisely to understand the meaning of first-order store and visibility within the π-calculus. In functional languages based on the λ-calculus, imposing first-order store is simply determined by the constraint that all references may only store first-order values. In the π-calculus, in contrast, there is no explicit notion of reference, and therefore the meaning of “first-order store” requires some care. In π-calculi, a piece of store is usually represented by an output message. For instance h¯5 may be thought of as the statement that name h currently contains 5. A process that inputs at h and then re-emits a message at h, such as h(z).h¯z+1, is a process that acts on such a store. In this case, h is a first-order name, hence h implements a piece of first-order store. An example of higher-order store is given by the process

P=defa(b).((b¯(d).!d.R)|c.b¯(d).d.R) (1)

Here, b¯(d) is a bound output, and represents the output of a “new” name d, and similarly for b¯(d); whereas, e.g., d.R and c.Q (where Q is b¯(d).d.R) represent inputs in which no value is exchanged (i.e., d and c carry unit values). In P, name a is higher-order, in that a carries a (pointer to a) service. In the input at a, the service name received in the input (the parameter b) is used after the input, but it is also stored, and used later when c is invoked. In other words, the visibility of c (the services that c may call when invoked) depends on interactions that have occurred earlier, at a. For this reason, P implements a form of higher-order store. When this does not happen, that is, the visibility of a higher-order name (the set of services that may be called when the name is invoked) may be determined at the point in which the name is created, the process implements a form of first-order store. (The word “service” is freely used, here and elsewhere, to indicate the input end of a name; in π-calculus, a name may have multiple input occurrences, in arbitrary syntactic positions within a process, in contrast with, say, the function declarations in functional languages, which are supposed to be unique.)

The amazing expressive power of the π-calculus also makes the contexts of the calculus very discriminating; as a consequence, behavioural equivalences, which are supposed to be preserved by the contexts of the calculus, are rather demanding relations. A well-established way of imposing constraints on the set of legal contexts, thus obtaining usefully coarser behavioural equivalences, is to adopt behavioural type systems. Types may be used in order to capture communication patterns on the usage of names, such as capabilities, linearity, sessions, and so on, e.g., [19, 11, 6, 1]. Type systems have also been designed to capture specific properties of processes, such as termination, deadlock-freedom, lock-freedom, e.g., [24, 12, 18].

A further step is then to tune the proof techniques of the π-calculus to such type systems, so to be able to actually prove the behavioural equalities that only hold in presence of types. For instance, in the case of may testing (or contextual equivalence) this may yield to refinements or modifications of the notion of trace equivalence; whereas in the case of barbed equivalence this may lead to refinements or modifications of the standard notion of labelled bisimilarity. The resulting proof techniques must be sound with respect to initial contextually-defined relations; ideally, they should also be complete.

In this paper we propose a type system that guarantees first-order store in π-calculus processes. The type system makes use of visibility functions, that is, partial finite functions that specify, for each higher-order name b that may occur free in a process, the set of services (i.e., higher-order names) that may be invoked when a call at b is made. In order to better understand the behavioural effects of visibility, we combine it first with sequentiality and then with well-bracketing. “Sequentiality” intuitively indicates the existence of a single thread of computation. That is, at any point there is a single process that is active and decides what the next computation step can be. In the encodings of the λ-calculus  [16, 21], a process is active, i.e., it carries the thread, when it contains an unguarded output at a higher-order name. When encoding λ-calculi with first-order references, an active process may also expose the thread by exhibiting an input at a first-order name. We follow such a convention also in the paper: higher-order names carry the thread via outputs, first-order names via inputs (other choices technically would however be possible). Sequentiality allows us to expose, in isolation, the causality properties of service calls, within a standard (interleaving) semantics. These aspects would be partially or totally obscured by the presence of other concurrent threads.

In higher-order languages, the effects of having first-order store are particularly strong in absence of control operators; that is, using a terminology borrowed from game semantics, in a “well-bracketed” setting, where the call-return interaction behaviour between a term and its context follows a stack discipline. We therefore also consider the refinement of our visibility-based type system under the well-bracketing hypothesis. To see an example of the effect of visibility, consider the following well-bracketed example:

𝝂h(h¯0|a¯(c,q).(!c.h(z).h¯z+1|q(y).Q))

Here, an external service a is called, exporting a local service c capable of incrementing a private reference h, and with a return channel q. If visibility holds, then the external environment cannot store c. Therefore, after providing an answer at q , the environment is unable to call c again, thus incrementing h, unless an access to c is explicitly provided again (by process Q). This property may be used to perform optimisations, possibly including garbage-collection of the service c if at some point c is not used anymore in Q.

We then study characterisations for both may testing and barbed equivalence, as special forms of trace equivalence and of labelled bisimilarity. Following the tradition of testing, the language includes special success signals, that are used by testers (i.e, processes running in parallel with the testees), and may be used at any time, to report success.

When developing such characterisations, some care is necessary so to distinguish between the visibility of the tested and of the tester processes, as they need not be the same. For this, we introduce visibility-constrained LTSs, in which process transitions are constrained by a visibility function, intuitively expressing the possibility for processes to perform a certain transition given a certain visibility function for the external observer. As a consequence of the transition, the visibility function may need to be updated, so to yield the visibility function for the next transition. In the case of well-bracketing, the constraints given by visibility have to be coupled with those given by the stack names used to track well-bracketing (and again, a distinction has to be made between the stacks for the testers and those for the testees). Based on these LTSs, we introduce forms of trace equivalence and of labelled bisimilarity that are proved to be sound and complete, for may testing and barbed equivalence, both in the case of sequentiality and in that of well-bracketing.

We present the version of the π-calculus with higher-order and first-order names in Section 2. In Section 3, we define the type system implementing visibility for sequential processes. We define typed labelled transitions and present labelled characterisations of behavioural equivalences in Section 4. Section 5 is devoted to the extension with well-bracketing. For lack of space, the results about labelled bisimilarities are presented in [4].

2 Background: the 𝝅-Calculus Language

The π-calculus language that will be used is called, technically, Internal π (πI) [22] (all channels exchanged are fresh – no free object outputs), with the addition of first-order values (such as integers and booleans), and expressions that evaluate to first-order values, called first-order expressions. We do not specify what exactly first-order values and first-order expressions are. We simply assume that, in a closed process, a first-order expression evaluates to a first-order value. Moreover, only the output capability of names may be exported. This means that, for instance, in an input a(b).P name b may only be used in output in P. This constraint is often followed in theory and applications of the π-calculus, as it simplifies various technical matters.

We assume that names are distinguished (partitioned) into higher-order names and first-order names, and success names. Higher-order names are the ordinary πI names; first-order names may only carry first-order values, and they may not be passed around (the second constraint simplifies the technical details, though it is not mandatory, see Section 3). In later sections, first-order names will be used to represent references. The fact that these names may only carry first-order values, together with constraints on visibility, will ensure that the calculus does not have (implicit or explicit forms of) higher-order store. The success names are used, in the tradition of testing equivalences, by tester processes so to report results of experiments on tested processes (thus, the processes compared in the examples of the paper do not contain success names).

The calculi in the paper will be typed. For simplicity we define our type systems as refinements of the most basic type system for π-calculus, namely Milner’s sorting [15], in which names are partitioned into a collection of types (or sorts), and a sorting function maps types onto types. We assume that there is a sorting system under which all processes we manipulate are well-typed. Thus, the sorting system separates higher-order and first-order names; moreover we assume that first-order names are monadic, and that higher-order names carry a pair of a first-order value and a higher-order name. Thus a¯v(b).P is the output of the first-order value v and of the fresh higher-order name b at the (higher-order) name a, with continuation P. When writing examples, we allow different sortings; for instance, writing a.P and b¯.Q for inputs and outputs in which no value is exchanged.

Table 1: The syntax of the calculus.
[Higher-order names, HO]a,b,c[First-order expressions]e,f[First-order names, FO]h,k[First-order variables]x,y[Success names]ω[First-order values]v,w
[Inputs]α::=a(x,b)h(x)[Outputs]α¯::=a¯e(b)h¯eω[Processes]P,Q,R::=α.Pα¯.P!α.PP|Q𝝂aP𝝂hP  0P+Q𝚒𝚏e=f𝚝𝚑𝚎𝚗P𝚎𝚕𝚜𝚎Q

The syntactic categories of the calculus are presented in Table 1. As usual, input and restriction are binding constructs, and give rise to the expected definitions of free and bound names. An expression or a process is closed if it does not have free (first-order) variables. It is intended that transitions are defined on closed processes.

The definition of structural congruence, written , and of the strong and weak (untyped) labelled transitions, written μ, , and μ^, are standard and are given in Appendix A (later we will introduce typed variants of the LTS). We note 𝚏𝚗(P) (resp. 𝚏𝚗(μ)) the set of free names of P (resp. μ). We sometimes abbreviate reductions PτP as PP.

As behavioural equivalences we consider both may-testing and barbed equivalence. Both relations are contextual, in that they are defined by requiring a closure under all “observers”. They both use “barbs” (or “success”) signals; barbed equivalence, in addition, makes use of a bisimulation game on reductions. We write ω to indicate the possibility of exhibiting an ω barb, possibly after some reductions; i.e., Pω holds if there is P with PP and P has an unguarded occurrence of ω. Thus intuitively two processes are behaviourally equal if they can produce “the same barbs” under all legal observers running in parallel with them. As we are in a typed setting, observer and tested processes should have compatible typings. The meaning of “compatible” depends on the specific type system. For visibility, the meaning will be specified in Sections 3 and 5. We write ΔP, and say that P is a Δ-process, if P is typable under Δ, and ΔP,Q if both ΔP and ΔQ hold. Behavioural equivalences are defined on closed processes; they are extended to open processes (i.e., processes with free first-order variables) in the usual manner, by considering all possible closing substitutions. We only consider weak behavioural equivalences (i.e., equivalences that abstract from internal moves of processes, the reductions), as these are, in practice, the most useful ones.

Definition 1 (May testing).

Suppose that Γ,Δ are compatible. Then two Δ-processes P and Q are may testing equivalent at Γ, written PΔΓQ, if for all Γ-process R and success name ω, we have (R|P)ω iff (R|Q)ω.

Definition 2 (Barbed bisimilarity and equivalence).

Barbed bisimilarity is the largest symmetric relation . s.t. P.Q implies:

  1. 1.

    whenever PP, there exists Q such that QQ and P.Q;

  2. 2.

    for each ω, if Pω then also Qω.

Suppose that Γ,Δ are compatible. Then two Δ-processes P and Q are barbed equivalent at Γ, written PΔΓQ, if for all R with ΓR it holds that P|R.Q|R.

We write PQ (resp. PQ) when PΔΓQ (resp. PΔΓQ) holds under any typing Δ for P,Q and any Γ compatible with Δ.

We now introduce some notations that will be useful below. In the paper we use partial functions whose codomains are finite powersets. If Δ is such a function, then Δ;iA is the extension of Δ in which i is mapped onto A, assuming that i is not in 𝚍𝚘𝚖(Δ)𝚌𝚘𝚍𝚘𝚖(Δ) ; conversely Δi is the restriction of Δ in which the entry for i is erased, both in the domain and codomain of Δ. We also write iA,j as an abbreviation for i(A{j}); and Δi (resp. Δi) means that Δ is (resp. is not) defined on i. Function Δ1Δ2 has domain 𝚍𝚘𝚖(Δ1)𝚍𝚘𝚖(Δ2), and then is defined as (Δ1Δ2)(p)=Δ1(p)Δ2(p); and likewise for Δ1Δ2. We write Δ1Δ2 if 𝚍𝚘𝚖(Δ1)𝚍𝚘𝚖(Δ2), and for each i𝚍𝚘𝚖(Δ1), we have Δ1(i)Δ1(i).

3 A Type System for Visibility

Our type system for visibility is built on top of that for sequentiality [3]. While visibility could be defined as a standalone notion, the combination with sequentiality makes the behavioural effects sharper and easier to grasp.

Intuitively, sequentiality ensures us that at any time at most one interaction can occur; i.e., there is a single computation thread. A process that holds the thread, called active, decides what the next interaction can be. It does so by offering a single particle (input or output) that controls the thread. A given name may exercise the control on the thread either in output or in input. Following [3], we require that, in higher-order names, the thread is carried by outputs, whereas, in first-order names, it is carried by inputs. An input that carries the thread maintains the thread, whereas an output releases it. (These appear to be, practically, the most interesting combinations; other combinations could be adopted, with the expected modifications.) Thus, for instance, the following process P is well-typed:

P=def(h(x).a¯x(b).(b(z,c).Q|h¯x))|k¯v

The initial particles in P are the input at h and the output at k; however only the input at h carries the thread, as h and k are first-order. Underneath the input, the thread is maintained and released in the output at a (the thread will be acquired by the process in the external environment performing the input at a); later, when the input at b is performed, process Q obtains the thread back. Sequentiality however does not exclude non-determinism: e.g., an output particle may have the possibility of interacting with different inputs.

The type system for visibility intuitively allows us to specify which possible higher-order outputs can be performed by a process that becomes active. Type environments are partial functions, called visibility functions, acting on higher-order names and, for active processes, on the special token , representing the active thread. (Later, when studying well-bracketing, type environments will have both a visibility function and a name stack.)

Definition 3 (Visibility function).

A visibility function is a finite partial function Δ:𝙷𝙾{}𝒫𝚏𝚒𝚗(𝙷𝙾). Moreover the function should be transitive, that is, for all o𝚍𝚘𝚖(Δ), if Δa and aΔ(o), then Δ(a)Δ(o).

To see the use of , suppose Δ()={a,b}; this means that a Δ-process is active, and may only perform outputs at a and b, as in the following process:

a¯v(c).c(d).b¯(w).0

Name c is created in the output at a and therefore c inherits a’s visibility.

Similarly, if Δ(d)={a,b} then, in a Δ-process d(x,c).P, the continuation P of the input at d may only perform outputs at a, b or at c (as c is the higher-order name received in the input). The use of visibility functions also allows us to rule out implicit forms of higher order store; in the following example, p,q are higher order names used for continuations.

When extending Δ, we impose in Δ;aA that a𝚍𝚘𝚖(Δ)𝚌𝚘𝚍𝚘𝚖(Δ), that is, a is fresh for Δ. Similarly, Δ;A is defined only when 𝚍𝚘𝚖(Δ).

Example 4 (Implicit forms of higher-order store).

In the λ-calculus, if a term without higher-order references is well-bracketed then it necessarily obeys visibility. In our calculus, even though we do not have explicit higher-order references, we can simulate higher-order store. Consider

P=defa¯(b,p).b(n,c,q).q¯n.p(m).c¯.0

In P the visibility Δ(p) is defined when the output at a is made, therefore cΔ(p), and the final output at c breaks visibility; indeed, the input at b, which justifies the output at c, is answered by the output at q before the output at c.

Transitivity ensures us that the visibility functions, viewed as “named sets”, represent transitive sets. Transitivity is needed to guarantee the behavioural expectations of visibility. If a process P calls a service a, with actual (higher-order) parameter b, then an output triggered by such a call (and possibly directed back to P) should be either at b or at a name in the visibility of a; however, the server a might call an external service c; this call should not allow an increase of the visibility associated to a; hence the transitivity constraint that the visibility of c is contained in that of a. Technically, transitivity is necessary to ensure preservation of typing under reduction (see Theorem 10 and Example 11).

Remark 5 (Transitivity and functional languages).

The issue of transitivity does not arise in the semantics of purely functional languages such as the λ-calculus [7]: visibility functions do appear, but the domain and codomain of such functions are disjoint (technically, in the game semantics terminology, the domain contains names introduced by Player, whereas the codomain contains names introduced by Opponent). This makes transitivity trivial.

In the typing of a parallel composition, the visibility function has to be split between the two components of the composition. This is important for elements of the domain of the function that are linear, and therefore may only appear in one, but not both, components; this is the case for , and the linear continuation names that will be introduced in Section 5.

Definition 6 (Split).

Let Δ be a visibility function, we define 𝚜𝚙𝚕𝚒𝚝(Δ) as the set of pairs (Δ1,Δ2) such that Δ1Δ2=Δ and 𝚍𝚘𝚖(Δ1)𝚍𝚘𝚖(Δ2).

Figure 1: Typing rules for visibility.

The typing rules are given in Table 1. We comment on a few of them. Rule 𝙾-𝙷𝙾 specifies that an output at a HO name a owns the thread, and that name a must be in the current visibility. In the continuation P (which is not active) the visibility for b is determined by the current visibility Δ() together with b itself, to allow for recursive calls at b. Symmetrically, in rule 𝙸-𝙷𝙾, a process performing an input at a acquires the thread, with a visibility given by Δ(a) plus the received name b. A replicated input is well-typed only if it is not active (rule 𝚁𝙴𝙿). When typing parallel composition, we use split to insure that at most one of the components holds the thread. We simply remove the name from Δ when typing a restriction (rule 𝚁𝙴𝚂-𝙷𝙾). Visibility plays no role in rules 𝙸-𝙵𝙾 and 𝙾-𝙵𝙾; the only checks made are given by sequentiality, concerning the respect of the thread.

Example 7.

Consider

P=defa(x,b).b¯x+1(d).a(x,b).b¯x+x(d).0|a(x1,b1).b1¯x1(d1).d1(d2).c¯x+1(c1).0

The process has three inputs at a; the first two are sequential, and make no requirements on visibility, as their continuations only perform outputs at names received in the input; the third one, in addition, has the effect of creating a name d1, whose input may activate an output at the free name c. This input requires that in the visibility Δ of P, we find cΔ(a).

Example 8.

(In this example, we ignore the first-order components of actions, as they are not relevant.) A process of the form

P=defa¯(b).(Q|c(d).b¯(d).R)

is not typable: the initial visibility of c may not include b, which is created fresh by a; yet, P may perform an output at b after the input at c. Indeed, while P does not directly create a form of higher-order store, it may do so indirectly: the external environment, after completing the treatment of the initial call at a, is supposed to “forget” the higher-order name b. However, this is not the case, as the environment may regain access to b by invoking the (unrelated) name c. In contrast P would become typable (in the straightforward extension of our type system with polyadicity) if the initial output at a would be replaced by a¯(b,c): now c becomes a fresh name, initially unknown, and created in the initial output, together with b, so that the visibility for b and c can be the same and can include both names.

The following lemma shows that a visibility function may always be enlarged (both in the domain and codomain), as long as sequentiality (i.e., being defined on ) is respected.

Lemma 9 (Weakening).

Suppose Δ1P, Δ1Δ2, and (Δ2 iff Δ1). Then Δ2P.

Some other technical lemmas that are used in proofs are presented in Appendix B.1.

Theorem 10 (Subject reduction).

Suppose ΔP and P𝜇P. We have:

  • if μ is a τ action or a first-order input, then ΔP; the same holds if μ is a first-order output and Δ;

  • if μ=a¯v(b) then aΔ() and Δ;bΔ(),bP;

  • if μ=av(b) and Δ, then Δ;Δ(a),bP.

Example 11.

Transitivity of visibility functions is necessary. Indeed, consider process P=defa.b¯.Q|a¯, and the non-transitive function Δ=a{a,b},a. We have ΔP. However P𝜏b¯.Q, with Δb¯.Q, violating Subject Reduction (Theorem 10).

To adapt the generic definitions of behavioural equivalence in Section 2 to the type system for visibility, we only have to specify the meaning of compatibility between typing environments (which in our case are visibility functions). Compatibility means ensuring that processes typed under the two typing environments cannot both be active.

Definition 12.

Two typings Δ1 and Δ2 are compatible if 𝚍𝚘𝚖(Δ1)𝚍𝚘𝚖(Δ2).

We discuss some examples of equivalences in which the behavioural constraints imposed on legal observers by visibility are essential: the equivalences would otherwise be broken.

Example 13.

Consider a process

P=defa¯(b,c).P for P=def(b(d).R)|c(c1).a¯(b,c).c(c2).b¯(d).Q

where we assume b does not occur in Q and R. Process P interrogates an external service a, providing access to local services b and c, and the derivative is P. Now, P may either be interrogated at b, or at c. In the former case, the output b¯(d).Q becomes dead code (as the environment may not install any input at b). In the latter case, the environment is again called at a; now, since visibility ensures us the environment cannot remember b, the input and the output at b in P may only interact with each other; we can therefore inline the call at b. We can express this behaviour using expansion as follows:

Pa¯(b,c).(b(d).(R|c(c1).a¯(b,c).c(c2).0)+c(c1).a¯(b,c).c(c2).τ.𝝂d(Q|R{d/d}))

where 𝟎 indicates an active process that cannot perform any action (e.g., 𝛎b2(b2¯.0)). (This equality holds under any visibility, hence we use the symbol .)

If we replaced the second output at a with an output at a different free name, say a, then the processes could still be typable, and the equalities above would still hold. However, the equalities would not hold if we replaced the second output at a with an output at c1. Indeed, while the environment may not store b or c for using them in a later call at a (or at an unrelated name such as a), the environment is allowed to use b and c within services that are created following the first call at a; for instance, the environment could be

a(b,c).c¯(c1).!c1(c1).b¯(d′′).0

The following example illustrates the use of visibility to perform garbage-collection on names that will never be used. We refer to Appendix B.3 for the full definition of the corresponding pruning function.

Example 14.

Consider a typing environment Δ, a Δ-process

P=def!a.Q1|!b.c¯.!a.Q2|!d.a¯.0

and a visibility Γ compatible with Δ such that ΓΔ is transitive. Γ is intended here to represent the observer’s visibility. Suppose aΓ(); that is, the observer is active but its current visibility does not include a (which may however be in the visibility of other names in Γ). We then have PΓΔ!b.c¯.0. The pruning is possible because, intuitively, the transitivity of ΔΓ ensures us that an observer, whenever active, cannot have a in its current visibility. For instance, if the observer interrogates b, then the transitivity of the visibility functions ensures us that aΔ(b); then cΔ(b) (which is necessary for P to be typable) gives us also aΓ(c). Similarly, exploiting transitivity, we deduce that also dΓ(), and that an observer may never be able to interrogate d; thus we can also remove the input on d.

4 Labelled Semantics

4.1 Trace-based proof techniques

The definitions of may-testing and barbed equivalence make use of contextual quantifications. We study here proof techniques for them, using labelled transitions, without such quantifications. These proof techniques will be expressed as forms of trace equivalence and labelled bisimilarity. The definition of may-testing makes use of contextual quantifications. We study here proof techniques without such quantifications, as forms of trace equivalence. For lack of space, analogous proof techniques for barbed equivalence are only reported in [4]. The first step is to express the transitions for a process that are allowed by an observer subject to certain visibility constraints. We call these the type-allowed transitions. They are of the form [Γ]P𝜇[Γ]P, to be read “an observer that has visibility Γ allows process P to make a transition μ and, as a result of the transition, the process becomes P and the visibility of the observer becomes Γ’. Type-allowed transitions are defined by the rules in Figure 2. Intuitively, an observer typable under Γ can initially test inputs of processes at names in Γ(), if Γ, and outputs of processes in 𝚍𝚘𝚖(Γ) otherwise. The weak transitions and μ, are defined in the usual manner from the strong one; for instance, [Γ]P𝜇[Γ]P holds if [Γ]P[Γ]P′′, and [Γ]P′′𝜇[Γ]P′′′, and [Γ]P′′′[Γ]P, for some P′′ and P′′′.

Figure 2: Visible LTS.

An action τ is called a reduction (or an internal action); the remaining actions are called interactions. We use 𝒯 to range over traces, which are finite sequences of interactions μ1μn (n0) in which the bound names are all distinct and different from the free names (the definition of bound and free names is as for processes, viewing a trace as a sequence of prefixes). A trace μ1μn is trace of P0 under visibility Γ0 if there are Pi,Γi with [Γi]Piμi[Γi+1]Pi+1, for 0i<n.

Definition 15 (Typed trace equivalence).

Two Δ-processes P and Q are trace equivalent at Γ, written PΔΓQ, if Δ, Γ are compatible and P, Q have the same sets of traces under Γ.

We show the main compositionality lemmas, and a trace-based characterisation of may testing. Other technical lemmas needed in proofs may be found in Appendix B.2.

Lemma 16 (Restriction).

If PΔΓQ then also 𝛎aPΔaΓa𝛎aQ.

Lemma 17 (Input).

If PΔ;Δ(a),bΓ;bΓ(),bQ and then also a(x,b).PΔΓa(x,b).Q.

Lemma 18 (Output).

If PΔ;bΔ(),bΓ;Γ(a),bQ and then also a¯e(b).PΔΓa¯e(b).Q.

Lemma 19 (Parallel composition).

Suppose PΔΓQ and (Γ1,Γ2)𝚜𝚙𝚕𝚒𝚝(Γ). Then Γ2R implies P|R(ΔΓ2)+Γ1Q|R where ()+ indicates the transitive closure.

In the proof of Lemma 19, a trace of P|R is split into a trace for P and one for R. We have then to ensure that the condition of the lemma are maintained throughout the trace, notwithstanding modifications of the visibility functions. Some care is needed in case of synchronisations between P and R, where the typing of the external observer has to remain the same; we also use the restriction Lemma 16. Other cases also exploit the extension Lemma 36, and the transitivity of the visibility function, to make sure that the views on free names are not increased along the trace.

Theorem 20 (Characterisation of may testing using trace equivalence).

Suppose ΔP,Q then PΔΓQ if and only if PΔΓQ.

The sketch of the proofs is the same as for characterisations of may testing with trace equivalence in untyped calculi, exploiting substitutivity properties of trace equivalence in the case of Soundness, and reason by contradiction in the case of Completeness. In addition, one has to take care of the observer visibilities, how it changes, and use type-allowed transitions. A similar results of characterisation also hold for barbed equivalence, using a typed form of labelled bisimilarity, and are presented in [4].

We can use typed trace equivalence to prove equalities such as those in Examples 13 and 14; the proofs are simple, following the definition of the equivalence and exploiting type-allowed transitions. See also Appendix B.3 for the proof about the pruning function that generalises Example 14. (Similarly, the proofs can be carried out for barbed equivalence, using the labelled bisimilarity in [4].)

4.2 Visibility property on traces

We formalise the link between our type system and the notion of visibility in game semantics [7]. The reader not familiar with game semantics may safely skip the section. In game semantics, the notions of visibility and well-bracketing are defined based on a justification relation between moves performed by Player. These moves correspond to interactions on higher-order names in our setting, and the notion of justification can be formulated as follows.

Definition 21.

Let μ1,μ2 be two interactions at HO names. We say that μ1 justifies μ2, noted μ1μ2, if: (i) either μ1=av(b) and μ2=b¯v(c), or (ii) μ1=a¯v(b) and μ2=bv(c). When this is not the case, we write μ1μ2.

μ1μ2 captures the dependency induced by the fact that μ2 performs an interaction at a name that has been previously introduced by μ1. In contrast with the situation in game semantics, though, there is no notion of question and answer in our setting.

We can now define the notion of view. In the definition below, we allow a starting visibility A, because we want to consider processes that already have some knowledge about the observer (Opponent).

Definition 22 (View).

Given A𝙷𝙾, we define the view with starting visibility A of a trace 𝒯, written 𝚟𝚒𝚎𝚠A(𝒯), as follows:

where 𝚗𝙷𝙾(μ) denotes the set of higher-order names appearing in the action μ.

Views capture the idea that when an action is justified by another one, the names created in between must have been forgotten, otherwise this would mean that the process had the ability to store these names in order to reuse them. In the last clause in Definition 22, the action is justified by an action that happened before the beginning of the trace, therefore it has the starting visibility. In particular, 𝚟𝚒𝚎𝚠(𝒯) yields the usual definition in game semantics.

Definition 23 (Respecting views).

Consider A𝙷𝙾, a trace (μ0μn) respect views under starting visibility A if 𝚏𝚗(μ0)A and 1in,𝚏𝚗(μi)𝚟𝚒𝚎𝚠A(μ0μi1)

Lemma 24.

Consider Δ,Γ,P such that ΔP, Γ is compatible with Δ, and ΔΓ is transitive. Let A=(ΓΔ)(), then every trace of P under visibility Γ respects views with starting visibility A.

The idea of the proof is that for a trace (μ0μn) there exist P0,,Pn+1, Δ0,,Δn, Γ0,,Γn+1 such that P0=P, Δ0=Δ, Γ0=Γ and for all 0in, [Γi]Piμi[Γi+1]Pi+1 and ΔiPi. We show by induction that for each 1in, (ΓiΔi)()𝚟𝚒𝚎𝚠A(μ0μi1); it thus follows that the trace respects views under starting visibility A. The condition of ΔΓ being transitive is crucial, otherwise (ΓiΔi)() could grow in unwanted ways.

5 Adding Well-Bracketing

5.1 Type system

In the previous sections we have studied visibility in connection with sequentiality. In this section we do the same for a refinement of sequentiality, namely well-bracketing. We begin by reviewing well-bracketing, following [3], and then outline how visibility is accommodated.

From sequentiality to well-bracketing.

In languages without control operators, well-bracketing intuitively means that return-call interactions among terms follow a stack-based discipline. In a well-bracketed system, a service that is interrogated, say S, acquires the thread and is supposed to return a final result (unless the computation diverges) thus releasing the thread. During its computation, S may however interrogate another service, say T, which, upon completion of its computation, will return the result to S; service S must receive the answer from T before returning the final result. The implementation of this policy requires continuation names, that are used to handle the return messages. When a service is interrogated, it receives a fresh continuation name that is used once, in output, to deliver the final result. Accordingly, a client that has interrogated the service will use the continuation name in input to receive the result. Thus continuation names are linear [11]  – they may only be used once. In contrast with [3], we do not require receptiveness [23]  – the input-end of the name needs not be made available as soon as the name is created. Enforcing only linearity allows us to gain flexibility. To ensure the well-bracketing policy, and linearity of continuation names, the type system in [20] makes use of stacks.

Definition 25 ([20]).

A stack, σ, is a sequence of input- and output- tagged continuation names, in which the input and output tags alternate:

Moreover: a name may appear at most once with a given tag; and, if a name appears with both tags, then the input occurrence should immediately follow the output occurrence.

We write pOσ (resp. pIσ) if there is an occurrence of pO (resp. pI) in σ. We write pσ if either pOσ or pIσ.

Intuitively, a stack expresses the expected usage of the free continuation names in a process. For instance, if P can be typed using stack p1:𝚘,p2:𝚒,p3:𝚘,p3:𝚒,p4:𝚘, then p1,..,p4 are the free continuation names in P; among these, p1 will be used first, in an output; then p2 will be used, in an input interaction with the environment. P possesses both the output and the input capability on p3, so it shall perform a reduction at p3; the computation for P terminates with an output at p4. This behaviour however concerns only the free continuation names of P: at any time when an output usage is expected, P may decide to create a new continuation name and send it out, maintaining its input end.

Visibility.

We now discuss how to combine the visibility in Section 3 with well-bracketing. Higher-order names are partitioned into the set SER of server names, and the set CON of continuation names. Now a,b,c range over server names, while p,q,r range over continuation names. By convention, server names carry a triple consisting of a first-order value, a server name and a continuation; whereas continuations carry a first-order value and a server name. Accordingly, outputs on higher-order names are of the form a¯n(b,p) and p¯n(b), and similarly for inputs. First-order names are as before.

Visibility functions are then transitive partial functions from 𝚂𝙴𝚁𝙲𝙾𝙽{} to 𝒫𝚏𝚒𝚗(𝚂𝙴𝚁𝙲𝙾𝙽). These functions handle server and continuation names essentially like HO names in Section 3.

Typing environments include a stack; thus a typing environment is a pair Δ|σ of a visibility function and a stack. In the typing rule for parallel composition, we rely on splitting (defined as in Section 3) as well as on 𝚒𝚗𝚝𝚎𝚛(σ,1σ)2, the interleaving of stacks σ1 and σ2.

Definition 26 (Interleaving).

We write σ1𝚒𝚗𝚝𝚎𝚛(σ𝟸;σ𝟹) if (i) σ1 is a stack, and (ii) σ is an interleaving of σ2 and σ3 as by the following inductive rules:

  1. 1.

    𝚒𝚗𝚝𝚎𝚛(;)

  2. 2.

    p:𝚘,σ1𝚒𝚗𝚝𝚎𝚛(σ𝟸;𝚙:𝚘,σ𝟹) if σ1𝚒𝚗𝚝𝚎𝚛(σ𝟸;σ𝟹)

  3. 3.

    p:𝚘,σ1𝚒𝚗𝚝𝚎𝚛(𝚙:𝚘,σ𝟸;σ𝟹) if σ1𝚒𝚗𝚝𝚎𝚛(σ𝟸;σ𝟹)

  4. 4.

    the same as (2) and (3) with p:𝚒 instead of p:𝚘

Figure 3: Typing rules with visibility and stack.

If a name appears both in σ2 and in σ3 with the same tag, then 𝚒𝚗𝚝𝚎𝚛(σ𝟸;σ𝟹) is empty. Figure 3 gives the typing rules. The rules combine the handling of visibility and the update of the stack. For instance, in rule 𝙾-𝚜𝚎𝚛, newly created names b and p are added to the visibility when typing the continuation P, and pI is added on top of the stack, meaning that P shall perform an input at p before interacting on other continuation names. The output capability on p is transmitted along the output at a; correspondingly, in rules 𝙸-𝚜𝚎𝚛𝟷 and 𝙸-𝚜𝚎𝚛𝟸, pO is added to σ. In contrast with [3], we do not impose σ= in rule 𝙸-𝚜𝚎𝚛𝟷, as we do not enforce input receptiveness on continuation names. Performing inputs and outputs at continuation names has the effect of consuming the corresponding particle on top of the stack. The stack is empty when typing a replicated input, so to avoid duplication of continuation names. Rules 𝚂𝚄𝙲𝙲, 𝙾-𝙵𝙾, 𝙸-𝙵𝙾, 𝚁𝙴𝚂-𝙵𝙾, 𝚂𝚄𝙼 and 𝙸𝙵 are like in Figure 1, and are omitted.

Theorem 27 (Subject reduction).

Suppose Δ|σP and P𝜇P. We have:

  • if μ=τ, then either σ=pO,pI,σ′′ with p𝙽𝚌𝚘𝚗𝚏𝚗(P), in which case Δp|σ′′P,

    or Δ|σP ;

  • if μ=a¯v(b,p) then aΔ() and Δ;bΔ(),b;pΔ(),b|pI,σP ;

  • if μ=p¯v(b) then σ=pO,σ′′, pΔ() and Δ;bΔ(),b|σ′′P ;

  • if μ=av(b,p) and Δ then Δ;Δ(a),b,p|pO,σP ;

  • if μ=pv(b) and Δ then σ=pI,qO,σ′′ and Δp;Δ(p),b|qO,σ′′P ;

  • if μ=hv or (μ=h¯v and Δ) then Δ|σP.

As previously, we have to define compatibility of typing environments so to be able to use the contextual forms of behavioural equivalence from Section 2.

Definition 28.

Δ1|σ1 and Δ2|σ2 are compatible if Δ1 and Δ2 are compatible (as by Definition 12) and 𝚒𝚗𝚝𝚎𝚛(σ,1σ)2.

Example 29.

Consider the process

P=def𝝂h(h¯5|a¯(b,q).(!b(p).h(x).(h¯x+1.0|p¯.0)|q.h(x).h¯x.c¯(d,r).r.h(y).h¯y.𝚒𝚏x=y𝚝𝚑𝚎𝚗s¯.0𝚎𝚕𝚜𝚎 0))

Here h is used as an integer reference, initially set to 5. The process calls a service a, giving access to a name b that can be used to increment the reference. When the call at a returns (at q), the reference is read twice and, in between, a call at c is made. Without visibility, the two values read for h might be different: as b has been exported, the environment could freely use b and increment the reference in between the two reads. Visibility ensures us that, when the initial call at a is returned, name b is “forgotten” by the environment, which cannot therefore use it anymore. Thus, if Q is the process defined like P but with the last line replaced with q.c¯(d,r).r.s¯.0, then we have PQ. We refer to Appendix C.1 for an ML-like presentation of the example above, as well as for a longer example, also showing how re-entrant calls may sometimes make visibility boundaries hard to predict.

5.2 Labelled semantics

To represent the point of view of the observer, we use typing environments of the form [Γ|κ], where Γ is a visibility function and κ is a stack. Figure 4 defines the typed transitions, written [Γ|κ]P𝜇[Γ|κ]P. Rules 𝚃𝚛𝚃𝚊𝚞, 𝚃𝚛𝙾-𝚏𝚘 and 𝚃𝚛𝙸-𝚏𝚘 are similar to their counterpart in Figure 2, and are omitted.

Figure 4: Visible LTS with stack.

A trace μ1μn is a well-bracketed trace of P0 under [Γ0|κ]0 if there are Pi,Γi,κi (1in) with [Γi|κ]iPiμi[Γi+1|κ]i+1Pi+1 for all 0i<n.

Definition 30 (Typed trace equivalence).

Two Δ|σ-processes P and Q are trace equivalent at [Γ|κ], written PΔ|σ[Γ|κ]Q, if Δ|σ and [Γ|κ] are compatible and P and Q have the same sets of well-bracketed traces under [Γ|κ].

This typed version of trace equivalence enjoys properties, including substitutivity properties, similar to those of the trace equivalence in Section 4. We only report the characterisation result with respect to may testing.

Theorem 31 (Characterisation of may testing using trace equivalence).

Suppose Δ|σP,Q; then PΔ|σ[Γ|κ]Q if and only if PΔ|σ[Γ|κ]Q.

The analogous result for typed bisimilarity is in Appendix C, together with results about the shape of type-allowed traces akin to those in Section 4.2.

6 Conclusions and Future Work

In this paper we have studied the meaning of visibility, originating from game-semantics interpretations of typed λ-calculi and reflecting absence of higher-order store, in a calculus of pure name-passing such as the π-calculus. In contrast with λ-calculi, in the π-calculus there is no explicit notion of store, and no unique identities (e.g., the input end of a name may have multiple occurrences, arbitrarily structured). These aspects determine considerable differences in the semantic analysis of visibility. For instance, in the π-calculus visibility has to be enforced by means of a dedicated type system; and the visibility functions have to satisfy special properties such as transitivity. We have highlighted such differences, and investigated the behavioural effects of visibility. In particular, we have shown full abstract characterisations of may testing and barbed equivalence, as forms of trace equivalence and labelled bisimilarity.

There are several directions for future work that we would like to pursue. In game semantics, further aspects related to first-order store have been studied; for instance allowing first-order references as values (that can be passed around) [13, 9], or allowing to store first-order references (i.e., references with types such as int ref ref [17, 10]). The distinction between first-order and higher-order state has also been studied in [14]. We would like to investigate the effects of such distinctions on our types and proof techniques.

We have worked with πI, a dialect of π-calculus in which all names exchanged are newly created. Thus πI lacks the free-output construct, where the communication of existing names is permitted. As shown in the literature [5, 25, 8], πI is closer to game semantics than the standard π-calculus. We would like to see whether our results can be adapted so to accommodate also the free output construct. While free output can be modelled in πI [2], it allows a direct representation of idioms such as “delegate to someone else the task of answering’, or the expression of tail-call recursion.

We have studied visibility on top of type systems for sequentiality and well-bracketing. Allowing concurrency would probably require relaxing the definition of the visibility functions; we leave the details to future work.

References

  • [1] Davide Ancona, Viviana Bono, Mario Bravetti, Joana Campos, Giuseppe Castagna, Pierre-Malo Deniélou, Simon J. Gay, Nils Gesbert, Elena Giachino, Raymond Hu, Einar Broch Johnsen, Francisco Martins, Viviana Mascardi, Fabrizio Montesi, Rumyana Neykova, Nicholas Ng, Luca Padovani, Vasco T. Vasconcelos, and Nobuko Yoshida. Behavioral types in programming languages. Found. Trends Program. Lang., 3(2-3):95–230, 2016. doi:10.1561/2500000031.
  • [2] Michele Boreale. On the expressiveness of internal mobility in name-passing calculi. Theor. Comput. Sci., 195(2):205–226, 1998. doi:10.1016/S0304-3975(97)00220-X.
  • [3] Daniel Hirschkoff, Enguerrand Prebet, and Davide Sangiorgi. On sequentiality and well-bracketing in the π-calculus. In 2021 36th Annual ACM/IEEE Symposium on Logic in Computer Science (LICS). IEEE, June 2021. doi:10.1109/lics52264.2021.9470559.
  • [4] Daniel Hirschkoff, Iwan Quémerais, and Davide Sangiorgi. First-order store and visibility in name-passing calculi. CoRR, abs/2504.17350, 2025. Extended online version of this paper. doi:10.48550/arXiv.2504.17350.
  • [5] Kohei Honda. Processes and games. In Fabio Gadducci and Ugo Montanari, editors, Fourth International Workshop on Rewriting logic and Its Applications, WRLA2002, Pisa, Italy, 19-21, 2002, volume 71 of Electronic Notes in Theoretical Computer Science, pages 40–69. Elsevier, 2002. doi:10.1016/S1571-0661(05)82528-9.
  • [6] Kohei Honda, Vasco Thudichum Vasconcelos, and Makoto Kubo. Language primitives and type discipline for structured communication-based programming. In Chris Hankin, editor, Programming Languages and Systems - ESOP’98, 7th European Symposium on Programming, Held as Part of the European Joint Conferences on the Theory and Practice of Software, ETAPS’98, Lisbon, Portugal, March 28 - April 4, 1998, Proceedings, volume 1381 of Lecture Notes in Computer Science, pages 122–138. Springer, 1998. doi:10.1007/BFB0053567.
  • [7] Guilhem Jaber and Andrzej S. Murawski. Complete trace models of state and control. In Programming Languages and Systems: 30th European Symposium on Programming, ESOP 2021, Held as Part of the European Joint Conferences on Theory and Practice of Software, ETAPS 2021, Luxembourg City, Luxembourg, March 27 – April 1, 2021, Proceedings, pages 348–374, Berlin, Heidelberg, 2021. Springer-Verlag. doi:10.1007/978-3-030-72019-3_13.
  • [8] Guilhem Jaber and Davide Sangiorgi. Games, Mobile Processes, and functions. In CSL 2022 - 30th EACSL Annual Conference on Computer Science Logic, pages 1–35, Göttingen, Germany, February 2022. URL: https://hal.science/hal-03407123.
  • [9] Guilhem Jaber and Nikos Tzevelekos. Trace semantics for polymorphic references. In Martin Grohe, Eric Koskinen, and Natarajan Shankar, editors, Proceedings of the 31st Annual ACM/IEEE Symposium on Logic in Computer Science, LICS ’16, New York, NY, USA, July 5-8, 2016, pages 585–594. ACM, 2016. doi:10.1145/2933575.2934509.
  • [10] Ohad Kammar, Paul B. Levy, Sean K. Moss, and Sam Staton. A monad for full ground reference cells. In 2017 32nd Annual ACM/IEEE Symposium on Logic in Computer Science (LICS), Reykjavik, Iceland, 2017. IEEE. doi:10.1109/LICS.2017.8005109.
  • [11] Naoki Kobayashi, Benjamin C. Pierce, and David N. Turner. Linearity and the pi-calculus. ACM Trans. Program. Lang. Syst., 21(5):914–947, 1999. doi:10.1145/330249.330251.
  • [12] Naoki Kobayashi and Davide Sangiorgi. A hybrid type system for lock-freedom of mobile processes. ACM Trans. Program. Lang. Syst., 32(5):16:1–16:49, 2010. doi:10.1145/1745312.1745313.
  • [13] James Laird. A fully abstract trace semantics for general references. In Lars Arge, Christian Cachin, Tomasz Jurdzinski, and Andrzej Tarlecki, editors, Automata, Languages and Programming, 34th International Colloquium, ICALP 2007, Wroclaw, Poland, July 9-13, 2007, Proceedings, volume 4596 of Lecture Notes in Computer Science, pages 667–679. Springer, 2007. doi:10.1007/978-3-540-73420-8_58.
  • [14] Paul-André Melliès and Nicolas Tabareau. An algebraic account of references in game semantics. In Samson Abramsky, Michael W. Mislove, and Catuscia Palamidessi, editors, Proceedings of the 25th Conference on Mathematical Foundations of Programming Semantics, MFPS 2009, Oxford, UK, April 3-7, 2009, volume 249 of Electronic Notes in Theoretical Computer Science, pages 377–405. Elsevier, 2009. doi:10.1016/J.ENTCS.2009.07.099.
  • [15] R. Milner. The polyadic π-calculus: a tutorial. Technical Report ECS–LFCS–91–180, LFCS, 1991. Also in Logic and Algebra of Specification, ed. F.L. Bauer, W. Brauer and H. Schwichtenberg, Springer Verlag, 1993.
  • [16] Robin Milner. Functions as processes. Mathematical Structures in Computer Science, 2(2):119–141, June 1992. doi:10.1017/S0960129500001407.
  • [17] Andrzej S. Murawski and Nikos Tzevelekos. Algorithmic games for full ground references. Formal Methods in System Design, 52(3):277–314, 2018. doi:10.1007/s10703-017-0292-9.
  • [18] Luca Padovani. Deadlock and lock freedom in the linear π-calculus. In Thomas A. Henzinger and Dale Miller, editors, Joint Meeting of the Twenty-Third EACSL Annual Conference on Computer Science Logic (CSL) and the Twenty-Ninth Annual ACM/IEEE Symposium on Logic in Computer Science (LICS), CSL-LICS ’14, Vienna, Austria, July 14 - 18, 2014, pages 72:1–72:10. ACM, 2014. doi:10.1145/2603088.2603116.
  • [19] Benjamin C. Pierce and Davide Sangiorgi. Typing and subtyping for mobile processes. Math. Struct. Comput. Sci., 6(5):409–453, 1996. doi:10.1017/S096012950007002X.
  • [20] Enguerrand Prebet. Typed Behavioural Equivalences in the Pi-Calculus. Theses, Ecole normale supérieure de lyon - ENS LYON ; Università degli studi (Bologne, Italie), September 2022. URL: https://hal.science/tel-03920089.
  • [21] Davide Sangiorgi. The lazy lambda calculus in a concurrency scenario. Inf. Comput., 111(1):120–153, 1994. doi:10.1006/INCO.1994.1042.
  • [22] Davide Sangiorgi. pi-calculus, internal mobility, and agent-passing calculi. Theor. Comput. Sci., 167(1&2):235–274, 1996. doi:10.1016/0304-3975(96)00075-8.
  • [23] Davide Sangiorgi. The name discipline of uniform receptiveness. Theor. Comput. Sci., 221(1-2):457–493, 1999. doi:10.1016/S0304-3975(99)00040-7.
  • [24] Nobuko Yoshida, Martin Berger, and Kohei Honda. Strong normalisation in the pi -calculus. Inf. Comput., 191(2):145–202, 2004. doi:10.1016/J.IC.2003.08.004.
  • [25] Nobuko Yoshida, Simon Castellan, and Léo Stefanesco. Game semantics: Easy as pi. CoRR, abs/2011.05248, 2020. arXiv:2011.05248.

Appendix A Section 2: Definition of the Operational Semantics

Structural congruence, written , is the smallest relation that is an equivalence relation, contains α-conversion, is preserved by all operators of the calculus, and satisfies the following axioms:

Similar versions of axioms for restrictions of the form 𝝂h instead of 𝝂a have been omitted.

To define the labelled transition system (LTS), we introduce actions, defined by the following grammar:

Actions are early for first-order values, and late for the transmission of HO names. We write 𝚋𝚗(μ) (resp. 𝚏𝚗(μ)) for the bound (resp. free) names of action μ, defined by saying that b is a bound name in actions av(b) and a¯v(b), and the other names in actions are free.

We suppose that any closed first-order expression e can be evaluated to some value v. We write ev for the corresponding evaluation relation. We furthermore suppose that equality between values can be tested.

The LTS is defined, on closed processes, by the rules in Figure 5. Based on μ, we define the following relations: stands for τ, and stands for the reflexive transitive closure of . We write μ for μ, and μ^ is equal to μ when μτ, while τ^=.

We write Pω if P𝜔, i.e., if P contains an unguarded occurrence of an ω prefix at toplevel. We write Pω when this is not the case.

Figure 5: Labelled transition semantics.
Symmetric versions of the rules for parallel composition and for sum have been omitted.

Appendix B Additional Material for Section 3

B.1 Properties of the type system

Lemma 32.

Suppose ΔP and a𝚏𝚗(P). Then also ΔaP.

Lemma 33 (Invariance of typing w.r.t. structural congruence).

If Δ|σP and PP, then also Δ|σP.

B.2 Properties of trace equivalence

Lemma 34 (Shrinking).

Suppose ΓΓ, Δ and Γ compatible and PΔΓQ. Then also PΔΓQ.

Definition 35 (Projection).

Let Γ be a visibility function and N a set of names. We define a visibility function as follows:

𝚙𝚛𝚘𝚓(N,Γ):𝙷𝙾{}𝒫(𝙷𝙾)adom(Γ)NΓ(a)N
Lemma 36 (Extension).

Consider Δ,Γ,Γ,P,Q such that 𝚙𝚛𝚘𝚓(𝚏𝚗(Γ,P,Q),Γ)=Γ and Δ and Γ are compatible. If PΔΓQ then PΔΓQ.

In the statement above, 𝚏𝚗(Γ,P,Q) stands for the union of all names mentioned in Γ, together with the names occurring free in P and Q.

B.3 Pruning Processes using Types

Consider a visibility function Δ and S𝙷𝙾. We write αS when α is an input of the form a(x,b) and either aS or (a𝚍𝚘𝚖(Δ) and Δ(a)S).

We define inductively the pruning function on processes that removes all instances of the names in S as follows:

Lemma 37 (Pruning).

Let Γ,Δ,P such ΔP and Γ and Δ are compatible and ΔΓ is transitive. Then for all S𝙷𝙾 such that S(ΓΔ())=, ΔS𝙿𝚛SΔ(P) and PΔΓ𝙿𝚛SΔ(P).

We actually remove more than the names in S. Indeed, to preserve sequentiality, we cannot simply remove an output; we actually remove all inputs that may cause an output on the names in S.

The idea of the proof is to show that S(ΓΔ())= is an invariant throughout the trace; for this we use repeatedly transitivity of ΓΔ.

Proof.

Let μ1μn a trace of P under Γ, let Pi,Γi be the processes and visibility functions given that trace and Δi the visibility functions given by subject reduction. We show by induction on i that there exists Γi,Δi such that ΓiΓi and ΔiΔi and S(ΓiΔi)()= and that Δi and Γi are compatible, have a transitive union and coincide on the intersection of their domains. The case i=0 is immediate, let 0i<n, we assume the induction hypothesis on i and show it for i+1 by cases on μi :

  • if μi=τ, or μi=hv or μi=h¯v then Γi+1=Γi and Δi+1=Δi, these cases are immediate by setting Γi+1=Γi and Δi+1=Δi.

  • if μi=a¯v(b) then Γi+1=Γi;Γi(a),b and Δi+1=Δi;bΔi(),b. Let Γi+1=Γi;Δi(),bΓi+1 because aΔi() therefore Γi(a)Δi(). And let Δi+1=Δi;bΔi(),b.
    Γi+1 and Δi+1 are compatible, their union is transitive and they coincide on the intersection of their domains.
    (Γi+1Δi+1)()=(ΓiΔi)(),b where b is fresh therefore bS and by induction hypothesis S(Γi+1Δi+1)()=.

  • if μi=av(b) the case is similar to the previous one, swapping Γ and Δ.

This ensures us that none of the μi are inputs or outputs on higher-order names in S. Moreover if a𝚍𝚘𝚖(Δ) and Δ(a)S then for all i, a(ΓiΔi)() otherwise we would have Δ(a)S=Δi(a)S(ΓiΔi)()S=.
Therefore the trace μ1μn is also a trace of 𝙿𝚛SΔ(P) under Γ.

Appendix C Additional Material for Section 5

C.1 About Example 29

The process discussed in Example 29 can be seen as the π-calculus counterpart of the following ML program, which might be more readable for a reader familiar with functional languages:
let h = ref 0 in
let b () = h := !h +1 in
begin
  a b;
  let x = !h in
  c x;
  let y = !h in
  if x=y then loop() else ()
end

Re-entrant call

The following example first shows an equality similar to that of Example 29; and then develops the example so to show how re-entrant calls may sometimes break “expected” visibility boundaries.

We define two processes P1 and P2, which access a reference h (implemented using a first-order name), and can call a server b. When calling b, the processes first pass the name 𝚒𝚗𝚌𝚛 of a server that increments the value stored in h. Once the call on b is answered the processes read the value in h and make another call to b passing the identity function. After that, the processes read again the value of h. Finally, P1 outputs the first value read in h while P2 outputs the second one.

Pi=defb¯(𝚒𝚗𝚌𝚛,q1). q1.h(x1).(h¯x1
|b¯(𝚒𝚍,q2).
q2.h(x2).(h¯x2
|p¯xi))

We first compare the processes

𝝂h(h¯0|a(b,p).P1|Q𝚒𝚗𝚌𝚛|Q𝚒𝚍)and𝝂h(h¯0|a(b,p).P2|Q𝚒𝚗𝚌𝚛|Q𝚒𝚍),

where Q𝚒𝚗𝚌𝚛 (resp. Q𝚒𝚍) is the encoding of function incr (resp. id).

Here, the only way to change the value stored in h is by calling 𝚒𝚗𝚌𝚛, which is not visible by the observer after the input on q1. These two processes are bisimilar under any visibility.

Then we compare the processes

Q1=def𝝂h(h¯0|!a(b,p).P1|Q𝚒𝚗𝚌𝚛|Q𝚒𝚍))andQ2=def𝝂h(h¯0|!a(b,p).P2|Q𝚒𝚗𝚌𝚛|Q𝚒𝚍).

We are be able to distinguish them using a re-entrant call :

R=defa¯(b,p).( b(𝚒𝚗𝚌𝚛,q).a¯(d,r).(!d(,s).𝚒𝚗𝚌𝚛¯(t).t.s¯
|r(n).𝚒𝚏n=1𝚝𝚑𝚎𝚗q¯𝚎𝚕𝚜𝚎ω)
|p(m))

The idea is to call a a second time when 𝚒𝚗𝚌𝚛 is still in the observer’s visibility; this means that the new server passed to a has access to 𝚒𝚗𝚌𝚛 during both calls. With the observer R, only Q2 will be able to send a success signal. Therefore, for any visibility function Γ such that aΓ(), Q1 and Q2 are not bisimilar under visibility Γ.

The processes Q1 and Q2 can be seen as the π-calculus counterparts of the following ML program. (This example, with re-entrant calls, has been inspired by similar examples in game semantics of functional languages):
let h = ref 0 in
let incr () = h := !h +1 in
let id x = x in
let a b =
  b incr;
  let x1 = !h in
  b id;
  let x2 = !h in
  xi

These programs can be distinguished by the following ML program that corresponds to the process R :
let b f =
  let d _ = f () in
  let n = a d in
  if n = 1 then () else ω
in
a b

The idea is the same as before: d calls f which will be incr in the first call to b; therefore at each call to d the reference is incremented. As a consequence, first program returns 1 while the second one returns 2.

C.2 Properties of traces: views and well-bracketing

Along the lines of the material presented in Section 4.2, we can reason about the traces produced by typable processes, based on the notion of justification. For this, we adapt Definition 22 to define views for traces. The notion of respecting views (Definition 23) is also adapted straightforwardly, which allows us to obtain the analogue of Lemma 24.

Lemma 38.

Consider Δ,Γ,σ,κ,P such that Δ|σP and [Γ|κ] is compatible with Δ|σ. Let A=(ΓΔ)(), then every trace of P under [Γ|κ] respects views with starting visibility A.

As highlighted in [3], continuation names allow us to formulate a property of well-bracketing for traces, enforced by our type system. In contrast with [3], however, we we do not impose input receptiveness on continuation names.

Definition 39 (Well-bracketing).

An action of the form av(b,p) or a¯v(b,p) is called a question. An action of the form pv(b) or p¯v(b) is called an answer.

A trace μ1μn is well-bracketed if for all i<j, if μi is a question and μj is an answer with μiμk and μkμj for all i<k<j, then μiμj.

A stack σ is clean if each name has at most one occurrence, with any tag, in σ. A trace μ0μn is a typed trace emanating from P0 if there are Δ1,σ1,,Δn,σn,P1,,Pn such that for all 0j<n we are in one of the cases given by Theorem 27, which gives Δj+1|σj+1 when Pjμj+1Pj+1.

Lemma 40.

Suppose Δ0|σ0P0, where σ0 is clean. All typed traces emanating from P0 are well-bracketed.