Concurrent NetKAT: Modeling and analyzing stateful, concurrent networks

We introduce Concurrent NetKAT (CNetKAT), an extension of NetKAT with operators for specifying and reasoning about concurrency in scenarios where multiple packets interact through state. We provide a model of the language based on partially-ordered multisets (pomsets), which are a well-established mathematical structure for defining the denotational semantics of concurrent languages. We provide a sound and complete axiomatization of this model, and we illustrate the use of CNetKAT through examples. More generally, CNetKAT can be understood as an algebraic framework for reasoning about programs with both local state (in packets) and global state (in a global store).


Introduction
Kleene algebra (KA) is a well-studied formalism [21,24,35,9] for analyzing and verifying imperative programs. Over the past few decades, various extensions of KA have been proposed for modeling increasingly sophisticated scenarios. For example, Kleene algebra with tests (KAT) [22] models conditional control flow while NetKAT [3,11] models behaviors in packet-switched networks.
A key limitation of NetKAT, however, is that the language is stateless and sequential. It cannot model programs composed in parallel, and it offers no way to reason algebraically about the effects induced by multiple concurrent packets. Meanwhile, the software-defined networking (SDN) paradigm has evolved to include richer functionality based on stateful processing including data aggregation and dynamic routing. In languages like P4 [5], issues of concurrency arise because the semantics depends on the order that packets are processed.
Given this context, it is natural to wonder we can add concurrency to NetKAT while retaining the elegance of the underlying framework. In this paper, we answer this question in the affirmative, by developing CNetKAT. However, to do this, we must overcome several challenges. A first hurdle is that networks exhibit many different forms of concurrent behavior. The most obvious source of concurrency arises when multiple packets are processed by different devices. In these situations, certain packets may cause changes in forwarding behavior by modifying global state variables on switches. However, there is also concurrency within individual devices: a high-speed switching chip often has multiple pipelines, each with multiple stages of match-action tables and stateful registers. The tables can be programmed to act concurrently on (parts of) a single packet, and the pipelines also act concurrently on multiple packets.
Another hurdle is that it is not entirely clear how to simultaneously extend KA with networking features and concurrency. Orthogonal to the development of NetKAT, the issue of adding concurrency to KA has been researched extensively, starting with concurrent Kleene algebra (CKA) [14,26,27,18]. However, the combination of concurrency from CKA and tests from KAT is not straightforwardsee, e.g. [15,16,17]-which motivated the development of partially-observable concurrent Kleene algebra (POCKA) [38]. In POCKA, a single thread only has partial view of the state. Hence, when evaluating control guards, a thread makes observations about the machine state, rather than definitive tests. This allows for fine-grained reasoning about concurrent programs with variables, conditionals, loops, and imperative statements that manipulate a shared global memory.
In this work, we use POCKA as a basis for designing a language with state and concurrent threads, which we combine with a multi-packet extension of NetKAT. The resulting language, Concurrent NetKAT (CNetKAT), models the behavior of packets in a network that communicate through a shared global state, and addresses the fundamental and non-trivial question of how to combine concurrency and the interaction between local and global state within KA.
Overall, the contributions of the paper are as follows: 1. We present the design of the CNetKAT language ( §3). The semantics combines the language models of NetKAT and POCKA, incorporating pomsets that record the evolution of the global state (as in POCKA) as well as sets of (output) packets (as in NetKAT). 2. We develop a sound and complete axiomatization of CNetKAT ( §4). 3. We illustrate the applicability of CNetKAT for modeling and analyzing concurrent network behaviors through case studies and examples ( §2 and §5).
The next section contains an overview of the challenges in the design of extending NetKAT with multiple packets, global state, and concurrency, as well as a glimpse of how to use the language in a practical example.

Overview
CNetKAT models the behavior of two basic entities: the packets being routed through the network, and a global store, which may be accessed by the network as it processes the packets. These elements give rise to two kinds of basic programs. On the one hand, basic packet programs-imported from NetKAT [3]-include tests (f i =n) and modifications (f i ←n) of packet fields f 1 , . . . , f N . Examples of fields are sw, denoting the switch of the packet in the network, and tag, denoting p1 sw = 1 ; ((v = 1 ; tag = ♠ ; sw←2) (tag = ♥ ; sw←3 ; v←1)) p2 sw = 2; sw←4 p3 sw = 3; sw←4 p4 sw = 4 p v←0 ; (p1 p2 p3 p4) * Fig. 1: Running example the type of a packet. In general, we expect packets to have fields for a collection of standard attributes; unused fields may be populated with a dummy value.
On the other hand, basic state programs include observations 4 (v i =n), modifications (v i ←n) and a copy operation (v i ←v j ) on state variables v 1 , . . . , v M . It will always be clear from context whether an action concerns a state or field variable. CNetKAT also includes a primitive program a for any set of packets a, which is useful for specifying the set of packets currently being processed. Remark 1. We could augment the set of primitives with features such as general expressions in assignments. However, to keep things simple, we will only consider these primitives, which are already rich enough to describe non-trivial behaviors.
The full syntax of CNetKAT is given in Figure 2. Before giving a precise account of the semantics, we will go over some simple example programs.
Example 1 (Packet forwarding). Consider the network depicted on the left in Figure 1. Similar to NetKAT, we assume packet movement and variable assignments are instantaneous. Suppose there are two packet types: ♠ and ♥. We want to write a program that transfers packets from node 1 to node 4 by sending ♠ via node 2, and ♥ via node 3. The program running in switch 1 could be p 1 := sw=1 ; ((tag=♠ ; sw←2) (tag=♥ ; sw←3)) This program first filters out the packets at switch 1. Next, it launches two parallel threads, both of which receive a copy of the incoming packets. The first thread filters out packets of type ♠ and forwards them to switch 2, while the second thread filters out packets of type ♥, forwarding them to switch 3.
We can write programs p 2 , p 3 and p 4 for the other switches as well, and then compose all of those in parallel to obtain a program for the entire network.
Remark 2. Instant packet movement is not baked into CNetKAT, but rather a consequence of modeling packet location using the field sw. A more advanced model could use an additional field to mark a packet as being "in-flight" until it reaches the next hop. Here, we opt for the simpler model.

Example 2 (Global behavior).
CNetKAT programs can read and write to a global store, letting earlier actions on packets affect later decisions. For instance, suppose we need ♠ packets to be forwarded only if a ♥ packet already visited switch 3. We can use a global variable v to implement this stateful behavior, writing: sw=1 ; ((v=1 ; tag=♠ ; sw←2) (tag=♥ ; sw←3 ; v←1)) We can program the other switches with p i , as shown in Figure 1.
Remark 3 (Concurrency and state). Actions involving global variables are more subtle than those that concern packet fields, due to concurrent threads accessing the global store. For instance, we can write the program v←1 ; v=2, which first sets v to 1 and then asserts that v should have value 2. This may seem inconsistent; however, there may be valid ways of executing this program if there are other threads that change the value of v from 1 to 2 between the assignment v←1 and the assertion v=2. This possibility makes defining a compositional semantics somewhat tricky, as we will discuss below.
Semantics of CNetKAT programs. A packet π is a record of fields f 1 , . . . , f N . We write π(sw) for the value of sw in π and π[1/sw] for the packet obtained after updating the value of sw to 1. We denote the set of packets by Pk.
The semantics of a CNetKAT program is represented as a function that takes a set of packets, potentially located in different nodes in the network, and returns a set of possible behaviors that those input packets might produce. More precisely, the semantics function has type − : 2 Pk → 2 Pom ·2 Pk . Here, Pom is the set of pomsets [13,12], which can be thought of as structures that record the causal order between concurrent events (details appear in Section 3.1). An element u · b ∈ p (a) means "there is an execution of p that changes the global variables according to u, and the set of output packets produced is b". 5 The semantics is defined in Figure 3. For instance, a packet filter (f =n) takes a set of packets a and returns {1 · a(f =n)}, where a(f =n) contains all packets in a where f has value n and 1 is the pomset representing that the global state did not change. A modification (f ←n) takes a set of input packets a and returns {1 · a(f ← n)}, where a(f ← n) = {π[n/f ] : π ∈ a}. These two basic packet actions manipulate the local state of the program.
On the global state we have observations of the form (v=n) and modifications (v←n), (v←v ). Each gives rise to a pair in the semantics-{v = n · a}, {(v←n) · a}, {(v←v ) · a}-in which the input set of packets a is returned as output and the assertion or modification is recorded in the pomset.
Lastly, the primitive a ∈ 2 Pk is useful for writing specifications. This program copies the set of packets a into the global pomset. We will see that this is useful for checking inclusion of certain behaviors in a program's semantics, and in the proof of completeness. Formally, the behavior of a on any input set b is {a · b}, where a is the global state pomset with one node labeled by a.
To construct more complicated programs, we can combine the basic elements above using operators from Kleene algebra. For instance, p + q is a program that represents a non-deterministic choice between p and q. Its semantics is obtained by taking the union of sets produced by both p and q on the input packets. We can also compose programs sequentially using p ; q, where we first apply p to the input packets and then q to all sets of packets produced by p, and we compose the corresponding global pomsets sequentially. We can iterate a program finitely many times using p * . Lastly, we can combine programs with a parallel operator, p q, which denotes a program that, on input a, executes both p and q on a, and then combines the results: the pomsets denoting the global components are composed in parallel, and the corresponding sets of output packets joined.
Remark 4 (Concurrency and state, continued). Note that statements observing or modifying global variables are stored in the pomsets but not executed, that is, we do not actually check immediately whether v is indeed 1 but rather simply record it. This may seem like an odd choice at first: why does the semantics not also keep a record of the global store? The reason is related to Remark 3.
Consider the program q = (v=0) ; (v=1), which asserts that v has value 0, and then that it has value 1. In isolation, q does not have any valid behavior, as it sequentially executes two tests that cannot be valid without intermediate intervention. However, the program q (v←1) does have valid behavior on some Filtering, updates and downwards closure a ∈ 2 Pk , Z ⊆ St Fig. 3: CNetKAT semantics. Pairs u·b in p (a) indicate that the program p takes input a and the global state change induced by p is encoded in u and constrains the final packet set b. We overload · for sequential composition of pomsets and pairs, while is the usual lifting from pomsets to languages.
interleavings-namely the ones where the assignment v←1 is scheduled between the two tests. It stands to reason that a compositional semantics of such programs should include traces with such local inconsistencies, as they may be explained by actions taken by other programs running in parallel [38]. For CNetKAT, this is accomplished by placing the observations and modifications in the pomset. This leaves us with the question of how to obtain the semantics of a program in isolation. We take a page from POCKA [38], which uses the set of guarded pomsets to filter out the pomsets sensible in isolation; details appear in §5.
One final modification is needed to obtain the CNetKAT semantics from − . The idea is to allow interleaving between parallel threads [14]. This is accomplished by adding to the semantics all pomsets in which events are "more ordered" than the ones already present in − . We denote this closed semantics by −  ; a precise definition is given in §3.
Recording local behavior To apply CNetKAT to various verification tasks, we sometimes need to take snapshots of the local state at different points. For example, if we want to argue that ♥ packets arrived at switch 3 before ♠ packets arrived at switch 2, we need more than the information about inputs and outputs that have occurred so far. We therefore have to extend the language with an operator comparable to dup in NetKAT. On input a, the semantics of the dup operator is the set {a · a}, where the first component is a single node pomset labeled with set of packets a. 6 By recording packets inside the pomset, information about changes to packets also contains their relation to changes to global variables during the execution. Hence, using dup, we can infer causality relations between local and global state changes. The programs p 1 , p 2 , p 3 and p 4 used in our running example (see Figure 1) can be instrumented with a dup on every entry to and exit from a switch. This encodes extra information in the semantics that can be used for reasoning about packet-forwarding paths as well as global state changes.
The overall program of the running example then becomes where the global variable v is initialized to 0, and the programs p 1 , p 2 , p 3 , p 4 are executed in parallel, performing the actions of each individual switch. The Kleene star ensures that the packets may take multiple hops through the network, eventually reaching their final destination (switch 4).
Remark 5. If a dup occurs in parallel to other threads, then these other parallel threads can only change the exact place of the dup-recording in the pomset via possible interleavings, but not influence its content.
Remark 6. We model the collection of in-flight packets as a set, as opposed to e.g. a partially ordered set encoding their order of arrival. This is an abstraction of our framework. Not putting an order on packets simplifies the algebraic presentation and has the advantage that it enables modeling of switches that reorder packets without an additional primitive. If the order of packets is important, information about this order can be extracted from the semantics. In particular, when packets were forwarded can be deduced by inspecting the sets of packets recorded in the pomset component using dup.
Two differences between CNetKAT and NetKAT Readers familiar with NetKAT might wonder why Example 1 uses instead of + to compose the branches of p 1 . The reason is that in CNetKAT, is interpreted as multicast and + is interpreted as non-deterministic composition. In NetKAT, programs act on a single input packet, so these coincide. But in CNetKAT, programs act on multiple packets concurrently, so they must be distinguished. To illustrate the difference, consider wanting to filter the input packets so that only those where field f has value n or field g has value m remain. In NetKAT, we can use the program f =n + g=m, which can be understood in two different ways. First, we can think of it as using (angelic) non-determinism to select a test, yielding {π} if at least one test passes and ∅ if both tests fail. Alternatively, we can think of it as using multicast to copy the input to both f =n and g=m, then using the tests to perform the required filtering, and finally taking the union of the resulting sets. In NetKAT, the net effect of both interpretations is identical, so multicast and non-determinism can be identified semantically.
However, when we generalize to sets of packets, it is natural to expect that processing a set a with f =n followed by g=m would yield the subset of a where each packet satisfies at least one of the tests. Operationally, processing a using these programs could be realized by making two copies of a, then using the tests to perform the required filtering, and taking the union of the resulting sets. This is reflected in the semantics: f =m g=n (a) = {1 · (a(f = m) ∪ a(g = n))}, where we get a single pair in the output. If instead we non-deterministically choose between the tests, the result would be the subset where f = n or the subset where g = m. Indeed, we have that f =m + g=n (a) = {1 · a(f = m), 1 · a(g = n)}. Hence, multicast and non-determinism can no longer be identified in the context of multiple packets. For readers familiar with NetKAT, this means that the Boolean disjunction ∨ is now identified with rather than +.
Lastly, we highlight that CNetKAT's dup is fundamentally different from NetKAT's dup, which just records versions of the packet during execution. In CNetKAT, dup does two things: it implements the same functionality as in NetKAT, but also structures the recording of packets inside the pomset. Proving properties with CNetKAT In §5, we analyze the behavior of the running example in detail and show how to filter out the behaviors of p that can be obtained when it is run in isolation. In this overview, we establish a simpler property: namely, that p exhibits executions where the packets were at switch 3 before they were at switch 2. We first argue this using the denotational semantics and then illustrate how we can establish the same fact with axiomatic reasoning.
Recall a pomset accounts for events and the ordering between them. In the following examples, we will depict pomsets as a graph with nodes labeled by state actions, observations and sets of packets, and the ordering indicated by arrows. For instance, a → b means that a happened before b.
We evaluate p on input {♥, ♠}, where both packets start at switch 1. In the closed semantics p  ({♥, ♠}) we find the following pomset (the · · · indicate that the pomset continues on the next line, not that nodes are omitted), in the first projection, with β a partial function from Var to Val s.t. β(v) = 1: Every node labeled with a set of packets can be understood intuitively as "at this point in the execution these packets were a subset of the total packets present in the network." We can observe in the pomset that the ♥ packet was at switch 3, before the ♠ packet reached switch 2. We also see that v←1, happens between v←0 and β. In the end, both packets are observed at switch 4.
The second projection in the semantics corresponding to this pomset is the set of output packets {♠[4/sw], ♥[4/sw]}.
In Appendix E, we show something stronger: in all behaviors that can happen in isolation, the packet ♥[3/sw] is recorded into the global pomset before the assignment v←1, which precedes the observation that v equals 1 and the generation of the packet ♠[2/sw].
We can write an axiomatic statement that captures that the above behavior is in the closed semantics of p on input {♥, ♠}. To do this, we first need to capture the pictured global state pomset with corresponding set of output packets syntactically, for which we use an abbreviation. Namely, we can write a program that outputs, on any input, a specific packet: for a packet π, we write this program simply as π. The output of π on any input is {1 · {π}}. This extends to sets of packets: ♥ ♠ denotes a program whose semantics is {1 · {♥ ♠}} on any input. This notation pairs well with the use of the letters a ∈ 2 Pk as programming syntax: if we know which set of packets we (want to) record into the global state pomset with dup, we can also directly write this set of packets in the program as a syntactic letter. For instance, the program (♥ ♠) ; dup, has the same behaviors as (♥ ♠) ; {♥, ♠}: the moment we execute the dup, we know the current set of packets is {♥, ♠}, and thus writing this set of packets as a letter and recording that letter into the global state pomset will have the same result. Using these two pieces of information, we can write the program . The first chunk of this program is the syntactic encoding of the desired global state pomset, where the ♥ packet arrives at switch 3 before the ♠ packet arrives at switch 2, and the final parallel of packets represents the set of output packets. We can prove using the axioms of CNetKAT that (2) states that the behavior of q on input {♥, ♠}, is included in the behavior of p on the same input. In the behavior of q, it is clear that the ♥ packets are observed at switch 3 before the ♠ packets appear at switch 2.
Remark 7 (Generalized alphabet). Here we see the use of sets of packets as letters in the program syntax. Program q is much closer to the behavior we try to capture, and therefore easier to analyze, than a program containing dup.
To check the validity of equivalences such as (2), we axiomitize CNetKAT and prove it sound and complete. The axioms include the axioms of KA, extended with additional axioms for operations that manipulate packets and the global state. The full axiomatization appears in Section 3.4. For instance, drop;q ≡ drop states that no outputs are produced in the absence of inputs. The program drop drops the set of inputs and returns {1 · ∅}. Any program q after drop outputs {1 · ∅}, because q is not executed when the input is empty. In contrast, q ; drop ≡ drop does not hold since q might have changed the global state.
In addition to drop, CNetKAT has a program abort, which acts as a unit for non-deterministic choice (+). To illustrate the difference between abort and drop consider (f =n) ; (f =m) and (v=n) ∧ (v=m), where m = n. The first program filters using f = n and and then filters using f = m where m = n. This yields {1 · ∅}, since a packet cannot have different values for f . Hence, we can derive (f =n) ; (f =m) ≡ drop. The second program asserts the global state variable v has value n and m, which is inconsistent; we require variable v to have two different values at the same time. Hence, from the axioms we can derive that (v=n) ∧ (v=m) ≡ ⊥ ≡ abort.
We prove in §4 that the axiomatization presented in Section 3.4 is not only sound but also complete-i.e., all programs with the same semantics can be proved equivalent using the axioms. The rest of the paper is devoted to presenting the CNetKAT syntax and semantics formally ( §3), and establishing conservativity results over NetKAT and POCKA. Lastly we present a case study ( §5).

Concurrent NetKAT
This section defines the syntax and semantics of CNetKAT formally.

Pomsets and pomset languages
For a poset (X, ≤) and a set S ⊆ X, define the downwards-closure of S by S ≤ ::= {x | ∃y ∈ S s.t x ≤ y} and P ≤ (X) : It is well-known that P ≤ (X) carries the structure of a bounded distributive lattice, with intersection as meet, union as join, X as top and ∅ as bottom. Further, if (X, ≤) is finite, the lattice is itself finite and thus carries a (necessarily unique) pseudocomplement defined by Y ::= {Z ∈ P ≤ (X) | Y ∩ Z = ∅}. We provide a concrete lattice with a pseudocomplement below.
Pomsets are used to capture the different evolutions of the state as it is accessed concurrently by different threads. Pomsets are labeled posets (up to isomorphism), used as a generalization of words [12,13]. A labeled poset over a finite alphabet Σ is a triple u = S u , ≤ u , λ u , where (S u , ≤ u ) is a partially ordered set and λ u : S → Σ is the labeling function. For u, v labeled posets, we say u is isomorphic to v, u ∼ = v, if there exists a bijection h : S u → S v that preserves labels -λ v • h = λ u -and preserves and reflects ordering-s ≤ u s if and only if h(s) ≤ v h(s ). A pomset over Σ is an isomorphism class of labeled posets over Σ, i.e., the class [v] = {u | u ∼ = v} for some labeled poset v. Because pomsets are label-preserving isomorphism classes, the nature of the carrier is not relevant, only its cardinality and order. The triple u = S u , ≤ u , λ u is a representation of the pomset. However, often we abuse terminology and call u the pomset.
We write Pom(Σ) for the set of pomsets over Σ, and 1 for the empty pomset. When a ∈ Σ, we write a for the pomset represented by the labeled poset with a single node labeled by a. Pomsets can be composed sequentially and in parallel.
The parallel composition of two pomsets is obtained by taking the disjoint union of the carriers, while keeping the ordering relations within each component.
, for x ∈ S v . Two pomsets are composed sequentially by taking the disjoint union of the carriers and ordering all elements of the first before all elements of the second, keeping the ordering relations within each component. Formally, Gischer introduced a notion of ordering on pomsets [12]: u v means that u, v have the same events and labels, but u is "more sequential" than v in the sense that more events are ordered. Formally, u v if there exists a label-and order-preserving bijection h : Pomset languages are simply sets of pomsets. The operations on pomsets lift pointwise to pomset languages, see Figure 3. The semantics of concurrent threads requires ensuring a closure property. In particular, we will close pomset languages under the subsumption order of Gischer. Additionally, for pomsets that contain nodes labeled by observations, we make use of a contraction order: u v, capturing that u results from v by eliminating consecutive observations that can be collapsed into one. As an example, consider Denote these pomset with u and v respectively, and let α ∈ St. Then u v. A formal definition can be found in Appendix A.
Definition 1 (Closure). Let L be a pomset language.
We define L↓ contr∪exch as the smallest language containing L and satisfying that if v ∈ L↓ contr∪exch and u v or u v, then u ∈ L↓ contr∪exch .
Closure under is called exch because it ensures soundness of the exchange law, an axiom introduced in [14] to capture the possibility of interleaving. Closure under contraction is motivated algebraically; it ensures soundness of one of the axioms necessary when adding a test algebra (a PCDL or a BA) to a KA [17].

CNetKAT: syntax and semantics
CNetKAT expressions denote (possibly concurrent) packet processing programs that have access to a global state. Syntactically, CNetKAT is a language built from alphabets of tests and actions, each of which is divided in two categories. For packet tests, we firstly inherit NetKAT's packet predicates, which are elements of a Boolean algebra generated by an alphabet of basic tests on packet fields. Packet predicates t, u include constants drop and pass, denoting false and true, basic tests f =n, negation ¬t, disjunction t∨ B u and conjunction t∧ B u operations.
Additionally, we have state observations, which do not have the structure of a Boolean algebra but instead form a pseudocomplemented distributive lattice. Intuitively, the functions denoting the state are partial. State observations o, o include constants ⊥ and , basic tests v=n, pseudocomplement o, intersection o ∧ o and union o ∨ o . The other constructs were introduced in §2 (see Figure 2).
The semantics of a program is a function · : 2 Pk → 2 Pom(St∪Act∪2 Pk )·2 Pk that takes a set of packets a and produces a (possibly empty) set of pairs u·b consisting of a pomset u, recording the global state behavior and the storage of local packets whenever dup is used, and a set of packets b. On an empty input set, every program produces {1 · ∅}, modeling that nothing can happen without packets. Producing the empty set when the input is non-empty models a program that has aborted, whereas producing a set {1·∅} models dropping all the packets without any change to the state. Most of the semantics was already explained in §2; in the following we elaborate on some behaviors and illustrate subtleties concerning the units. See Figure 3 for an overview of the full denotational semantics of CNetKAT.
On a non-empty input a, a packet filter t removes packets in a that do not satisfy predicate t and does not touch the state -this is captured by the set {1 · t B (a)}, where t B (a) is interpreted as an element of the Boolean algebra (2 a , ∪, ∩, ∅, a, \) defined by the poset (2 a , ⊆), and t B (a) is defined as the homomorphic extension of f =n B (a) = {π ∈ a | π(f ) = n}.
A state observation denotes a function that returns a set with elements u · a when applied to a set a. In case the original input set a is empty, nothing happens and the output of o (a) is simply {1·∅}. When a is not empty, the semantics of o makes use of an observation algebra developed in [15,38]. More formally, we take the pseudocomplemented bounded distributive lattice ( we find all the partial functions (elements of St) that agree with o. For instance, v=n O contains all partial functions that assign n to v. This also illustrates the need for a pseudocomplement rather than a complement: if threads have only partial information about the state, an observation should be satisfied only if there is positive evidence for it. Hence, e.g. v=n should be satisfied only if v has a value and it is not n, which is not captured by the complement from a Boolean algebra -the complement would also include partial functions that do not assign a value to v in the behavior of v=n. This is incorrect, because if v has no value in a partial observation, we might learn later that the actual value of v was in fact n, and it was therefore incorrect to assert v=n.
State modifications are interpreted as a set of elements u·a when applied to a set a. The pomsets u record the state modification surrounded by arbitrary state observations; in the first projection of the semantics of the assignment v←n we get a set of possible pomsets: Remark 8. We surround state changes and observations with arbitrary sequences of states to include global pomsets that have alternating modifications and states in the semantics. Reasoning about behavior of programs is more practical using such alternating pomsets, because the states allow one to take stock of the configuration of the machine in between modifications. The semantics contains also non-alternating pomsets to ensure compositionality w.r.t the parallel.
CNetKAT has six different syntactical units, some of which coincide semantically. There are two units for packets: drop, which drops all the packets ({1 · ∅}), and pass, which passes the current packets without changing the state ({1 · a} on input a). Similarly, we have two units for state observations: ⊥ and . The first one indicates an inconsistent state, and therefore the whole program exhibits no behavior; its behavior is ∅. The second one indicates any state observation is acceptable, and its behavior on input a is {s · a | s ∈ St}. Lastly there are two units for programs in general: abort, the program without behavior, and skip, the program where nothing happens (on input a its semantics is {1 · a}). Hence, abort is equivalent to ⊥ and skip equivalent to pass. All units behave as {1 · ∅} when the input set is ∅, because nothing happens when there are no packets.
The CNetKAT semantics consists of pairs of global state pomsets and sets of output packets. It might be possible to encode the information of the output packets as a final node in the pomset, but keeping the set of output packets separated allows us to easily track the input-output behavior of a program in terms of packets. This brings CNetKAT closer to NetKAT and its packet processing behavior. In particular, the NetKAT packet processing axioms, can only be used because we track the input-output behavior of the program separately.
To obtain the full semantics, and ensure we capture correctly the intended behavior, we need to perform a closure on the state component.
Definition 2 (Closed Semantics). Given a CNetKAT policy p, we define the semantics of p when applied to input a ∈ 2 Pk as Closure under exch and contr formalizes important intuitions about the semantics of concurrent threads. The closure under exch ensures all traces resulting from interleaving threads are included, and the closure under contr specifies that if two observations hold simultaneously, then it is possible to observe them in sequence. Note that the converse should not hold as some action could happen in between the two observations in a parallel thread.
We distinguish state, packet and deterministic packet programs as follows.
Definition 3 (State and deterministic packet programs). Let T packet denote packet programs, which are programs generated by the following grammar: Let T det−pack denote deterministic packet programs: 7 : x, y : In this paper we mostly use state programs over alphabet O∪Act∪2 Pk ∪{dup}. Whenever we intend to use this alphabet, we simply write T state .
We prove the following lemmas regarding the CNetKAT semantics.
Lemma 1 (State and packet program semantics). Let p ∈ T packet , s ∈ T state and a ∈ 2 Pk . For all w ∈ p (a), w is of the form For non-empty sets of packets a and a , the global behavior of a state program without dup is identical on both inputs. Let 2 Pk ne denote 2 Pk \ {∅}.
We characterize − B in terms of its behavior on subsets of the input set.
Lastly, we have a lemma characterising the semantics of a deterministic packet program in terms of its behavior on subsets of the input.

Is CNetKAT conservative over NetKAT and POCKA?
CNetKAT combines NetKAT and POCKA, so it is natural to ask whether it is a conservative extension of either language. It turns out that the answer is positive for POCKA, and for a fragment of NetKAT. We start by recalling the semantics of NetKAT [3]. Note that NetKAT expressions are packet programs without .
We can derive a further relation between the semantics if we assume there is no use of + and * (the proof uses Lemma 3).
Lemma 5. Let p be built out of packet predicates and modifications (f ←n), and their sequential composition. Then p (a) = 1 · x∈a p NK (x) .
It is worth remarking that the equational theories of NetKAT and CNetKAT are not equivalent: there are equivalent programs in NetKAT, that cannot be proved equivalent with the CNetKAT axioms, as the following example illustrates. Consider the program p + drop for p a packet program without parallel. In NetKAT, because the + is interpreted as multicast, this program is provably equivalent to p: executing p on your input packet while at the same time also dropping a copy of the input, has the same outcome as just executing p. In CNetKAT, however, this is not the case. Instead, the +-operator is interpreted as non-deterministic choice and in the semantics of p + drop we get the trace 1 · ∅, representing the choice of dropping all the packets, which is not present in the semantics of p. Hence, this axiom is unsound (p + drop ≡ p), and instead the alternative axiom p drop = p holds, reflecting the fact that is multicast.
We now show CNetKAT semantics is equivalent to the POCKA semantics on state programs. In [38], POCKA terms are what we defined as state programs over the alphabet O ∪Act, and they are interpreted in terms of pomset languages over assignments and states, encoded as partial functions, similarly to separation logic [34]. The POCKA semantics are defined in two steps: the first step results in a set containing all pomsets that can be derived directly from the terms, and in a second step this set is closed under two laws-exch and contr-that account for all traces that can be built in parallel threads (including simple interleaving).
The semantics of a POCKA expression p is p POCKA = p  exch∪contr .

Axiomatization
We introduce notation to describe packets and sets of packets axiomatically. Let f 1 , . . . , f k be a list of all fields of a packet in some fixed order. Then for each tuple n = n 1 , . . . , n k we obtain expressions f 1 = n 1 · · · f k = n k and f 1 ← n 1 · · · f k ← n k , which, similar to NetKAT, we call complete tests and complete assignments.
Complete tests are also referred to as atoms, because they are the atoms of the Boolean algebra generated by the tests. We denote the set of atoms by At, complete tests with α and complete assignments with π. There is a one-to-one correspondence between complete tests and assignments according to the values of n. For α ∈ At we denote the corresponding complete assignment by π α , and if π is a complete assignment we denote the corresponding atom by α π . There is also a link between sets of packets and terms of the form i∈I π i . For each set of packets a, we take the set {π i | i ∈ I} of complete assignments such that each π i corresponds to a packet of a, and combine them in parallel. Formally, for a set of packets a there exists an expression i∈I π i , that we denote with Π a , such that on any input b = ∅, Π a (b) = {1 · a}. Similarly, the semantics of an expression of the form i∈I π i on any input is always {1 · a} for some a ∈ 2 Pk . We use the notation Π a as a syntactic representation of set of packets a.
CNetKAT has the structure of a Kleene algebra on state programs, enriched with additional axioms. Tests form a Boolean algebra and state observations a pseudocomplemented distributive lattice (PCDL). The test and observation structures are subject to interaction constraints. The packet processing behavior is captured by the packet axioms, which contain axioms for individual packets and sets of packets. The axioms governing the parallel operator are partially familiar from earlier work on BKA [14,26]. There is also the exchange law familiar from CKA. Lastly, we have axioms for the interactions between state programs and packet programs. The full set of axioms is described in Figure 4. We write ≡ for the smallest congruence on Prg generated by the axioms in Figure 4.
Remark 9 (When is Π a equal to drop?). Π a ≡ drop if and only if a is empty.
There are a few subtleties to notice in Figure 4. First, we point out the interaction between drop and abort. When no packets are present, not even abort can be executed. Hence, if we drop all packets and then abort, the abort does not happen: drop ; abort ≡ drop. On the other hand, if we first abort and then drop all the packets, the behavior is equal to just aborting: abort ; drop ≡ abort.
In the axioms of the parallel operator, the axiom s skip ≡ skip from BKA is missing; it only holds when s is a state program, and can be found in the local state vs global state axioms. In addition to the familiar BKA axioms, there is the axiom drop p ≡ p, in contrast with abort p ≡ abort.
The local state vs global state axioms capture the interactions between the global pomset and the output packets. The first one, Π a ; dup ≡ Π a ; a, captures the intuition that if we know the input is a (due to Π a , which, as a parallel of complete assignments, essentially overwrites any non-empty input set to a), then we know the dup is recording an "a". The second axiom, Π a ; w ≡ w ; Π a states Kleene Algebra axioms s ∈ Tstate Fig. 4: Axioms of CNetKAT. The left column contains the KA axioms, the packet axioms, the axioms for the interaction between the local and global state, and an extensionality axiom. The right column axiomatizes the , the algebra of packet tests (which is a Boolean algebra), and the algebra of partial state observations (which is a PCDL). The interface axioms connect both the lattice operators to the Kleene algebra ones. We write e f as a shorthand for e + f ≡ f . that for dup-free state program w, we can flip the order between changing the set of output packets or performing the state changes in w, as long as Π a is not the parallel representing the empty set. This latter condition is crucial: if a = ∅, then Π a ≡ drop, and drop ; w ≡ drop (the global state changes in w do not get executed if we have no packets).
The axiom drop ; p ≡ drop for any program p captures the intuition that if there are no packets, nothing happens anymore. The other way around, y;drop ≡ drop is only true for y a packet program; if it was a state program, the global state changes get executed if we start with a non-empty set of input packets, making the behavior of y ; drop not equivalent to drop.
Lastly, extensionality says that if two programs are equivalent on all inputs (i.e., a ∈ 2 Pk ), then the programs are equivalent. It is not clear whether this axiom is derivable from the others; we hope to settle this question in the future.

Soundness and Completeness
In this section we prove soundness and completeness of the CNetKAT semantics w.r.t. the axiomatization from Figure 4. For soundness, we prove that if programs p and q are provably equivalent using the axioms, they have the same semantics: Conversely, we will prove that if p and q have the same semantics on all inputs a, then p ≡ q. We structure the completeness proof in four parts: 1. Define a normal form for CNetKAT programs, and show that for every input set a, every program is provably equivalent to a program in normal form in which a is incorporated. In other words, the normal form of a program is dependent on the input. Similar to NetKAT, normal form programs are CNetKAT expressions over complete assignments. We show that we have a simplified set of axioms on complete assignments and tests. 2. Obtain completeness for Π a -shaped programs from NetKAT completeness. 3. Using completeness of POCKA, obtain completeness for programs of the form s ; Π a (and sums thereof), where s is a state program. 4. Lastly, we combine these results to prove that if p and q have the same behavior on input a, the program Π a ; p is provably equivalent to Π a ; q.
Step 1: Normal form We prove that for every a ∈ 2 Pk , we can write any program p as Π a followed by a sum of state programs followed by a parallel of complete assignments. This is the most difficult step in the completeness proof.
We derive a few equivalences from Figure 4 regarding complete tests and assignments that make the proof of the normal form easier. We refer to these axioms as the reduced axioms. For α and β complete tests such that α = β, π and π complete assignments, and a ∈ 2 Pk ne , b ∈ 2 Pk , we can derive: All of these equivalences are easy consequences of the packet axioms, the packet predicate axioms, the axiom t ∧ B t ≡ t ; t and the fact that for all packet programs p we have p ; drop ≡ drop ≡ drop ; p [3]. The last reduced axiom is derived in Lemma 14 in Appendix D.
Theorem 4 (Normal form). Let p ∈ Prg and a ∈ 2 Pk . There exists a finite set J, and elements u j ∈ T state (O ∪ Act ∪ 2 Pk ) and b j ∈ 2 Pk for each j ∈ J s.t.
Sketch. The proof proceeds by induction on the structure of p. For instance, for an assignment f ←n, where we take Π a = k∈K π k for some non-empty finite index set K and complete assignments π k , we derive where π k is π k with the assignment for f replaced by f ←n. If K = ∅ then Π a ≡ drop and the equivalence above follows immediately. The most difficult case is the star; we use an argument that relies on the fact that matrices over a Kleene algebra form a Kleene algebra [21]. A proof can be found in Appendix D.
Step 2: Completeness for Π a -shaped programs As mentioned, Π ashaped programs are syntactic representations of packet sets. We prove that if two such programs result in the same set of packets on any non-empty input, they are provably equivalent, using that Π a describes a unique set of packets.
Step 3: Completeness of sums in the normal form We first prove completeness for state programs, where we use completeness of POCKA. To do so, some caution is needed; POCKA terms are state terms over the alphabet O ∪ Act. However, the state terms relevant here also include elements a ∈ 2 Pk .
Next we prove completeness for expressions of the form s ; Π a , and then extend this to arbitrary finite sums of such programs: Lemma 8. Let b, c ∈ 2 Pk , u, v state programs, and a ∈ 2 Pk ne . Then we have: where J, K are finite; u j , v k are state programs and b j , c k ∈ 2 Pk for each j, k.
Step 4: Completeness The last lemma before proving completeness relates the semantics of p on input a to the semantics of Π a ; p on any non-empty input. .
Proof. We first show that Π a ; p ≡ Π a ; q for all a ∈ 2 Pk . In case a = ∅, Π a must be the empty parallel. Hence, Π a ; p ≡ drop ≡ Π a ; q. In the rest of the proof we assume a = ∅. Via Lemma 10, we obtain that p . We obtain a normal form such that Π a ; p ≡ Π a ; With the partial completeness result from Lemma 9, we obtain that j∈J u j ; Hence, we have derived that Π a ; p ≡ Π a ; q for all a ∈ 2 Pk . With the extensionality axiom we can conclude that p ≡ q.

Examples
This section shows how we can use CNetKAT to model and analyze several concurrent programs. We start by analyzing the running example from §2, and then proceed to a more involved example that combines the behavior of a stateful firewall, a load balancer, and an in-network cache.

Running Example
Consider again the running example from §2. Because we are ultimately interested in the behavior of the program when the packets have reached their final destination, switch 4, we will add a test sw=4 at the end of the program: Recall that the CNetKAT semantics of a program contains traces that are only required to model executions where the program is composed in parallel with another program, to ensure a compositional semantics for the language. However, to analyze the behavior of a program in isolation, we want to eliminate these extra traces. To do this, we follow the same strategy used in [38], where so-called guarded pomsets were proposed. Guarded pomsets are a subclass of pomsets that captures the characteristics of behaviors of (concurrent) programs running in isolation. For example, in a guarded pomset, if one assertion, say v=0, occurs before another assertion, say v=1, there must be an assignment v←1 between the two asserts to account for the change. That is, in an isolated execution every change to variables must be explained by an action in the program.
To illustrate the difference between pomsets and guarded pomsets, consider our example. We unfold the Kleene star twice and evaluate the resulting program; we obtain a pair with output {♠[4/sw], ♥[4/sw]} and corresponding pomset, with α(v) = 0, β(v) = 1, and γ unrestricted. This pomset is guarded because it contains an arrow from v←1 to β, justifying the change in valuation from α to β. As we show in Appendix E, all guarded pomsets in the semantics will have this arrow, and satisfy the desired property: ♥ packets are observed at switch 3 before ♠ packets are observed at switch 2. Now consider the axiomatic claim we made in §2 (i.e., (2)), (♥ ♠);q (♥ ♠);p where q is the program from (1). We can easily see that the following holds: Hence, we can use Lemma 10 and the completeness result for CNetKAT (Theorem 5) to obtain (2).

Stateful Load Balancer, Cache, and Firewall
For a more complex example, consider the network in Figure 5, which is adapted from an example from [2]. The overall goal is to (i) prevent packets from a highpriority server S h going to low priority hosts l 1 , . . . , l k and (ii) load balance requests to the servers in a round robin fashion. We provide naive specifications for the cache, firewall and load balancer programs in Figure 5. For simplicity, we assume that there is exactly one low-priority host, and exactly one high-priority host, i.e., n = k = 1, and we leave the specification of the topology implicit.
Remark 10. In contrast with the previous example, the program in Figure 5 includes reads and writes of a global variable that occur on different physical devices. In principle, synchronizing variables like r would give rise to additional packets that update local copies of variables-a process that could itself be modelled in CNetKAT. We leave the implementation of a translation pass that achieves the synchronization of global variables across switches to future work. In [2], the authors point out a problem with the example that arises because the cache has no means to enforce the security policy. One strategy for resolving this problem is to swap the placement of the firewall and the cache. Another is to distribute access control rules onto the cache as well as the firewall. However, there is also a second, more subtle issue: the load balancer uses the global variable r to decide to which server to forward requests. In the presence of multiple packets, another packet may arrive before the change to the global variable occurs allowing two (or more!) packets to be sent to the same server.
The issue with the load balancer can be observed in the following example. Take as input packets ♠ and ♥ with ♠(src) = ♥(src) = l 1 . After being processed at the cache, both packets arrive at the firewall. One of the pairs in the semantics of the firewall F is the following, with α unrestricted and β(r) = 0: (α → (r←0) → β) · {♥[loadb/dst], ♠[loadb/dst]}. After processing by the load balancer, both packets are sent to s l simultaneously. To illustrate this event, we claim that there is a guarded pomset in the semantics of the load balancer. Observe that in the semantics of L we find the following pomset, with α and β from before (the second β is the result of the r=0 in L): Using closure under contraction, we obtain a guarded pomset (the two β-nodes are merged into one) where both packets appear at s l at the same time.
A final issue stems from the fact that the firewall implementation is flawed as written. Specifically, it uses a global variable to determine whether a packet should be forwarded on to a high priority host. Of course, if another packet arrives before the current one has been forwarded, the value of this variable might change, resulting in both packets being forwarded to a low priority host.
are sent to h 1 or l 1 . To illustrate how the packets travel to e.g. l 1 , we find the following pomset in the semantics of C, with α, β from before and γ(v) = 0: This pomset subsumes a guarded pomset. Hence, by exchange closure, we find guarded pomsets in the behavior of C where the packets both end up at l 1 .
Overall, these examples show that CNetKAT can model subtle interactions between packets that arise in the presence of concurrency and state. Moreover, the axiomatic semantics can be used to prove (in)equivalences between programs.

Related Work
The core of CNetKAT is two extensions of Kleene Algebra: NetKAT [3,11], a networking extension of Kleene algebra with tests, and POCKA [38], a concurrent extension of KA. NetKAT describes how single packets move through a network, whereas CNetKAT can handle multiple packets. POCKA was introduced to describe concurrent interactions of global variables, whereas CNetKAT makes use of this algebra to enable intra-packet communication. CNetKAT captures local and global state interactions which was not in any of the previous work.
In the family of KA extensions, POCKA is closest to Concurrent Kleene algebra with Observations (CKAO) [16,17], which was proposed to integrate concurrency with conditionals such as if-statements and while-loops. Contrary to CKAO, which uses a Boolean algebra to axiomatize conditionals, POCKA uses a pseudocomplemented distributive lattice (PCDL) as the algebra for tests, which are referred to as observations to mark the difference. The idea to use a PCDL as the algebra for observations was first proposed in [15].
Our work fits within the CKA tradition, which gives a true concurrency semantics and is thereby distinct from bisimulation semantics typically considered in process algebras, such as CSP and CCS. Another distinction is that CNetKAT uses global state rather than message passing.
Some recently published work has also extended NetKAT with constructs for modeling multi-packet behavior [8]. Here the goal is to model interactions between the control-and date-plane in dynamic updates. Parallel composition is axiomatized with a left-merge operator and a communication-merge operator, and semantics is in terms of bisimilarity instead of traces. The examples largely focus on the table updates, not on the flow of packets through the network.
The current paper deviates from earlier concurrent variations on NetKAT, such as Concurrent NetCore [36] and a stateful variant of NetKAT introduced in [32]. Both have a different algebraic structure than NetKAT. Concurrent Net-Core does not have Kleene star, and does not provide a denotational semantics, or axiomatization. Moreover, it does not handle multiple packets, the use of + in the language is multicast rather than non-determinism, and is concurrent processing of disjoint fields of the same packet. Because of these restrictions, concurrent NetCore is less suitable to specify inter-packet concurrency.
The approach in [32] models interactions among multiple packets, but is accompanied by semantic correctness guarantees, rather than algebraic formalizations as in CNetKAT. A recent PhD thesis [30] contains another version of stateful NetKAT, which assumes packet processing can always be serialized into a deterministic, global order. This assumption enables a simpler semantics and a decision procedure, though completeness is left as an open problem. Flow control in [30] is handled in the style of Guarded Kleene Algebra with Tests [23,37], which means that programs and specifications must be deterministic.
More broadly, there is a growing community doing research on network verification tools. Early work such as HSA [19], Anteater [31], Veriflow [20], Atomic Predicates [39], etc. focused on stateless SDN data planes, while more recent work such as p4v [28] and VMN [33] supports richer models such as P4 and stateful middleboxes. These tools typically use analyses based on symbolic simulation or they encode verification tasks into first-order formulas that can be checked using SMT solvers. To the best of our knowledge, CNetKAT is the first algebraic framework to model network-wide, multi-packet interaction with mutable state.

Discussion
We proposed CNetKAT, an algebraic framework to reason about programs with both local and global state, in the presence of parallel threads and control-flow statements. We provided a denotational semantics and a complete axiomatization. We also provided examples of how the language can be used to reason about stateful network programs and different sources of concurrency in a network.
As a result of the algebraic approach, the semantics of a program arises from the semantics of its parts. This clashes with the idea of observational equivalence when concurrency comes into play: some behaviors of a program can only be observed when executed concurrently with another program, and not in isolation. Hence it becomes necessary to include some elements in the semantics that do not immediately correspond to observable behavior. This implies that observational equivalence is not the right notion for axiomatising the semantics. However, using the greatest congruence contained in a notion of observational equivalence is interesting; this guided us in the development of our axiomatisation but it remains to be shown that our axiomatisation is indeed the greatest congruence.
CNetKAT relies on a classic approach to proving program correctness: develop a framework can model both specifications and implementations, and show that equivalence is decidable. Past experience with NetKAT suggests that this approach is usable, although CNetKAT lacks a procedure to check semantic equivalence, or at least membership of a given pomset. Devising an efficient procedure for this task is our immediate priority. The procedure will most likely rely on automata models such as fork automata [29] or Petri automata [7,6].
Ultimately, we would like to use CNetKAT to reason about stateful and distributed P4 programs. A target case study is provided in [10], which implemented Lamport's Paxos algorithm in the forwarding plane. To show correctness, the authors used a translation to Promela, a model checking language, and specify check that learners never decide on separate values for a single instance of consensus. This property is closely related to guarded pomsets. We would like to use CNetKAT to show correctness of the P4 implementation of the protocol directly (translation from the P4 code is almost direct, see Figure 6 for an example).
The reader will notice that the CNetKAT expression in Figure 6 uses an action of the form f ←v, where f is a field (inst) and v a global variable (instance). Adding actions of the converse form v←f is trivial since the packet logic specifies that f always has exactly one value. However, actions f ←v require more care: the value of global variables can only be determined at the end since parallel threads might change it while it is being copied. To accommodate this in the semantics, we will have to allow partially defined packet fields and determine the missing field values at the end (when we check for guarded traces).
Another exciting direction for future work is the development of a library of litmus tests for networking in the spirit of [1]. Litmus tests are carefully crafted concurrent programs operating on shared memory locations that expose subtle bugs in memory models of hardware. One could imagine using the guarded pomsets semantics to discover minimal witnesses of undesired concurrent behavior.
We would also like to investigate the memory model of CNetKAT; this would give insight into the rules followed by operations on the global state. For a partial answer, we can look at POCKA. The guarded fragment of the POCKA semantics was shown to be sequentially consistent (concurrent memory accesses behave as if they are executed sequentially [25]), as it passed the store buffering litmus test [1]. The guarded fragment of the pomsets recording global variable changes is expected to pass this litmus test as well. It is worth investigating whether CNetKAT also supports other weak memory models, such as linearizability. The images or other third party material in this chapter are included in the chapter's Creative Commons license, unless indicated otherwise in a credit line to the material. If material is not included in the chapter's Creative Commons license and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need to obtain permission directly from the copyright holder.

A Proofs for Section 3.1 (Pomsets and pomset languages)
Formally, u v holds iff there exists a surjection h : S v → S u satisfying: (i) The following lemma was shown in [17]: Lemma 11. Let L be a pomset language. We have L↓ exch∪contr = ( L↓ exch )   contr .
Hence, we know that U ∈ L↓ exch∪contr if and only if there exists W ∈ L↓ exch and V ∈ L such that U W V .

B Proofs for Section 3.2 (Syntax and Semantics)
The following properties concerning the interaction between closure and other operators can be useful. Here , · and the star all have their usual interpretation on pomset languages. That is, We can prove the following properties about our closure definition.
Proof. For the first item, take w ∈ p  (a). Thus w = u·b such that v·b ∈ p (a) and u ∈ {v}  exch∪contr . Then v · b ∈ q  (a) and the desired result follows immediately. For the other direction we take w ∈ p (a). As w = u · b for some u and b and u ∈ {u}  exch∪contr , we also have that w ∈ p  (a). From the assumption it then immediately follows that w ∈ q  (a). For the second item, we take w ∈ p + q  (a). Hence, w = u · b such that v·b ∈ p + q (a) = p (a)∪ q (a) and u ∈ {v}  exch∪contr . W.l.o.g. we can assume v·b ∈ p (a), and by definition we then immediately we obtain that u ∈ p  (a). For the other direction we take w ∈ p  (a), and thus w = u · b such that v · b ∈ p (a), and u ∈ {v}  exch∪contr . Then immediately v · b ∈ p + q (a) and . For the third item, take a word w ∈ p ; q  (a). Hence, w = u · b such that v · b ∈ p ; q (a) and u ∈ {v}  exch∪contr . From this we obtain that v = x · y for x · a ∈ p (a) and y · b ∈ q (a ). Using 1, we then conclude that x · a ∈ p  (a) and y · b ∈ q  (a ). We need that u ∈ {x · y}  exch∪contr , but this is immediate as v = x · y.
For the other direction, we take w · b such that u · a ∈ p  (a), v · b ∈ q  (a ), and w ∈ {u · v}  exch∪contr . Hence, from Definition 2 we obtain that there exists x and y such that x · a ∈ p (a), y · b ∈ q (a ), u ∈ {x}  exch∪contr , and v ∈ {y}  exch∪contr . We can conclude that (x · y) · b ∈ p ; q  (a). The only The proof of the fourth item is analogous but instead uses 4 of Lemma 12.
For the fifth item, we observe that by definition Lemma 1 (State and packet program semantics). Let p ∈ T packet , s ∈ T state and a ∈ 2 Pk . For all w ∈ p (a), w is of the form 1 · b for b ∈ 2 Pk . For all w ∈ s (a), w is of the form v · a for v a pomset over St ∪ Act ∪ 2 Pk .
Proof. Both statements are proven with an easy induction on p and s.
Proof. The result is proven with an easy induction on s.
Proof. We prove this by induction on t. The cases where t = drop or t = pass are trivial.
For the negation we derive Note that if we have π ∈ a such that π / ∈ t B (a), then also π / ∈ t B (b) for any set of packets b, because if π / ∈ t B (a) while π ∈ a, we know that π does not satisfy predicate t.
In the middle step we use that if a packet π ∈ t B (a)∪ t B (b) and π ∈ t B (a)∪ t B (b), then we know that π satisfies predicate t and t , and w.l.o.g. π is an element of a. Then also π ∈ t B (a) ∩ t B (a). Similarly, if π ∈ t B (a) ∩ t B (a) or π ∈ t B (b) ∩ t B (b) we can w.l.o.g. assume the former. We then know that π satisfies both t and t and hence is an element of t B (a) ∪ t B (b) and of t B (a) ∪ t B (b).
Lemma 4. Let x ∈ T det−pack and a, b ⊆ Pk. Then Proof. We prove this by induction on x. For x = t ∈ B we use Lemma 3.
For p + q we calculate: For p;q, we first note that for packet programs without parallel, the semantics of p on a single input packet, consists of pairs 1 · b such that b = {x} for x ∈ Pk or b = ∅. We derive For p * we first prove by induction on n that if p NK (π) = {a | 1 · a ∈ p (a)}, then for all n we have p (n) NK (π) = {a | 1 · a ∈ p (n) (a)}. The base case is trival as p 0 NK (π) = {π}, and p (0) (a) = skip (a) = {1 · {π}}. For the inductive step, the induction hypothesis is p (n) NK (π) = {a | 1 · a ∈ p (n) (a)}. Then we derive (IH and the case for p ; q) Then we can derive: Let p be built out of packet predicates and modifications (f ←n), and their sequential composition. Then p (a) = 1 · x∈a p NK (x) .
Proof. If a = ∅, the result follows immediately. If a = ∅, we prove this by induction on p. For p = t ∈ B we derive In the inductive step we derive Proof. We first show by induction on the structure of p that the theorem holds without closures. We show that The For p + q we calculate: For p ; q, we have: For p q, we have: For the case with the star, first note that from p (a) = {u · a | u ∈ p } and the case for sequential composition, we can derive p (n) (a) = {u · a | u ∈ p (n) }.

D Proofs for Section 4 (Soundness and Completeness)
Lemma 14. Let a ∈ 2 Pk ne and b ∈ 2 Pk . Then we can derive using the axioms of CNetKAT that Proof. We know there exists finite index sets I, J and complete assignments π i , π j such that Π a ≡ i∈I π i and Π b ≡ j∈J π j . Then we can derive using the axioms of CNetKAT that ≡ j∈J i∈I π j (π ; π ≡ π (shown to follow from packet axioms in [3])) ≡ j∈J π j Theorem 3 (Soundness). For all p, q ∈ Prg, if p ≡ q, then p  = q  .
Proof. We proceed by induction on ≡. In most cases we prove soundness of the axioms before closure, in which case the semantics is also sound after closure. For two axioms the closure is crucial for soundness, and we provide a soundness result only after the closure is computed. We prove that for all a ∈ 2 Pk we have p  (a) = q  (a). If a = ∅, the result follows immediately as then p (a) = {1 · ∅} = q (a). If a = ∅, we give direct proofs for all the axioms. Note that regardless of whether a is ∅ or not p + q (a) = p (a) ∪ q (a), We start with the axioms of KA. As + is defined as ∪, associativity, commutativity and idempotence of the + follow immediately. The axiom p + abort ≡ p is also immediately satisfied. For the other axioms we give a direct proof.
We consider the axiom p ; (q ; r) ≡ (p ; q) ; r. Let a be a set of packets. We derive In the third step we used the fact that sequential composition on pomsets is associative.
The next axiom we verify is s ; abort ≡ abort for s a state program and abort ; p ≡ p for all programs p. We derive ∈ q (a), v · b ∈ r (a )} = p ; r (a) ∪ q ; r (a) = p ; r + q ; r (a) Next is p * ≡ skip + pp * Take an element x ∈ p * (a). Thus x ∈ p (n) (a) for some n ∈ N. If n = 0, then x ∈ skip (a) = {1 · a} ⊆ skip + p ; p * (a). If n > 0, then x ∈ p ; p (n−1) . Hence, x = (u · v) · b such that u · a ∈ p (a) and v · b ∈ p (n−1) (a ). From the latter we obtain that v · b ∈ p * (a ). As u · a ∈ p (a), we then get that x ∈ p ; p * (a) ⊆ skip + p ; p * (a). For the other direction, we first observe that skip (a) ⊆ p * (a). Then take an x ∈ p ; p * (a). Hence, x = (u · v) · b such that u · a ∈ p (a) and v · b ∈ p * (a ). From the later we can conclude that there exists an n ∈ N such that v · b ∈ p (n) (a ). Hence, x ∈ p ; p (n) (a) = p n+1 (a) and we obtain subsequently that x ∈ p * (a). The other star-axiom is verified in a similar way.
For the first least fixpoint axiom we assume that p + q ; r  (a) ⊆ q  (a) for all a. If w ∈ p ; r * (a), then w = (u · v) · b such that u · a ∈ p (a) and v·b ∈ r * (a ). Either v·b = 1·a , in which case w ∈ q  (a) follows immediately from the premise, or v · b = (v 1 · · · v n )c n for v i c i ∈ r (c i−1 ) and c 0 = a . Note that u · a ∈ q  (a) because of the premise. Then (u · v 1 ) · c 1 ∈ q  (a) because of the premise as well. Repeating this, we get that w ∈ q  (a). The other least fixpoint axiom is verified similarly.
Next are the axioms for the parallel, which we will also prove directly. For associativity, where we use associativity of union and of parallel composition of pomsets, we derive Commutativity of the parallel follows in a similar manner.
The next axiom for the parallel is distributivity over plus.
For the exchange law we give a direct proof. Let s, s , v and v be state programs. It is sufficient to prove (s s ) ; Then by definition of the closed CNetKAT semantics we can conclude that v · a ∈ (s ; v) (s ; v )  (a). Soundness of all but the last three of the packet axioms follows directly from Lemma 5 and soundness of NetKAT for those axioms [3,Theorem 1].
For the last three packet axioms let x be a deterministic packet program. Observe that this means that x (a) = {1 · b} for some (possibly empty) set of packets b (Lemma 16, Item 2).
For the extensionality axiom we derive for any a ∈ 2 Pk and b ∈ 2 Pk (a) using Lemma 10. Next we prove the interface axioms, which we will also prove directly. Take a word w ∈ o ∧ o (a). Hence w = (u 1 αu 2 ) · a and u 1 , u 2 ∈ St * and α ∈ o O ∩ o O . Then (u 1 α) · a ∈ o (a) and (αu 2 ) · a ∈ o (a). Because of Lemma 1 we can then conclude that (u 1 ααu 2 ) · a ∈ o ; o (a). As u 1 αu 2 u 1 ααu 2 , we obtain from Definition 1 that u 1 αu 2 ∈ {u 1 ααu 2 }  exch∪contr . From Definition 2, we can then immediately conclude that (u 1 αu 2 ) · a = w ∈ o ; o  (a). For the next axiom we derive The axiom abort ≡ ⊥ is verified immediately as they both are interpreted as the empty set. The axiom skip ≡ pass is also verified immediately by definition.
For the next axiom we derive The axioms o ; o, e ; e and ; e e are verified similarly. The last two interface axioms are the following.
We now check the local state vs global state axioms. Let x be a deterministic packet program.
For any program p we derive Take y a packet program.
Let s be a state program.
Let y, z be packet programs and s, v state programs.
The packet predicate and state observation axioms need to be proven both for elements from B and for elements from O. For the latter we use that − O is identical to − OA and soundness for those semantics is proven in [38,Theorem 3.8]. For the former, we use that ∪ and ∩ (interpretations of ∨ B and ∧ B ) satisfy all those properties. The additional state observation axioms also follow from [38,Theorem 3.8]. The only axioms left to check are the additional packet predicate axioms.
Let m = n. Observe that this entails for a set of packets a that a(f =n) ∩ a(f =m) = ∅, as packets cannot have two different values for one field.
This is because i f =i B (a) is the union of all the filters f =i on a for all possible values i of f , and each packet in a has a value for f . Hence, each packet is an element of f =i B (a) for some i.
In the inductive step we need to check whether the closure rules for congruence have been preserved. We distinguish four cases. If p = p 0 +p 1 and q = q 0 +q 1 with p 0 ≡ q 0 and p 1 ≡ q 1 , then by induction we know that p 0  (a) = q 0  (a) and p 1  (a) = q 1  (a) for all a ∈ 2 Pk . Via property 2 of Lemma 13, we obtain that For the next case we consider p = p 0 ; p 1 and q = q 0 ; q 1 with p 0 ≡ q 0 and p 1 ≡ q 1 . Using property 3 from Lemma 13 and the induction hypothesis we immediately obtain The case for p = p 0 p 1 and q = q 0 q 1 is analogous but instead uses 4 of Lemma 13.
For p = p * 0 and p 0 ≡ q 0 . We derive (IH and previous case) Theorem 4 (Normal form). Let p ∈ Prg and a ∈ 2 Pk . There exists a finite set J, and elements u j ∈ T state (O ∪ Act ∪ 2 Pk ) and b j ∈ 2 Pk for each j ∈ J s.t.
Proof. Let Π a = k∈K π k . In case K = ∅, the equivalence follows immediately, as drop ; p ≡ drop for any program p. In the rest of the proof we assume K = ∅. We prove the claim by induction on the structure of p. For the case p = t ∈ B, we note that the complete tests are the atoms (minimal nonzero elements) of the Boolean algebra generated by the tests. Hence, we know that each element t can be written as a disjunction of all the atoms below t ([4, Chapter 5.9]). We derive ≡ Π a ; skip ; k∈K,απ k ≤ B t (π k ) (p ; skip ≡ p) For p = skip, we just use that skip ≡ pass and the case above.
In the next base case we let p = f ←n. We derive where π k is π k with the assignment for f replaced by (f ←n).
The next three bases cases are for state actions and the rest of the state observations. Let p = v←n. The case for p = b ∈ 2 Pk and p = o ∈ O is identical.
We derive For the case where p = abort, we use that ⊥ ≡ abort and the case above.
The last base case is for dup. We derive We have four inductive cases.
For p + q we derive For p q we derive This last line is already in the desired format, using associativity of the parallel. Now we make a case distinction for each element from the sum. For each j we have Π bj equal to drop or not. In case it is equal to drop, we have b j = ∅ (see Remark 9), we can derive for this j and any m that In case Π bj is not equal to drop, we have b j = ∅ and we derive Hence, every element in the sum in is provably equivalent to an expression such that the sum becomes an expression in normal form.
For p * , we need a more complicated argument. We are going to use the fact that matrices over a Kleene algebra form a Kleene algebra [21]. We first construct a set Q of syntactic representations of sets of packets.
Q is finite because from the induction hypothesis we know that K is finite for each sum, and Q exists out parallel products of packets, and we only have finitely many of such terms (up-to-equivalence), because parallel composition is idempotent on complete assignments (direct representation of a packet), and we only have finitely many complete assignments, because we have finitely many fields and values.
Next we define a Q×Q-matrix M . If R = ∅ and R;p and addition is defined pointwise.
We now prove that where the expression on the right has the correct format for the normal form, because all elements of M * are state programs: they are formed out of elements of M , which are state programs, and the Kleene algebra operators.
We start with . To apply one of the fixpoint axioms, we need to prove that Then the desired result follows from one of the fixpoint axioms. We first show that Π a Π a ; R∈Q M * (Π a , R) ; R Let 1 be the identity matrix. Because all the Kleene algebra axioms hold on state programs, the elements of the matrix M have a Kleene algebra structure. Then, because matrices over a Kleene algebra form a Kleene algebra, we have 1 + M ; M * ≡ M * (axiom of KA) [21]. From this we can conclude that 1 M * , and thus 1(Π a , Π a ) M * (Π a , Π a ). We also know that 1(Π a , Π a ) = skip. We derive The last step we can do because Π a ≡ drop and M * (Π a , Π a ) is a state program. We now have proved (5). Next we show that We first apply distributivity and the induction hypothesis to obtain In order to prove (6), it thus suffices to show that for all R and all k we have and u k ; Π b k is one of the entries of that sum). Then we derive From the fact that matrices over a Kleene algebra form a Kleene algebra we know that M * ; M M * . Hence We also know that Putting (7) and (8) together we obtain From this we obtain As we already had that we can now conclude from (9) and (10) that which concludes the proof of (6). Then (5) and (6) together lead to (4). This concludes the -direction.
For the other direction ( ) we need to prove that This is exactly what we needed to prove. We now prove that indeed M * ; V V . We use one of the fixpoint axioms. We need to show that V + M ; V V . We prove this pointwise for all R ∈ Q. We first show that V (R) V (R). This follows immediately as V (R) = R and V (R) = R ; p * . Now we need to prove that for any R ∈ Q we have (M ; V )(R) V (R). We derive for S ≡ Π b k and R ; u k ; S R ; p. Thus we need to prove that for all u k such that S ≡ Π b k and R ; u k ; S R ; p we have The following lemma rewrites the elements in a sum such that the packet elements are all unique.
Lemma 15. Let J be a finite index set, u j state programs and Π bj finite parallels of complete assignments for some sets of packets b j . Then any expression j∈J u j ; Π bj is provably equivalent to an expression j ∈J u j ; Π b j for finite index set J , state programs u j and finite parallels of complete assignments Π b j such that for all x, y ∈ J , it holds that Π bx ≡ Π by .
Proof. We prove this by induction on the size of J. If J = ∅, we are done immediately. If | J |= n + 1, we let K be J \ {l} for l ∈ J. We derive where for all k, k ∈ K we have that Π b k ≡ Π b k via the induction hypothesis. If there does not exists k ∈ K such that Π b l ≡ Π b k , we are immediately done. If such a k does exist, we know via the induction hypothesis there is only one. We derive Hence, for all l, l ∈ K it is the case that Π b l ≡ Π b l and j∈J u j ; Π bj ≡ j ∈K \{k} u j ; Π b j + (u k + u l ) ; Π b k Because (u k + u l ) is a state program, this proves the required result.
The next lemma states some basic facts about the semantics of state and packet programs, and their sequential composition.
Lemma 16. Let s ∈ T state , x ∈ T packet , and a ∈ 2 Pk . Then we have Proof. For the first item (1) we derive Because s is a state program, we know that a = a, and because x is a packet program, we know that v = 1. Hence The second item (2) can be proven with induction on the structure of x. The result follows easily because packet programs do not influence the state pomset (Lemma 1), and and ; do not introduce multiple elements in the output.
Proof. As π and π are complete assignments, they assign a value to each field. Because π  (a) = {1 · {x}} = π  (a) for some packet x, both π and π must assign to each field the same value. Using commutativity of independent assignments, we obtain that π ≡ π . Lemma 6. Let a ∈ 2 Pk ne , and b, c ∈ 2 Pk . If Π b Proof. Take finite parallels of complete assignments i∈I π i and j∈J π j such that i∈I π i ≡ Π b and j∈J π j ≡ Π c . Let − p : C → Pk, where C is the set of complete assignments, be defined as π p := x for π (b) = {1 · {x}} for some non-empty set of packets b (this is independent of the choice of b). The function − p is surjective, and thus has at least one right inverse. We denote it with r : Pk → C. Hence, we have r(x) p = x. We now show that Note that for a complete assignment and non-empty set of packets π i (a) = {1 · {x}} for some x ∈ Pk. We derive Then we obtain using soundness that As π i p and π j p are always just a packet for all i ∈ I and j ∈ J, we can conclude from associativity, idempotence and commutativity of the parallel on deterministic packet programs that i∈I r( π i p ) ≡ j∈J r( π j p ) As r is a right inverse we can derive r( π i p ) p = π i p Using Lemma 17, we obtain that r( π i p ) ≡ π i . Hence, we can conclude that We now slightly generalize the completeness proof from [38].
Lemma 18. Take the POCKA terms over alphabet O ∪ Act ∪ 2 Pk , let s, v be such terms, and extend Definition 5 with a = {a} for a ∈ 2 Pk . If s POCKA = v POCKA , then s ≡ POCKA v.
Proof. We need to extend the result of [38,Theorem 4.6]. This result is built on Lemma 4.1, Lemma 4.2, Lemma 4.3 and Lemma 4.4 from the same paper, which we need to extend first. The homomorphism r gets an extra clause and is defined instead as the homomorphic extension of Lemma 4.1 from [38], which states that for all POCKA programs e, we have e ≡ POCKA r(e), can be proven in the exact same way as in [38], except that there is an extra base case for a ∈ 2 Pk , which follows immediately. Lemma 4.2 from the same paper shows the unclosed POCKA semantics of a program e is equivalent to the BKA semantics of r(e) after closure under a set of hypotheses called top.
In the current paper we do not provide this definition, but for the reader familiar with this framework: letters a ∈ 2 Pk do not occur in top, and hence the BKAsemantics of r(a) for a ∈ 2 Pk closed under top is just {a}. This is a new base case in the proof, and the rest of the proof follows in the same way. Lemma 4.3 is independent of the POCKA terms, so can be copied immediately. For Lemma 4.4, we need to extend s with the clause s(a) = a for a ∈ 2 Pk . The result that the homomorphism s generated by s is such that for all POCKA terms we have e ≡ s(e) still holds as the only added base case is trivial. The other claim, that the BKA semantics of s(e) are the same as the BKA semantics of e closed under top, also follows immediately as the BKA semantics of s(a) = {a} and the BKA semantics of a closed under top is {a} as well. Then we can repeat the exact proof as is given in [38] for Lemma 4.6 (completeness).
Lemma 7. Let s, v ∈ T state (O ∪ Act ∪ 2 Pk ) and a ∈ 2 Pk ne . If s Proof. The proof of Theorem 2 can trivially be extended with an extra base case for b ∈ 2 Pk , as b (a) = {b · a}. Hence, from s  (a) = v  (a) we obtain via Theorem 2 that s POCKA = v POCKA . Now we use Lemma 18 to conclude that s ≡ POCKA v, and as all the axioms of POCKA on state terms are axioms of CNetKAT, we obtain that s ≡ v.
Lemma 8. Let b, c ∈ 2 Pk , u, v state programs, and a ∈ 2 Pk ne . Then we have: Proof. Via Lemma 16 item 1 and 2, we obtain that Π b = {1 · d} = Π c (a) for some d ∈ 2 Pk . We can use Lemma 6 to obtain that Next we show that For w ∈ u  (a) we know via Lemma 1 and the definition of closure that w = u · a, u ∈ {u }  contr∪exch and u · a ∈ u (a). Via Lemma 16 we obtain that u · d ∈ u ; Π b  (a) and via our assumption that u · d ∈ v ; Π c  (a). Via Lemma 16 we can conclude that u · a ∈ v  (a). The other direction is argued symmetrically. Via Lemma 7, we obtain from (12) that Combining (11) and (13) we obtain where J, K are finite; u j , v k are state programs and b j , c k ∈ 2 Pk for each j, k.
Proof. We can use Lemma 15 to obtain a sum that is provably equivalent to j∈J u j ; Π bj where it holds that for all j, j in the sum, we have Π bj ≡ Π b j . Via soundness, the semantics of this expression is equivalent to the semantics of j∈J u j ; Π bj . For simplicity we will not rename variables; we simply assume that in j∈J u j ; Π bj it is the case that for all j, j ∈ J, we have Π bj ≡ Π b j .
Take any j ∈ J. Take w ∈ j∈J u j ; Π bj   (a). Because of property 2 from Lemma 13, we know that Hence, there exists a j ∈ J such that w ∈ u j ; Π bj  (a). Via Lemma 16, we get that w = u · d for some state pomset u and Π bj (a) = {1 · d}. Because of our assumption, we know there exists a k ∈ K such that w ∈ v k ; Π c k  (a). Via Lemma 16 we get that Π c k (a) = {1 · d}. Now we prove that in fact The left-to-right inclusion is already proven. For the right-to-left inclusion we take w ∈ v k ; Π c k  (a). Via Lemma 16 and the fact that Π c k (a) = {1 · d}, we obtain that w = v · d for some state pomset v. Because of our assumption, we know there exists an n ∈ J such that w ∈ u n ; Π bn  (a). Suppose that n = j. Via Lemma 16 and the fact that w = v · d we obtain that Π bn (a) = {1 · d}. Hence Π bn  (a) = Π bj  (a) and we obtain Π bn ≡ Π bj via Lemma 6. This is a contradiction with Lemma 15. Hence, j = n. This proves (14). Now we can use Lemma 8 to obtain that for all j ∈ J there exists k ∈ K such that Similarly, we can prove (15) for all k ∈ K. Via idempotence, cummatativity and associativity of + we can then conclude that Lemma 10. Let b ∈ 2 Pk ne , a ∈ 2 Pk . For all p ∈ Prg, Π a ; p Proof. We prove instead that Π a ; p (b) = p (a), which directly implies the statement we need to show. Using the fact that Π a (x) = {1 · a} for any nonempty set of packets x, we have directly that Π a ;

E Analysis of Example
We follow the same strategy used in [38], where they identified a type of pomset called a guarded pomset. It was demonstrated that guarded pomsets have seven characteristics of behaviors of (possibly concurrent) programs in isolation, and that if a pomset represents some execution of an isolated program, it must be guarded. We need the following definitions from [38] for the proofs on guardedness. First, we define the result of a state after updating it for one value. Let a ∈ Act and α ∈ St. We say that α[a] exists if a = v←n for some n ∈ Val or a = v←v and v ∈ dom(α). If α[a] exists, we define it for all w ∈ Var as follows: Second, we define a binary operator ⊕ on St to combine states. For α, β ∈ St: for all v ∈ dom(α) ∩ dom(β) undefined otherwise Definition 6. The set of guarded pomsets, denoted G, is the smallest set satisfying: Guardedness in pomsets can be characterized by the conjunction of seven properties [38,Theorem 5.9]. We only need two of those properties in the proofs that follow, which we will write out below.
A path for a variable v from a state-node u to another state-node s is a chain such that the changes in the value of v between u and s are explained by the actions between them and recorded in all the states between u and s. Definition 7 (Path). Let u ∈ Pom(Act∪St) and u 1 , u 2 ∈ S u such that u 1 ≤ u u 2 and λ u (u 1 ), λ u (u 1 ) ∈ St. We say a path p v from u 1 to u 2 for variable v ∈ Var is a sequence of nodes q 1 , a 1 , . . . , a n , q n+1 ∈ S u that satisfy the following conditions: (P1) For all 1 ≤ i ≤ n, we have λ u (a i ) ∈ Act and u 1 ≤ u a i ≤ u u 2 for all i.
Additionally we require that a i ≤ u a i+1 for 1 ≤ i < n. (P2) For all 1 ≤ i ≤ n + 1 it holds that λ u (q i ) ∈ St, and for all 1 ≤ i ≤ n, the predecessor of a i is q i , and the successor of a i is q i+1 . Additionally we have that λ u (q 1 ) = λ u (u 1 ), v ∈ dom(λ u (u 1 )) and λ u (q n+1 ) = λ u (u 2 ). Lastly, for 1 ≤ i ≤ n we have: n λ u (a i ) = v←n for some n ∈ Val λ u (q i )(v ) λ u (a i ) = v←v for some v ∈ dom(λ u (q i )) λ u (q i )(v) otherwise Property (A5): (A5) If u ∈ S u such that λ u (u) = v←n for some v ∈ Var and n ∈ Val, we require that the successor of u is s s.t. λ u (s)(v) = n.
Property (A7): (A7) Let u ∈ S u be a state-node. Then for all v ∈ dom(λ u (u)), there exists a path for v from s ∈ S u to u such that either v ∈ dom(λ u (s)) and s = * min or s is the successor of an assignment-node with label v←k with k ∈ Var ∪ Val.
Lastly, we need the following definition and lemma.
Definition 8 (Bottleneck). Let u ∈ Pom(Act ∪ St) and u 0 , u 1 , u 2 ∈ S u . We say u 1 is a bottleneck between u 0 and u 2 if u 0 ≤ u u 1 ≤ u u 2 and for all u 3 ∈ S u s.t. u 0 ≤ u u 3 we have u 1 ≤ u u 3 or u 3 ≤ u u 1 .
We use the following result in the proofs below ([38, Lemma C.3]): Lemma 19. Let u ∈ Pom(Act ∪ St) and u 1 , u 2 ∈ S u s.t. u 1 ≤ u u 2 . If there exists a path p v from u 1 to u 2 , and a bottleneck u 3 between them, then the bottleneck is on p v .
We now return to our running example. In order to identify the isolated behaviors of p, we thus have to filter out the pairs where the state pomset is guarded. Guarded pomsets are defined specifically for pomsets whose nodes are labeled with state observations and state modifications, and our pomsets also have nodes labeled with elements from 2 Pk . When deciding whether a behavior is guarded, we simply study the pomset of a behavior, and then in particular the nodes labeled with state observations and state modifications, and see whether they form a guarded pomset. If they do, we call the original behavior guarded.
In order to show that all guarded behaviors in the semantics of the running example record the ♥ packets at switch 3 before they record the ♠ packets at switch 2, we first show that all state pomsets of the pairs in the semantics of p have a certain property P . We then claim that if a pomset has this property, and is guarded, it must be such that the ♥ packets are recorded at switch 3 before the ♠ packets are recored at switch 2.
We first look at the semantics of the running example before closure, after which we define property P . We are interested in the behavior of the program when the packets have reached their final destination (switch 4). Hence, we add a test (sw=4) to the end, to ensure the packets have arrived at switch 4: p (v←0) ; (p 1 p 2 p 3 p 4 ) * ; (sw=4) If we input packets {♥, ♠} at switch 1, after one iteration of the Kleene star (before closure of the semantics), we get the following distirbution of packets when we multicast according to p: In terms of packets, the output looks like {♠[2/sw], ♥[3/sw]}. In terms of global state pomset, the output may look like the following, with β(v) = 1: The other state pomsets in the semantics of (v←0) ; (p 1 p 2 p 3 p 4 ) are pomsets with the same nodes and ordering as the one above but with extra St * -nodes around state observations and assignments.
In the next iteration of the Kleene star we obtain the output set of packets We now define property P , which contains some characteristics of the global state pomset in each pair in the semantics of p that we can use later to show that all guarded pomsets in the semantics of the running example record the ♥ packets at switch 3 before they record the ♠ packets at switch 2.
1. the following conditions hold: Graphically, we can represent these conditions as the following diagram: 2. For all nodes z ∈ S u we have the following conditions.
∀z.λ u (z) = (v←k) ⇒ z = u 2 ∨ z = u 1 S u .z ≤ u u 1 ∨ u 1 ≤ u z ∃π ∈ λ u (z) ∈ 2 Pk .π(sw) = 3 ∧ π(tag) = ♥ ⇒ u 4 ≤ u z ∃π ∈ λ u (z) ∈ 2 Pk .π(sw) = 2 ∧ π(tag) = ♠ ⇒ u 5 ≤ u z The property P describes global asserts and modifications and sets of packets found in the running example, and their relative ordering. The condition ∀z.λ u (z) = (v←k) ⇒ z = u 2 ∨ z = u 1 entails that there are only two nodes in the pomset labeled with an action that modifies v. The condition ∀z ∈ S u .z ≤ u u 1 ∨ u 1 ≤ u z implies that u 1 is always on any sequence of nodes between the minimal node of u and u 3 . The last two conditions entail that u 4 and u 5 are the first times in the execution that respectively ♥ packets are present at switch 3 and ♠ packets are present at switch 2.
Lemma 20. Let u be a pomset with P (u). If u is guarded, then u 2 ≤ u u 3 .
Proof. We use characteristics (A5) and (A7) of guarded pomsets, which u satisfies as we assume it is guarded. We take node u 3 , which is a node with state label β such that β(v) = 1. According to (A7), this then means that there exists a path for v from the minimal node of the pomset, let us denote it with * min , to u 3 or there exists a path for v from a node s to u 3 and s is the successor of an assignment-node with label v←k for some k ∈ Var ∪ Val. In the former case, we use Lemma 19 to conclude that u 1 is on the path for v from * min to u 3 . Then, via (A5), we obtain that u 1 has a successor node t such that λ u (t) = α with α(v) = 0. By definition of successor, this means that u 1 ≤ u t ≤ u u 3 , and via the properties of Definition 7 there must exist at least one node q labeled with v←k such that t ≤ u q ≤ u u 3 altering the value of v, as the path must explain how the value of v changed from 0 to 1. Via item 2 of property P , we then know that q = u 2 (q cannot be u 1 as that would imply that u 1 ≤ u t ≤ u u 1 which is a contradiction as u 1 and t do not have the same labels), and thus u 2 ≤ u u 3 .
In the latter case, s has to be the successor of u 1 or u 2 via item 2 of property P . In the former case, we obtain that u 1 ≤ u s, and again via property (A5) we get that λ u (s) = α and α(v) = 0. For there to be a path from s to u 3 for v, we obtain in similar fashion as before that u 2 ≤ u u 3 . In the latter case, thus if s is the successor of u 2 , we get that u 2 ≤ u s. For there to be a path from s to u 3 we need s ≤ u u 3 . This implies then that u 2 ≤ u u 3 .
Note that this entails via transitivity that u 4 ≤ u u 5 , and thus that the ♥ packets arrived at switch 3 before the ♠ packets arrived at switch 2.
We return to our running example and study its semantics closed under contraction and subsumption. We show that property P is preserved: Lemma 21. Let a ∈ 2 Pk ne . For all u · b ∈ p  (a), it holds that P (u).
Proof. It is clear that for all u such that u · b ∈ p (a), we have P (u). For u·b ∈ p  (a), we know that v·b ∈ p (a) and u ∈ {v}  exch∪contr . Via Lemma 11 and the definition of closure under exch and contr, we can conclude that there exists a pomset w such that u w v. We also know that P (v). We now show that then also P (w) and P (u). From the definition of we get that there exists a bijective pomset morhphism h from v to w. Thus, h is a bijective function from S v to S w such that λ w • h = λ v and if u ≤ v u then h(u) ≤ w h(u ). Now we need to verify the properties of Definition 10.