# Theory SequentialComposition

(*  Title:       Conservation of CSP Noninterference Security under Sequential Composition
Author:      Pasquale Noce
Security Certification Specialist at Arjo Systems, Italy
pasquale dot noce dot lavoro at gmail dot com
pasquale dot noce at arjosystems dot com
*)

section "Sequential composition and noninterference security"

theory SequentialComposition
imports Propaedeutics
begin

text ‹
\null

This section formalizes the definitions of sequential processes and sequential composition given in
\<^cite>‹"R4"›, and then proves that under the assumptions discussed above, noninterference security is
conserved under sequential composition for any pair of processes sharing an alphabet that contains
successful termination. Finally, this result is generalized to an arbitrary list of processes.
›

subsection "Sequential processes"

text ‹
In \<^cite>‹"R4"›, a \emph{sequential process} is defined as a process whose alphabet contains successful
termination. Since sequential composition applies to sequential processes, the first problem put by
the formalization of this operation is that of finding a suitable way to represent such a process.

A simple but effective strategy is to identify it with a process having alphabet @{typ "'a option"},
where @{typ 'a} is the native type of its ordinary (i.e. distinct from termination) events. Then,
ordinary events will be those matching pattern ‹Some _›, whereas successful termination will
be denoted by the special event @{term None}. This means that the \emph{sentences} of a sequential
process, defined in \<^cite>‹"R4"› as the traces after which the process can terminate successfully, will
be nothing but the event lists @{term xs} such that @{term "xs @ [None]"} is a trace (which implies
that @{term xs} is a trace as well).

Once a suitable representation of successful termination has been found, the next step is to
formalize the properties of sequential processes related to this event, expressing them in terms of
the selected representation. The first of the resulting predicates, ‹weakly_sequential›, is
the minimum required for allowing the identification of event @{term None} with successful
termination, namely that @{term None} may occur in a trace as its last event only. The second
predicate, ‹sequential›, following what Hoare does in \<^cite>‹"R4"›, extends the first predicate
with an additional requirement, namely that whenever the process can engage in event @{term None},
it cannot engage in any other event. A simple counterexample shows that this requirement does not
imply the first one: a process whose traces are @{term "{[], [None], [None, None]}"} satisfies the
second requirement, but not the first one.

Moreover, here below is the definition of a further predicate, ‹secure_termination›, which
applies to a security policy rather than to a process, and is satisfied just in case the policy does
not allow event @{term None} to be affected by confidential events, viz. by ordinary events not
allowed to affect some event in the alphabet. Interestingly, this property, which will prove to be
necessary for the target theorem to hold, is nothing but the CSP counterpart of a condition required
for a security type system to enforce termination-sensitive noninterference security of programs,
namely that program termination must not depend on confidential data (cf. \<^cite>‹"R5"›, section 9.2.6).

\null
›

definition sentences :: "'a option process ⇒ 'a option list set" where
"sentences P ≡ {xs. xs @ [None] ∈ traces P}"

definition weakly_sequential :: "'a option process ⇒ bool" where
"weakly_sequential P ≡
∀xs ∈ traces P. None ∉ set (butlast xs)"

definition sequential :: "'a option process ⇒ bool" where
"sequential P ≡
(∀xs ∈ traces P. None ∉ set (butlast xs)) ∧
(∀xs ∈ sentences P. next_events P xs = {None})"

definition secure_termination :: "('d × 'd) set ⇒ ('a option ⇒ 'd) ⇒ bool" where
"secure_termination I D ≡
∀x. (D x, D None) ∈ I ∧ x ≠ None ⟶ (∀u ∈ range D. (D x, u) ∈ I)"

text ‹
\null

Here below is the proof of some useful lemmas involving the constants just defined. Particularly, it
is proven that process sequentiality is indeed stronger than weak sequentiality, and a sentence of a
refusals union closed (cf. \<^cite>‹"R3"›), sequential process admits the set of all the ordinary events
of the process as a refusal. The use of the latter lemma in the proof of the target security
conservation theorem is the reason why the theorem requires to assume that the first of the
processes to be composed be refusals union closed (cf. below).

\null
›

lemma seq_implies_weakly_seq:
"sequential P ⟹ weakly_sequential P"

lemma weakly_seq_sentences_none:
assumes
WS: "weakly_sequential P" and
A: "xs ∈ sentences P"
shows "None ∉ set xs"
proof -
have "∀xs ∈ traces P. None ∉ set (butlast xs)"
using WS by (simp add: weakly_sequential_def)
moreover have "xs @ [None] ∈ traces P"
using A by (simp add: sentences_def)
ultimately have "None ∉ set (butlast (xs @ [None]))" ..
thus ?thesis
by simp
qed

lemma seq_sentences_none:
assumes
S: "sequential P" and
A: "xs ∈ sentences P" and
B: "xs @ y # ys ∈ traces P"
shows "y = None"
proof -
have "∀xs ∈ sentences P. next_events P xs = {None}"
using S by (simp add: sequential_def)
hence "next_events P xs = {None}"
using A ..
moreover have "(xs @ [y]) @ ys ∈ traces P"
using B by simp
hence "xs @ [y] ∈ traces P"
by (rule process_rule_2_traces)
hence "y ∈ next_events P xs"
ultimately show ?thesis
by simp
qed

lemma seq_sentences_ref:
assumes
A: "ref_union_closed P" and
B: "sequential P" and
C: "xs ∈ sentences P"
shows "(xs, {x. x ≠ None}) ∈ failures P"
(is "(_, ?X) ∈ _")
proof -
have "(∃X. X ∈ singleton_set ?X) ⟶
(∀X ∈ singleton_set ?X. (xs, X) ∈ failures P) ⟶
(xs, ⋃X ∈ singleton_set ?X. X) ∈ failures P"
using A by (simp add: ref_union_closed_def)
moreover have "∃x. x ∈ ?X"
by blast
hence "∃X. X ∈ singleton_set ?X"
ultimately have "(∀X ∈ singleton_set ?X. (xs, X) ∈ failures P) ⟶
(xs, ⋃X ∈ singleton_set ?X. X) ∈ failures P" ..
moreover have "∀X ∈ singleton_set ?X. (xs, X) ∈ failures P"
proof (rule ballI, simp add: singleton_set_def del: not_None_eq,
erule exE, erule conjE, simp (no_asm_simp))
fix x :: "'a option"
assume D: "x ≠ None"
have "xs @ [None] ∈ traces P"
using C by (simp add: sentences_def)
hence "xs ∈ traces P"
by (rule process_rule_2_traces)
hence "(xs, {}) ∈ failures P"
by (rule traces_failures)
hence "(xs @ [x], {}) ∈ failures P ∨ (xs, {x}) ∈ failures P"
by (rule process_rule_4)
thus "(xs, {x}) ∈ failures P"
proof (rule disjE, rule_tac ccontr, simp_all)
assume "(xs @ [x], {}) ∈ failures P"
hence "xs @ [x] ∈ traces P"
by (rule failures_traces)
with B and C have "x = None"
by (rule seq_sentences_none)
thus False
qed
qed
ultimately have "(xs, ⋃X ∈ singleton_set ?X. X) ∈ failures P" ..
thus ?thesis
by (simp only: singleton_set_union)
qed

subsection "Sequential composition"

text ‹
In what follows, the definition of the failures resulting from the sequential composition of two
processes @{term P}, @{term Q} given in \<^cite>‹"R4"› is formalized as the inductive definition of set
‹seq_comp_failures P Q›. Then, the sequential composition of @{term P} and @{term Q},
denoted by means of notation ‹P ; Q› following \<^cite>‹"R4"›, is defined as the process having
‹seq_comp_failures P Q› as failures set and the empty set as divergences set.

For the sake of generality, this definition is based on the mere implicit assumption that the input
processes be weakly sequential, rather than sequential. This slightly complicates things, since the
sentences of process @{term P} may number further events in addition to @{term None} in their
future.

Therefore, the resulting refusals of a sentence @{term xs} of @{term P} will have the form
@{term "insert None X ∩ Y"}, where @{term X} is a refusal of @{term xs} in @{term P} and @{term Y}
is an initial refusal of @{term Q} (cf. rule ‹SCF_R2›). In fact, after @{term xs}, process
‹P ; Q› must be able to refuse @{term None} if @{term Q} is, whereas it cannot refuse an
ordinary event unless both @{term P} and @{term Q}, in their respective states, can.

Moreover, a trace @{term xs} of ‹P ; Q› may result from different combinations of a sentence
of @{term P} with a trace of @{term Q}. Thus, in order that the refusals of ‹P ; Q› be
closed under set union, the union of any two refusals of @{term xs} must still be a refusal (cf.
rule ‹SCF_R4›). Indeed, this property will prove to be sufficient to ensure that for any two
processes whose refusals are closed under set union, their sequential composition still be such,
which is what is expected for any process of practical significance (cf. \<^cite>‹"R3"›).

According to the definition given in \<^cite>‹"R4"›, a divergence of ‹P ; Q› is either a
divergence of @{term P}, or the concatenation of a sentence of @{term P} with a divergence of
@{term Q}. Apparently, this definition does not match the formal one stated here below, which
identifies the divergences set of ‹P ; Q› with the empty set. Nonetheless, as remarked
above, sequential composition does not make sense unless the input processes are weakly sequential,
since this is the minimum required to confer the meaning of successful termination on the
corresponding alphabet symbol. But a weakly sequential process cannot have any divergence, so that
the two definitions are actually equivalent. In fact, a divergence is a trace such that, however it
is extended with arbitrary additional events, the resulting event list is still a trace (cf. process
properties @{term process_prop_5} and @{term process_prop_6} in \<^cite>‹"R2"›). Therefore, if @{term xs}
were a divergence, then @{term "xs @ [None, None]"} would be a trace, which is impossible in case
the process satisfies predicate @{term weakly_sequential}.

\null
›

inductive_set seq_comp_failures ::
"'a option process ⇒ 'a option process ⇒ 'a option failure set"
for P :: "'a option process" and Q :: "'a option process" where

SCF_R1: "⟦xs ∉ sentences P; (xs, X) ∈ failures P; None ∉ set xs⟧ ⟹
(xs, X) ∈ seq_comp_failures P Q" |

SCF_R2: "⟦xs ∈ sentences P; (xs, X) ∈ failures P; ([], Y) ∈ failures Q⟧ ⟹
(xs, insert None X ∩ Y) ∈ seq_comp_failures P Q" |

SCF_R3: "⟦xs ∈ sentences P; (ys, Y) ∈ failures Q; ys ≠ []⟧ ⟹
(xs @ ys, Y) ∈ seq_comp_failures P Q" |

SCF_R4: "⟦(xs, X) ∈ seq_comp_failures P Q; (xs, Y) ∈ seq_comp_failures P Q⟧ ⟹
(xs, X ∪ Y) ∈ seq_comp_failures P Q"

definition seq_comp ::
"'a option process ⇒ 'a option process ⇒ 'a option process" (infixl ";" 60)
where
"P ; Q ≡ Abs_process (seq_comp_failures P Q, {})"

text ‹
\null

Here below is the proof that, for any two processes @{term P}, @{term Q} defined over the same
alphabet containing successful termination, set @{term "seq_comp_failures P Q"} indeed enjoys the
characteristic properties of the failures set of a process as defined in \<^cite>‹"R2"› provided that
@{term P} is weakly sequential, which is what happens in any meaningful case.

\null
›

lemma seq_comp_prop_1:
"([], {}) ∈ seq_comp_failures P Q"
proof (cases "[] ∈ sentences P")
case False
moreover have "([], {}) ∈ failures P"
by (rule process_rule_1)
moreover have "None ∉ set []"
by simp
ultimately show ?thesis
by (rule SCF_R1)
next
case True
moreover have "([], {}) ∈ failures P"
by (rule process_rule_1)
moreover have "([], {}) ∈ failures Q"
by (rule process_rule_1)
ultimately have "([], {None} ∩ {}) ∈ seq_comp_failures P Q"
by (rule SCF_R2)
thus ?thesis by simp
qed

lemma seq_comp_prop_2_aux [rule_format]:
assumes WS: "weakly_sequential P"
shows "(ws, X) ∈ seq_comp_failures P Q ⟹
ws = xs @ [x] ⟶ (xs, {}) ∈ seq_comp_failures P Q"
proof (erule seq_comp_failures.induct, rule_tac [!] impI, simp_all, erule conjE)
fix X'
assume
A: "(xs @ [x], X') ∈ failures P" and
B: "None ∉ set xs"
have A': "(xs, {}) ∈ failures P"
using A by (rule process_rule_2)
show "(xs, {}) ∈ seq_comp_failures P Q"
proof (cases "xs ∈ sentences P")
case False
thus ?thesis
using A' and B by (rule SCF_R1)
next
case True
have "([], {}) ∈ failures Q"
by (rule process_rule_1)
with True and A' have "(xs, {None} ∩ {}) ∈ seq_comp_failures P Q"
by (rule SCF_R2)
thus ?thesis by simp
qed
next
fix X'
assume A: "(xs @ [x], X') ∈ failures P"
hence A': "(xs, {}) ∈ failures P"
by (rule process_rule_2)
show "(xs, {}) ∈ seq_comp_failures P Q"
proof (cases "xs ∈ sentences P")
case False
have "∀xs ∈ traces P. None ∉ set (butlast xs)"
using WS by (simp add: weakly_sequential_def)
moreover have "xs @ [x] ∈ traces P"
using A by (rule failures_traces)
ultimately have "None ∉ set (butlast (xs @ [x]))" ..
hence "None ∉ set xs" by simp
with False and A' show ?thesis
by (rule SCF_R1)
next
case True
have "([], {}) ∈ failures Q"
by (rule process_rule_1)
with True and A' have "(xs, {None} ∩ {}) ∈ seq_comp_failures P Q"
by (rule SCF_R2)
thus ?thesis by simp
qed
next
fix xs' ys Y
assume
A: "xs' @ ys = xs @ [x]" and
B: "xs' ∈ sentences P" and
C: "(ys, Y) ∈ failures Q" and
D: "ys ≠ []"
have "∃y ys'. ys = ys' @ [y]"
using D by (rule_tac xs = ys in rev_cases, simp_all)
then obtain y and ys' where D': "ys = ys' @ [y]"
by blast
hence "xs = xs' @ ys'"
using A by simp
thus "(xs, {}) ∈ seq_comp_failures P Q"
proof (cases "ys' = []", simp_all)
case True
have "xs' @ [None] ∈ traces P"
using B by (simp add: sentences_def)
hence "xs' ∈ traces P"
by (rule process_rule_2_traces)
hence "(xs', {}) ∈ failures P"
by (rule traces_failures)
moreover have "([], {}) ∈ failures Q"
by (rule process_rule_1)
ultimately have "(xs', {None} ∩ {}) ∈ seq_comp_failures P Q"
by (rule SCF_R2 [OF B])
thus "(xs', {}) ∈ seq_comp_failures P Q"
by simp
next
case False
have "(ys' @ [y], Y) ∈ failures Q"
using C and D' by simp
hence C': "(ys', {}) ∈ failures Q"
by (rule process_rule_2)
with B show "(xs' @ ys', {}) ∈ seq_comp_failures P Q"
using False by (rule SCF_R3)
qed
qed

lemma seq_comp_prop_2:
assumes WS: "weakly_sequential P"
shows "(xs @ [x], X) ∈ seq_comp_failures P Q ⟹
(xs, {}) ∈ seq_comp_failures P Q"
by (erule seq_comp_prop_2_aux [OF WS], simp)

lemma seq_comp_prop_3 [rule_format]:
"(xs, Y) ∈ seq_comp_failures P Q ⟹ X ⊆ Y ⟶
(xs, X) ∈ seq_comp_failures P Q"
proof (induction arbitrary: X rule: seq_comp_failures.induct, rule_tac [!] impI)
fix xs X Y
assume
A: "xs ∉ sentences P" and
B: "(xs, X) ∈ failures P" and
C: "None ∉ set xs" and
D: "Y ⊆ X"
have "(xs, Y) ∈ failures P"
using B and D by (rule process_rule_3)
with A show "(xs, Y) ∈ seq_comp_failures P Q"
using C by (rule SCF_R1)
next
fix xs X Y Z
assume
A: "xs ∈ sentences P" and
B: "(xs, X) ∈ failures P" and
C: "([], Y) ∈ failures Q" and
D: "Z ⊆ insert None X ∩ Y"
have "Z - {None} ⊆ X"
using D by blast
with B have "(xs, Z - {None}) ∈ failures P"
by (rule process_rule_3)
moreover have "Z ⊆ Y"
using D by simp
with C have "([], Z) ∈ failures Q"
by (rule process_rule_3)
ultimately have "(xs, insert None (Z - {None}) ∩ Z) ∈ seq_comp_failures P Q"
by (rule SCF_R2 [OF A])
moreover have "insert None (Z - {None}) ∩ Z = Z"
by blast
ultimately show "(xs, Z) ∈ seq_comp_failures P Q"
by simp
next
fix xs ys X Y
assume
A: "xs ∈ sentences P" and
B: "(ys, Y) ∈ failures Q" and
C: "ys ≠ []" and
D: "X ⊆ Y"
have "(ys, X) ∈ failures Q"
using B and D by (rule process_rule_3)
with A show "(xs @ ys, X) ∈ seq_comp_failures P Q"
using C by (rule SCF_R3)
next
fix xs X Y Z
assume
A: "⋀W. W ⊆ X ⟶ (xs, W) ∈ seq_comp_failures P Q" and
B: "⋀W. W ⊆ Y ⟶ (xs, W) ∈ seq_comp_failures P Q" and
C: "Z ⊆ X ∪ Y"
have "Z ∩ X ⊆ X ⟶ (xs, Z ∩ X) ∈ seq_comp_failures P Q"
using A .
hence "(xs, Z ∩ X) ∈ seq_comp_failures P Q"
by simp
moreover have "Z ∩ Y ⊆ Y ⟶ (xs, Z ∩ Y) ∈ seq_comp_failures P Q"
using B .
hence "(xs, Z ∩ Y) ∈ seq_comp_failures P Q"
by simp
ultimately have "(xs, Z ∩ X ∪ Z ∩ Y) ∈ seq_comp_failures P Q"
by (rule SCF_R4)
hence "(xs, Z ∩ (X ∪ Y)) ∈ seq_comp_failures P Q"
moreover have "Z ∩ (X ∪ Y) = Z"
using C by (rule Int_absorb2)
ultimately show "(xs, Z) ∈ seq_comp_failures P Q"
by simp
qed

lemma seq_comp_prop_4:
assumes WS: "weakly_sequential P"
shows "(xs, X) ∈ seq_comp_failures P Q ⟹
(xs @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs, insert x X) ∈ seq_comp_failures P Q"
proof (erule seq_comp_failures.induct, simp_all)
fix xs X
assume
A: "xs ∉ sentences P" and
B: "(xs, X) ∈ failures P" and
C: "None ∉ set xs"
have "(xs @ [x], {}) ∈ failures P ∨
(xs, insert x X) ∈ failures P"
using B by (rule process_rule_4)
thus "(xs @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs, insert x X) ∈ seq_comp_failures P Q"
proof
assume D: "(xs @ [x], {}) ∈ failures P"
show ?thesis
proof (cases "xs @ [x] ∈ sentences P")
case False
have "None ∉ set (xs @ [x])"
proof (simp add: C, rule notI)
assume "None = x"
hence "(xs @ [None], {}) ∈ failures P"
using D by simp
hence "xs @ [None] ∈ traces P"
by (rule failures_traces)
hence "xs ∈ sentences P"
thus False
qed
with False and D have "(xs @ [x], {}) ∈ seq_comp_failures P Q"
by (rule SCF_R1)
thus ?thesis ..
next
case True
have "([], {}) ∈ failures Q"
by (rule process_rule_1)
with True and D have "(xs @ [x], {None} ∩ {}) ∈ seq_comp_failures P Q"
by (rule SCF_R2)
thus ?thesis by simp
qed
next
assume "(xs, insert x X) ∈ failures P"
with A have "(xs, insert x X) ∈ seq_comp_failures P Q"
using C by (rule SCF_R1)
thus ?thesis ..
qed
next
fix xs X Y
assume
A: "xs ∈ sentences P" and
B: "(xs, X) ∈ failures P" and
C: "([], Y) ∈ failures Q"
show "(xs @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs, insert x (insert None X ∩ Y)) ∈ seq_comp_failures P Q"
proof (cases "x = None", simp)
case True
have "([] @ [None], {}) ∈ failures Q ∨ ([], insert None Y) ∈ failures Q"
using C by (rule process_rule_4)
thus "(xs @ [None], {}) ∈ seq_comp_failures P Q ∨
(xs, insert None (insert None X ∩ Y)) ∈ seq_comp_failures P Q"
proof (rule disjE, simp)
assume "([None], {}) ∈ failures Q"
moreover have "[None] ≠ []"
by simp
ultimately have "(xs @ [None], {}) ∈ seq_comp_failures P Q"
by (rule SCF_R3 [OF A])
thus ?thesis ..
next
assume "([], insert None Y) ∈ failures Q"
with A and B have "(xs, insert None X ∩ insert None Y)
∈ seq_comp_failures P Q"
by (rule SCF_R2)
moreover have "insert None X ∩ insert None Y =
insert None (insert None X ∩ Y)"
by blast
ultimately have "(xs, insert None (insert None X ∩ Y))
∈ seq_comp_failures P Q"
by simp
thus ?thesis ..
qed
next
case False
have "(xs @ [x], {}) ∈ failures P ∨ (xs, insert x X) ∈ failures P"
using B by (rule process_rule_4)
thus ?thesis
proof (rule disjE, cases "xs @ [x] ∈ sentences P")
assume
D: "xs @ [x] ∉ sentences P" and
E: "(xs @ [x], {}) ∈ failures P"
have "None ∉ set xs"
using WS and A by (rule weakly_seq_sentences_none)
hence "None ∉ set (xs @ [x])"
using False by (simp del: not_None_eq)
with D and E have "(xs @ [x], {}) ∈ seq_comp_failures P Q"
by (rule SCF_R1)
thus ?thesis ..
next
assume
"xs @ [x] ∈ sentences P" and
"(xs @ [x], {}) ∈ failures P"
moreover have "([], {}) ∈ failures Q"
by (rule process_rule_1)
ultimately have "(xs @ [x], {None} ∩ {}) ∈ seq_comp_failures P Q"
by (rule SCF_R2)
thus ?thesis by simp
next
assume D: "(xs, insert x X) ∈ failures P"
have "([] @ [x], {}) ∈ failures Q ∨ ([], insert x Y) ∈ failures Q"
using C by (rule process_rule_4)
thus ?thesis
proof (rule disjE, simp)
assume "([x], {}) ∈ failures Q"
moreover have "[x] ≠ []"
by simp
ultimately have "(xs @ [x], {}) ∈ seq_comp_failures P Q"
by (rule SCF_R3 [OF A])
thus ?thesis ..
next
assume "([], insert x Y) ∈ failures Q"
with A and D have "(xs, insert None (insert x X) ∩ insert x Y)
∈ seq_comp_failures P Q"
by (rule SCF_R2)
moreover have "insert None (insert x X) ∩ insert x Y =
insert x (insert None X ∩ Y)"
by blast
ultimately have "(xs, insert x (insert None X ∩ Y))
∈ seq_comp_failures P Q"
by simp
thus ?thesis ..
qed
qed
qed
next
fix xs ys Y
assume
A: "xs ∈ sentences P" and
B: "(ys, Y) ∈ failures Q" and
C: "ys ≠ []"
have "(ys @ [x], {}) ∈ failures Q ∨ (ys, insert x Y) ∈ failures Q"
using B by (rule process_rule_4)
thus "(xs @ ys @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs @ ys, insert x Y) ∈ seq_comp_failures P Q"
proof
assume "(ys @ [x], {}) ∈ failures Q"
moreover have "ys @ [x] ≠ []"
by simp
ultimately have "(xs @ ys @ [x], {}) ∈ seq_comp_failures P Q"
by (rule SCF_R3 [OF A])
thus ?thesis ..
next
assume "(ys, insert x Y) ∈ failures Q"
with A have "(xs @ ys, insert x Y) ∈ seq_comp_failures P Q"
using C by (rule SCF_R3)
thus ?thesis ..
qed
next
fix xs X Y
assume
"(xs @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs, insert x X) ∈ seq_comp_failures P Q" and
"(xs @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs, insert x Y) ∈ seq_comp_failures P Q"
thus "(xs @ [x], {}) ∈ seq_comp_failures P Q ∨
(xs, insert x (X ∪ Y)) ∈ seq_comp_failures P Q"
proof (cases "(xs @ [x], {}) ∈ seq_comp_failures P Q", simp_all)
assume
"(xs, insert x X) ∈ seq_comp_failures P Q" and
"(xs, insert x Y) ∈ seq_comp_failures P Q"
hence "(xs, insert x X ∪ insert x Y) ∈ seq_comp_failures P Q"
by (rule SCF_R4)
thus "(xs, insert x (X ∪ Y)) ∈ seq_comp_failures P Q"
by simp
qed
qed

lemma seq_comp_rep:
assumes WS: "weakly_sequential P"
shows "Rep_process (P ; Q) = (seq_comp_failures P Q, {})"
proof (subst seq_comp_def, rule Abs_process_inverse, simp add: process_set_def,
(subst conj_assoc [symmetric])+, (rule conjI)+)
show "process_prop_1 (seq_comp_failures P Q, {})"
qed (rule seq_comp_prop_1)
next
show "process_prop_2 (seq_comp_failures P Q, {})"
proof (simp add: process_prop_2_def del: all_simps, (rule allI)+, rule impI)
qed (rule seq_comp_prop_2 [OF WS])
next
show "process_prop_3 (seq_comp_failures P Q, {})"
proof (simp add: process_prop_3_def del: all_simps, (rule allI)+, rule impI,
erule conjE)
qed (rule seq_comp_prop_3)
next
show "process_prop_4 (seq_comp_failures P Q, {})"
proof (simp add: process_prop_4_def, (rule allI)+, rule impI)
qed (rule seq_comp_prop_4 [OF WS])
next
show "process_prop_5 (seq_comp_failures P Q, {})"
next
show "process_prop_6 (seq_comp_failures P Q, {})"
qed

text ‹
\null

Here below, the previous result is applied to derive useful expressions for the outputs of the
functions returning the elements of a process, as defined in \<^cite>‹"R2"› and \<^cite>‹"R3"›, when acting on
the sequential composition of a pair of processes.

\null
›

lemma seq_comp_failures:
"weakly_sequential P ⟹
failures (P ; Q) = seq_comp_failures P Q"
by (drule seq_comp_rep [where Q = Q], simp add: failures_def)

lemma seq_comp_divergences:
"weakly_sequential P ⟹
divergences (P ; Q) = {}"
by (drule seq_comp_rep [where Q = Q], simp add: divergences_def)

lemma seq_comp_futures:
"weakly_sequential P ⟹
futures (P ; Q) xs = {(ys, Y). (xs @ ys, Y) ∈ seq_comp_failures P Q}"

lemma seq_comp_traces:
"weakly_sequential P ⟹
traces (P ; Q) = Domain (seq_comp_failures P Q)"

lemma seq_comp_refusals:
"weakly_sequential P ⟹
refusals (P ; Q) xs ≡ seq_comp_failures P Q  {xs}"

lemma seq_comp_next_events:
"weakly_sequential P ⟹
next_events (P ; Q) xs = {x. xs @ [x] ∈ Domain (seq_comp_failures P Q)}"

subsection "Conservation of refusals union closure and sequentiality under sequential composition"

text ‹
Here below is the proof that, for any two processes @{term P}, @{term Q} and any failure
@{term "(xs, X)"} of @{term "P ; Q"}, the refusal @{term X} is the union of a set of refusals where,
for any such refusal @{term W}, @{term "(xs, W)"} is a failure of @{term "P ; Q"} by virtue of one
of rules ‹SCF_R1›, ‹SCF_R2›, or ‹SCF_R3›.

The converse is also proven, under the assumption that the refusals of both @{term P} and @{term Q}
be closed under union: namely, for any trace @{term xs} of @{term "P ; Q"} and any set of refusals
where, for any such refusal @{term W}, @{term "(xs, W)"} is a failure of the aforesaid kind, the
union of these refusals is still a refusal of @{term xs}.

The proof of the latter lemma makes use of the axiom of choice.

\null
›

lemma seq_comp_refusals_1:
"(xs, X) ∈ seq_comp_failures P Q ⟹ ∃R.
X = (⋃n ∈ {..length xs}. ⋃W ∈ R n. W) ∧
(∀W ∈ R 0.
xs ∉ sentences P ∧ None ∉ set xs ∧ (xs, W) ∈ failures P ∨
xs ∈ sentences P ∧ (∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)) ∧
(∀n ∈ {0<..length xs}. ∀W ∈ R n.
take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q) ∧
(∃n ∈ {..length xs}. ∃W. W ∈ R n)"
(is "_ ⟹ ∃R. ?T R xs X")
proof (erule seq_comp_failures.induct, (erule_tac [4] exE)+)
fix xs X
assume
A: "xs ∉ sentences P" and
B: "(xs, X) ∈ failures P" and
C: "None ∉ set xs"
show "∃R. ?T R xs X"
proof (rule_tac x = "λn. if n = 0 then {X} else {}" in exI,
simp add: A B C, rule equalityI, rule_tac [!] subsetI, simp_all)
fix x
assume "∃n ∈ {..length xs}.
∃W ∈ if n = 0 then {X} else {}. x ∈ W"
thus "x ∈ X"
by (simp split: if_split_asm)
qed
next
fix xs X Y
assume
A: "xs ∈ sentences P" and
B: "(xs, X) ∈ failures P" and
C: "([], Y) ∈ failures Q"
show "∃R. ?T R xs (insert None X ∩ Y)"
proof (rule_tac x = "λn. if n = 0 then {insert None X ∩ Y} else {}" in exI,
simp add: A, rule conjI, rule equalityI, rule_tac [1-2] subsetI, simp_all)
fix x
assume "∃n ∈ {..length xs}.
∃W ∈ if n = 0 then {insert None X ∩ Y} else {}. x ∈ W"
thus "(x = None ∨ x ∈ X) ∧ x ∈ Y"
by (simp split: if_split_asm)
next
show "∃U. (xs, U) ∈ failures P ∧ (∃V. ([], V) ∈ failures Q ∧
insert None X ∩ Y = insert None U ∩ V)"
proof (rule_tac x = X in exI, rule conjI, simp add: B)
qed (rule_tac x = Y in exI, rule conjI, simp_all add: C)
qed
next
fix xs ys Y
assume
A: "xs ∈ sentences P" and
B: "(ys, Y) ∈ failures Q" and
C: "ys ≠ []"
show "∃R. ?T R (xs @ ys) Y"
proof (rule_tac x = "λn. if n = length ys then {Y} else {}" in exI,
simp add: A B C, rule equalityI, rule_tac [!] subsetI, simp_all)
fix x
assume "∃n ∈ {..length xs + length ys}.
∃W ∈ if n = length ys then {Y} else {}. x ∈ W"
thus "x ∈ Y"
by (simp split: if_split_asm)
qed
next
fix xs X Y Rx Ry
assume
A: "?T Rx xs X" and
B: "?T Ry xs Y"
show "∃R. ?T R xs (X ∪ Y)"
proof (rule_tac x = "λn. Rx n ∪ Ry n" in exI, rule conjI, rule_tac [2] conjI,
rule_tac [3] conjI, rule_tac [2] ballI, (rule_tac [3] ballI)+)
have "X ∪ Y = (⋃n ≤ length xs. ⋃W ∈ Rx n. W) ∪
(⋃n ≤ length xs. ⋃W ∈ Ry n. W)"
using A and B by simp
also have "… = (⋃n ≤ length xs. (⋃W ∈ Rx n. W) ∪ (⋃W ∈ Ry n. W))"
by blast
also have "… = (⋃n ≤ length xs. ⋃W ∈ Rx n ∪ Ry n. W)"
by simp
finally show "X ∪ Y = (⋃n ≤ length xs. ⋃W ∈ Rx n ∪ Ry n. W)" .
next
fix W
assume "W ∈ Rx 0 ∪ Ry 0"
thus
"xs ∉ sentences P ∧ None ∉ set xs ∧ (xs, W) ∈ failures P ∨
xs ∈ sentences P ∧ (∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)"
(is "?T' W")
proof
have "∀W ∈ Rx 0. ?T' W"
using A by simp
moreover assume "W ∈ Rx 0"
ultimately show ?thesis ..
next
have "∀W ∈ Ry 0. ?T' W"
using B by simp
moreover assume "W ∈ Ry 0"
ultimately show ?thesis ..
qed
next
fix n W
assume C: "n ∈ {0<..length xs}"
assume "W ∈ Rx n ∪ Ry n"
thus
"take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q"
(is "?T' n W")
proof
have "∀n ∈ {0<..length xs}. ∀W ∈ Rx n. ?T' n W"
using A by simp
hence "∀W ∈ Rx n. ?T' n W"
using C ..
moreover assume "W ∈ Rx n"
ultimately show ?thesis ..
next
have "∀n ∈ {0<..length xs}. ∀W ∈ Ry n. ?T' n W"
using B by simp
hence "∀W ∈ Ry n. ?T' n W"
using C ..
moreover assume "W ∈ Ry n"
ultimately show ?thesis ..
qed
next
have "∃n ∈ {..length xs}. ∃W. W ∈ Rx n"
using A by simp
then obtain n where C: "n ∈ {..length xs}" and D: "∃W. W ∈ Rx n" ..
obtain W where "W ∈ Rx n"
using D ..
hence "W ∈ Rx n ∪ Ry n" ..
hence "∃W. W ∈ Rx n ∪ Ry n" ..
thus "∃n ∈ {..length xs}. ∃W. W ∈ Rx n ∪ Ry n"
using C ..
qed
qed

lemma seq_comp_refusals_finite [rule_format]:
assumes A: "xs ∈ Domain (seq_comp_failures P Q)"
shows "finite A ⟹ (∀x ∈ A. (xs, F x) ∈ seq_comp_failures P Q) ⟶
(xs, ⋃x ∈ A. F x) ∈ seq_comp_failures P Q"
proof (erule finite_induct, simp, rule_tac [2] impI)
have "∃X. (xs, X) ∈ seq_comp_failures P Q"
using A by (simp add: Domain_iff)
then obtain X where "(xs, X) ∈ seq_comp_failures P Q" ..
moreover have "{} ⊆ X" ..
ultimately show "(xs, {}) ∈ seq_comp_failures P Q"
by (rule seq_comp_prop_3)
next
fix x' A
assume B: "∀x ∈ insert x' A. (xs, F x) ∈ seq_comp_failures P Q"
hence "(xs, F x') ∈ seq_comp_failures P Q"
by simp
moreover assume "(∀x ∈ A. (xs, F x) ∈ seq_comp_failures P Q) ⟶
(xs, ⋃x ∈ A. F x) ∈ seq_comp_failures P Q"
hence "(xs, ⋃x ∈ A. F x) ∈ seq_comp_failures P Q"
using B by simp
ultimately have "(xs, F x' ∪ (⋃x ∈ A. F x)) ∈ seq_comp_failures P Q"
by (rule SCF_R4)
thus "(xs, ⋃x ∈ insert x' A. F x) ∈ seq_comp_failures P Q"
by simp
qed

lemma seq_comp_refusals_2:
assumes
A: "ref_union_closed P" and
B: "ref_union_closed Q" and
C: "xs ∈ Domain (seq_comp_failures P Q)" and
D: "X = (⋃n ∈ {..length xs}. ⋃W ∈ R n. W) ∧
(∀W ∈ R 0.
xs ∉ sentences P ∧ None ∉ set xs ∧ (xs, W) ∈ failures P ∨
xs ∈ sentences P ∧ (∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)) ∧
(∀n ∈ {0<..length xs}. ∀W ∈ R n.
take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q)"
shows "(xs, X) ∈ seq_comp_failures P Q"
proof -
have "∃Y. (xs, Y) ∈ seq_comp_failures P Q"
using C by (simp add: Domain_iff)
then obtain Y where "(xs, Y) ∈ seq_comp_failures P Q" ..
moreover have "{} ⊆ Y" ..
ultimately have E: "(xs, {}) ∈ seq_comp_failures P Q"
by (rule seq_comp_prop_3)
have "(xs, ⋃W ∈ R 0. W) ∈ seq_comp_failures P Q"
proof (cases "∃W. W ∈ R 0", cases "xs ∈ sentences P")
assume "¬ (∃W. W ∈ R 0)"
thus ?thesis
using E by simp
next
assume
F: "∃W. W ∈ R 0" and
G: "xs ∉ sentences P"
have H: "∀W ∈ R 0. None ∉ set xs ∧ (xs, W) ∈ failures P"
using D and G by simp
show ?thesis
proof (rule SCF_R1 [OF G])
have "∀xs A. (∃W. W ∈ A) ⟶ (∀W ∈ A. (xs, W) ∈ failures P) ⟶
(xs, ⋃W ∈ A. W) ∈ failures P"
using A by (simp add: ref_union_closed_def)
hence "(∃W. W ∈ R 0) ⟶ (∀W ∈ R 0. (xs, W) ∈ failures P) ⟶
(xs, ⋃W ∈ R 0. W) ∈ failures P"
by blast
thus "(xs, ⋃W ∈ R 0. W) ∈ failures P"
using F and H by simp
next
obtain W where "W ∈ R 0" using F ..
thus "None ∉ set xs"
using H by simp
qed
next
assume
F: "∃W. W ∈ R 0" and
G: "xs ∈ sentences P"
have "∀W ∈ R 0. ∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V"
using D and G by simp
hence "∃F. ∀W ∈ R 0. ∃V. (xs, F W) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None (F W) ∩ V"
by (rule bchoice)
then obtain F where "∀W ∈ R 0.
∃V. (xs, F W) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None (F W) ∩ V" ..
hence "∃G. ∀W ∈ R 0. (xs, F W) ∈ failures P ∧ ([], G W) ∈ failures Q ∧
W = insert None (F W) ∩ G W"
by (rule bchoice)
then obtain G where H: "∀W ∈ R 0.
(xs, F W) ∈ failures P ∧ ([], G W) ∈ failures Q ∧
W = insert None (F W) ∩ G W" ..
have "(xs, insert None (⋃W ∈ R 0. F W) ∩ (⋃W ∈ R 0. G W))
∈ seq_comp_failures P Q"
(is "(_, ?S) ∈ _")
proof (rule SCF_R2 [OF G])
have "∀xs A. (∃X. X ∈ A) ⟶ (∀X ∈ A. (xs, X) ∈ failures P) ⟶
(xs, ⋃X ∈ A. X) ∈ failures P"
using A by (simp add: ref_union_closed_def)
hence "(∃X. X ∈ F  R 0) ⟶ (∀X ∈ F  R 0. (xs, X) ∈ failures P) ⟶
(xs, ⋃X ∈ F  R 0. X) ∈ failures P"
(is "?A ⟶ ?B ⟶ ?C")
by (erule_tac x = xs in allE, erule_tac x = "F  R 0" in allE)
moreover obtain W where "W ∈ R 0" using F ..
hence ?A
proof (simp add: image_def, rule_tac x = "F W" in exI)
qed (rule bexI, simp)
ultimately have "?B ⟶ ?C" ..
moreover have ?B
proof (rule ballI, simp add: image_def, erule bexE)
fix W X
assume "W ∈ R 0"
hence "(xs, F W) ∈ failures P"
using H by simp
moreover assume "X = F W"
ultimately show "(xs, X) ∈ failures P"
by simp
qed
ultimately have ?C ..
thus "(xs, ⋃W ∈ R 0. F W) ∈ failures P"
by simp
next
have "∀xs A. (∃Y. Y ∈ A) ⟶ (∀Y ∈ A. (xs, Y) ∈ failures Q) ⟶
(xs, ⋃Y ∈ A. Y) ∈ failures Q"
using B by (simp add: ref_union_closed_def)
hence "(∃Y. Y ∈ G  R 0) ⟶ (∀Y ∈ G  R 0. ([], Y) ∈ failures Q) ⟶
([], ⋃Y ∈ G  R 0. Y) ∈ failures Q"
(is "?A ⟶ ?B ⟶ ?C")
by (erule_tac x = "[]" in allE, erule_tac x = "G  R 0" in allE)
moreover obtain W where "W ∈ R 0" using F ..
hence ?A
proof (simp add: image_def, rule_tac x = "G W" in exI)
qed (rule bexI, simp)
ultimately have "?B ⟶ ?C" ..
moreover have ?B
proof (rule ballI, simp add: image_def, erule bexE)
fix W Y
assume "W ∈ R 0"
hence "([], G W) ∈ failures Q"
using H by simp
moreover assume "Y = G W"
ultimately show "([], Y) ∈ failures Q"
by simp
qed
ultimately have ?C ..
thus "([], ⋃W ∈ R 0. G W) ∈ failures Q"
by simp
qed
moreover have "(⋃W ∈ R 0. W) ⊆ ?S"
proof (rule subsetI, simp, erule bexE)
fix x W
assume I: "W ∈ R 0"
hence "W = insert None (F W) ∩ G W"
using H by simp
moreover assume "x ∈ W"
ultimately have "x ∈ insert None (F W) ∩ G W"
by simp
thus "(x = None ∨ (∃W ∈ R 0. x ∈ F W)) ∧ (∃W ∈ R 0. x ∈ G W)"
(is "?A ∧ ?B")
proof (rule IntE, simp)
assume "x = None ∨ x ∈ F W"
moreover {
assume "x = None"
hence ?A ..
}
moreover {
assume "x ∈ F W"
hence "∃W ∈ R 0. x ∈ F W" using I ..
hence ?A ..
}
ultimately have ?A ..
moreover assume "x ∈ G W"
hence ?B using I ..
ultimately show ?thesis ..
qed
qed
ultimately show ?thesis
by (rule seq_comp_prop_3)
qed
moreover have "∀n ∈ {0<..length xs}.
(xs, ⋃W ∈ R n. W) ∈ seq_comp_failures P Q"
proof
fix n
assume F: "n ∈ {0<..length xs}"
hence G: "∀W ∈ R n.
take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q"
using D by simp
show "(xs, ⋃W ∈ R n. W) ∈ seq_comp_failures P Q"
proof (cases "∃W. W ∈ R n")
case False
thus ?thesis
using E by simp
next
case True
have "(take (length xs - n) xs @ drop (length xs - n) xs, ⋃W ∈ R n. W)
∈ seq_comp_failures P Q"
proof (rule SCF_R3)
obtain W where "W ∈ R n" using True ..
thus "take (length xs - n) xs ∈ sentences P"
using G by simp
next
have "∀xs A. (∃W. W ∈ A) ⟶ (∀W ∈ A. (xs, W) ∈ failures Q) ⟶
(xs, ⋃W ∈ A. W) ∈ failures Q"
using B by (simp add: ref_union_closed_def)
hence "(∃W. W ∈ R n) ⟶
(∀W ∈ R n. (drop (length xs - n) xs, W) ∈ failures Q) ⟶
(drop (length xs - n) xs, ⋃W ∈ R n. W) ∈ failures Q"
by blast
thus "(drop (length xs - n) xs, ⋃W ∈ R n. W) ∈ failures Q"
using G and True by simp
next
show "drop (length xs - n) xs ≠ []"
using F by (simp, arith)
qed
thus ?thesis
by simp
qed
qed
ultimately have F: "∀n ∈ {..length xs}.
(xs, ⋃W ∈ R n. W) ∈ seq_comp_failures P Q"
by auto
have "(xs, ⋃n ∈ {..length xs}. ⋃W ∈ R n. W) ∈ seq_comp_failures P Q"
proof (rule seq_comp_refusals_finite [OF C], simp)
fix n
assume "n ∈ {..length xs}"
with F show "(xs, ⋃W ∈ R n. W) ∈ seq_comp_failures P Q" ..
qed
moreover have "X = (⋃n ∈ {..length xs}. ⋃W ∈ R n. W)"
using D by simp
ultimately show ?thesis
by simp
qed

text ‹
\null

In what follows, the previous results are used to prove that refusals union closure, weak
sequentiality, and sequentiality are conserved under sequential composition. The proof of the first
of these lemmas makes use of the axiom of choice.

Since the target security conservation theorem, in addition to the security of both of the processes
to be composed, also requires to assume that the first process be refusals union closed and
sequential (cf. below), these further conservation lemmas will permit to generalize the theorem to
the sequential composition of an arbitrary list of processes.

\null
›

lemma seq_comp_ref_union_closed:
assumes
WS: "weakly_sequential P" and
A: "ref_union_closed P" and
B: "ref_union_closed Q"
shows "ref_union_closed (P ; Q)"
proof (simp only: ref_union_closed_def seq_comp_failures [OF WS],
(rule allI)+, (rule impI)+, erule exE)
fix xs A X'
assume
C: "∀X ∈ A. (xs, X) ∈ seq_comp_failures P Q" and
D: "X' ∈ A"
have "∀X ∈ A. ∃R.
X = (⋃n ∈ {..length xs}. ⋃W ∈ R n. W) ∧
(∀W ∈ R 0.
xs ∉ sentences P ∧ None ∉ set xs ∧ (xs, W) ∈ failures P ∨
xs ∈ sentences P ∧ (∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)) ∧
(∀n ∈ {0<..length xs}. ∀W ∈ R n.
take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q)"
(is "∀X ∈ A. ∃R. ?T R X")
proof
fix X
assume "X ∈ A"
with C have "(xs, X) ∈ seq_comp_failures P Q" ..
hence "∃R. X = (⋃n ∈ {..length xs}. ⋃W ∈ R n. W) ∧
(∀W ∈ R 0.
xs ∉ sentences P ∧ None ∉ set xs ∧ (xs, W) ∈ failures P ∨
xs ∈ sentences P ∧ (∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)) ∧
(∀n ∈ {0<..length xs}. ∀W ∈ R n.
take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q) ∧
(∃n ∈ {..length xs}. ∃W. W ∈ R n)"
by (rule seq_comp_refusals_1)
thus "∃R. ?T R X"
by blast
qed
hence "∃R. ∀X ∈ A. ?T (R X) X"
by (rule bchoice)
then obtain R where E: "∀X ∈ A. ?T (R X) X" ..
have "xs ∈ Domain (seq_comp_failures P Q)"
have "(xs, X') ∈ seq_comp_failures P Q"
using C and D ..
thus "∃X. (xs, X) ∈ seq_comp_failures P Q" ..
qed
moreover have "?T (λn. ⋃X ∈ A. R X n) (⋃X ∈ A. X)"
proof (rule conjI, rule_tac [2] conjI)
show "(⋃X ∈ A. X) = (⋃n ∈ {..length xs}. ⋃W ∈ ⋃X ∈ A. R X n. W)"
proof (rule equalityI, rule_tac [!] subsetI, simp_all,
erule bexE, (erule_tac [2] bexE)+)
fix x X
assume F: "X ∈ A"
hence "X = (⋃n ∈ {..length xs}. ⋃W ∈ R X n. W)"
using E by simp
moreover assume "x ∈ X"
ultimately have "x ∈ (⋃n ∈ {..length xs}. ⋃W ∈ R X n. W)"
by simp
hence "∃n ∈ {..length xs}. ∃W ∈ R X n. x ∈ W"
by simp
hence "∃X ∈ A. ∃n ∈ {..length xs}. ∃W ∈ R X n. x ∈ W"
using F ..
thus "∃n ∈ {..length xs}. ∃X ∈ A. ∃W ∈ R X n. x ∈ W"
by blast
next
fix x n X W
assume F: "X ∈ A"
hence G: "X = (⋃n ∈ {..length xs}. ⋃W ∈ R X n. W)"
using E by simp
assume "x ∈ W" and "W ∈ R X n"
hence "∃W ∈ R X n. x ∈ W" ..
moreover assume "n ∈ {..length xs}"
ultimately have "∃n ∈ {..length xs}. ∃W ∈ R X n. x ∈ W" ..
hence "x ∈ (⋃n ∈ {..length xs}. ⋃W ∈ R X n. W)"
by simp
hence "x ∈ X"
by (subst G)
thus "∃X ∈ A. x ∈ X"
using F ..
qed
next
show "∀W ∈ ⋃X ∈ A. R X 0.
xs ∉ sentences P ∧ None ∉ set xs ∧ (xs, W) ∈ failures P ∨
xs ∈ sentences P ∧ (∃U V. (xs, U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)"
(is "∀W ∈ _. ?T W")
proof (rule ballI, simp only: UN_iff, erule bexE)
fix W X
assume "X ∈ A"
hence "∀W ∈ R X 0. ?T W"
using E by simp
moreover assume "W ∈ R X 0"
ultimately show "?T W" ..
qed
next
show "∀n ∈ {0<..length xs}. ∀W ∈ ⋃X ∈ A. R X n.
take (length xs - n) xs ∈ sentences P ∧
(drop (length xs - n) xs, W) ∈ failures Q"
(is "∀n ∈ _. ∀W ∈ _. ?T n W")
proof ((rule ballI)+, simp only: UN_iff, erule bexE)
fix n W X
assume "X ∈ A"
hence "∀n ∈ {0<..length xs}. ∀W ∈ R X n. ?T n W"
using E by simp
moreover assume "n ∈ {0<..length xs}"
ultimately have "∀W ∈ R X n. ?T n W" ..
moreover assume "W ∈ R X n"
ultimately show "?T n W" ..
qed
qed
ultimately show "(xs, ⋃X ∈ A. X) ∈ seq_comp_failures P Q"
by (rule seq_comp_refusals_2 [OF A B])
qed

lemma seq_comp_weakly_sequential:
assumes
A: "weakly_sequential P" and
B: "weakly_sequential Q"
shows "weakly_sequential (P ; Q)"
proof (subst weakly_sequential_def, rule ballI, drule traces_failures,
subst (asm) seq_comp_failures [OF A], erule seq_comp_failures.induct, simp_all)
fix xs :: "'a option list"
assume C: "None ∉ set xs"
show "None ∉ set (butlast xs)"
proof
assume "None ∈ set (butlast xs)"
hence "None ∈ set xs"
by (rule in_set_butlastD)
thus False
qed
next
fix xs
assume "xs ∈ sentences P"
with A have C: "None ∉ set xs"
by (rule weakly_seq_sentences_none)
show "None ∉ set (butlast xs)"
proof
assume "None ∈ set (butlast xs)"
hence "None ∈ set xs"
by (rule in_set_butlastD)
thus False
qed
next
fix xs ys Y
assume "xs ∈ sentences P"
with A have C: "None ∉ set xs"
by (rule weakly_seq_sentences_none)
have "∀xs ∈ traces Q. None ∉ set (butlast xs)"
using B by (simp add: weakly_sequential_def)
moreover assume "(ys, Y) ∈ failures Q"
hence "ys ∈ traces Q"
by (rule failures_traces)
ultimately have "None ∉ set (butlast ys)" ..
hence "None ∉ set (xs @ butlast ys)"
using C by simp
moreover assume "ys ≠ []"
hence "butlast (xs @ ys) = xs @ butlast ys"
ultimately show "None ∉ set (butlast (xs @ ys))"
by simp
qed

lemma seq_comp_sequential:
assumes
A: "sequential P" and
B: "sequential Q"
shows "sequential (P ; Q)"
proof (subst sequential_def, rule conjI)
have "weakly_sequential P"
using A by (rule seq_implies_weakly_seq)
moreover have "weakly_sequential Q"
using B by (rule seq_implies_weakly_seq)
ultimately have "weakly_sequential (P ; Q)"
by (rule seq_comp_weakly_sequential)
thus "∀xs ∈ traces (P ; Q). None ∉ set (butlast xs)"
next
have C: "weakly_sequential P"
using A by (rule seq_implies_weakly_seq)
show "∀xs ∈ sentences (P ; Q). next_events (P ; Q) xs = {None}"
proof (rule ballI, simp add: sentences_def next_events_def, rule equalityI,
rule_tac [!] subsetI, simp_all, (drule traces_failures)+,
fix xs x
assume
D: "(xs @ [None], {}) ∈ seq_comp_failures P Q" and
E: "(xs @ [x], {}) ∈ seq_comp_failures P Q"
have "∃R. {} = (⋃n ∈ {..length (xs @ [None])}. ⋃W ∈ R n. W) ∧
(∀W ∈ R 0.
xs @ [None] ∉ sentences P ∧
None ∉ set (xs @ [None]) ∧ (xs @ [None], W) ∈ failures P ∨
xs @ [None] ∈ sentences P ∧
(∃U V. (xs @ [None], U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)) ∧
(∀n ∈ {0<..length (xs @ [None])}. ∀W ∈ R n.
take (length (xs @ [None]) - n) (xs @ [None]) ∈ sentences P ∧
(drop (length (xs @ [None]) - n) (xs @ [None]), W) ∈ failures Q) ∧
(∃n ∈ {..length (xs @ [None])}. ∃W. W ∈ R n)"
(is "∃R. ?T R")
using D by (rule seq_comp_refusals_1)
then obtain R where F: "?T R" ..
hence "∃n ∈ {..Suc (length xs)}. ∃W. W ∈ R n"
by simp
moreover have "R 0 = {}"
proof (rule equals0I)
fix W
assume "W ∈ R 0"
hence "xs @ [None] ∈ sentences P"
using F by simp
with C have "None ∉ set (xs @ [None])"
by (rule weakly_seq_sentences_none)
thus False
by simp
qed
ultimately have "∃n ∈ {0<..Suc (length xs)}. ∃W. W ∈ R n"
proof -
assume "∃n ∈ {..Suc (length xs)}. ∃W. W ∈ R n"
then obtain n where G: "n ∈ {..Suc (length xs)}" and H: "∃W. W ∈ R n" ..
assume I: "R 0 = {}"
show "∃n ∈ {0<..Suc (length xs)}. ∃W. W ∈ R n"
proof (cases n)
case 0
hence "∃W. W ∈ R 0"
using H by simp
then obtain W where "W ∈ R 0" ..
moreover have "W ∉ R 0"
using I by (rule equals0D)
ultimately show ?thesis
next
case (Suc m)
hence "n ∈ {0<..Suc (length xs)}"
using G by simp
with H show ?thesis ..
qed
qed
then obtain n and W where G: "n ∈ {0<..Suc (length xs)}" and "W ∈ R n"
by blast
hence
"take (Suc (length xs) - n) (xs @ [None]) ∈ sentences P ∧
(drop (Suc (length xs) - n) (xs @ [None]), W) ∈ failures Q"
using F by simp
moreover have H: "Suc (length xs) - n ≤ length xs"
using G by (simp, arith)
ultimately have I:
"take (Suc (length xs) - n) xs ∈ sentences P ∧
(drop (Suc (length xs) - n) xs @ [None], W) ∈ failures Q"
by simp
have "∃R. {} = (⋃n ∈ {..length (xs @ [x])}. ⋃W ∈ R n. W) ∧
(∀W ∈ R 0.
xs @ [x] ∉ sentences P ∧
None ∉ set (xs @ [x]) ∧ (xs @ [x], W) ∈ failures P ∨
xs @ [x] ∈ sentences P ∧
(∃U V. (xs @ [x], U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W = insert None U ∩ V)) ∧
(∀n ∈ {0<..length (xs @ [x])}. ∀W ∈ R n.
take (length (xs @ [x]) - n) (xs @ [x]) ∈ sentences P ∧
(drop (length (xs @ [x]) - n) (xs @ [x]), W) ∈ failures Q) ∧
(∃n ∈ {..length (xs @ [x])}. ∃W. W ∈ R n)"
(is "∃R. ?T R")
using E by (rule seq_comp_refusals_1)
then obtain R' where J: "?T R'" ..
hence "∃n ∈ {..Suc (length xs)}. ∃W. W ∈ R' n"
by simp
then obtain n' where K: "n' ∈ {..Suc (length xs)}" and L: "∃W. W ∈ R' n'" ..
have "n' = 0 ∨ n' ∈ {0<..Suc (length xs)}"
using K by auto
thus "x = None"
proof
assume "n' = 0"
hence "∃W. W ∈ R' 0"
using L by simp
then obtain W' where "W' ∈ R' 0" ..
hence
"xs @ [x] ∉ sentences P ∧
None ∉ set (xs @ [x]) ∧ (xs @ [x], W') ∈ failures P ∨
xs @ [x] ∈ sentences P ∧
(∃U V. (xs @ [x], U) ∈ failures P ∧ ([], V) ∈ failures Q ∧
W' = insert None U ∩ V)"
using J by simp
hence M: "xs @ [x] ∈ traces P ∧ None ∉ set (xs @ [x])"
proof (cases "xs @ [x] ∈ sentences P", simp_all, (erule_tac [2] conjE)+,
simp_all)
case False
assume "(xs @ [x], W') ∈ failures P"
thus "xs @ [x] ∈ traces P"
by (rule failures_traces)
next
case True
hence "(xs @ [x]) @ [None] ∈ traces P"
hence "xs @ [x] ∈ traces P"
by (rule process_rule_2_traces)
moreover have "None ∉ set (xs @ [x])"
using C and True by (rule weakly_seq_sentences_none)
ultimately show "xs @ [x] ∈ traces P ∧ None ≠ x ∧ None ∉ set xs"
by simp
qed
have "xs @ [x] = take (Suc (length xs) - n) (xs @ [x]) @
drop (Suc (length xs) - n) (xs @ [x])"
by (simp only: append_take_drop_id)
hence "xs @ [x] = take (Suc (length xs) - n) xs @
drop (Suc (length xs) - n) xs @ [x]"
using H by simp
moreover have "∃y ys. drop (Suc (length xs) - n) xs @ [x] = y # ys"
by (cases "drop (Suc (length xs) - n) xs @ [x]", simp_all)
then obtain y and ys where "drop (Suc (length xs) - n) xs @ [x] = y # ys"
by blast
ultimately have N: "xs @ [x] = take (Suc (length xs) - n) xs @ y # ys"
by simp
have "take (Suc (length xs) - n) xs ∈ sentences P"
using I ..
moreover have "take (Suc (length xs) - n) xs @ y # ys ∈ traces P"
using M and N by simp
ultimately have "y = None"
by (rule seq_sentences_none [OF A])
moreover have "y ≠ None"
using M and N by (rule_tac not_sym, simp)
ultimately show ?thesis
next
assume M: "n' ∈ {0<..Suc (length xs)}"
moreover obtain W' where "W' ∈ R' n'"
using L ..
ultimately have
"take (Suc (length xs) - n') (xs @ [x]) ∈ sentences P ∧
(drop (Suc (length xs) - n') (xs @ [x]), W') ∈ failures Q"
using J by simp
moreover have N: "Suc (length xs) - n' ≤ length xs"
using M by (simp, arith)
ultimately have O:
"take (Suc (length xs) - n') xs ∈ sentences P ∧
(drop (Suc (length xs) - n') xs @ [x], W') ∈ failures Q"
by simp
moreover have "n = n'"
proof (rule ccontr, simp add: neq_iff, erule disjE)
assume P: "n < n'"
have "take (Suc (length xs) - n) xs =
take (Suc (length xs) - n') (take (Suc (length xs) - n) xs) @
drop (Suc (length xs) - n') (take (Suc (length xs) - n) xs)"
by (simp only: append_take_drop_id)
also have "… =
take (Suc (length xs) - n') xs @
drop (Suc (length xs) - n') (take (Suc (length xs) - n) xs)"
using P by (simp add: min_def)
also have "… =
take (Suc (length xs) - n') xs @
take (n' - n) (drop (Suc (length xs) - n') xs)"
using M by (subst drop_take, simp)
finally have "take (Suc (length xs) - n) xs =
take (Suc (length xs) - n') xs @
take (n' - n) (drop (Suc (length xs) - n') xs)" .
moreover have "take (n' - n) (drop (Suc (length xs) - n') xs) ≠ []"
proof (rule_tac notI, simp, erule disjE)
assume "n' ≤ n"
thus False
using P by simp
next
assume "length xs ≤ Suc (length xs) - n'"
moreover have "Suc (length xs) - n' < Suc (length xs) - n"
using M and P by simp
hence "Suc (length xs) - n' < length xs"
using H by simp
ultimately show False
by simp
qed
hence "∃y ys. take (n' - n) (drop (Suc (length xs) - n') xs) = y # ys"
by (cases "take (n' - n) (drop (Suc (length xs) - n') xs)", simp_all)
then obtain y and ys where
"take (n' - n) (drop (Suc (length xs) - n') xs) = y # ys"
by blast
ultimately have Q: "take (Suc (length xs) - n) xs =
take (Suc (length xs) - n') xs @ y # ys"
by simp
have "take (Suc (length xs) - n') xs ∈ sentences P"
using O ..
moreover have R: "take (Suc (length xs) - n) xs ∈ sentences P"
using I ..
hence "take (Suc (length xs) - n) xs @ [None] ∈ traces P"
hence "take (Suc (length xs) - n) xs ∈ traces P"
by (rule process_rule_2_traces)
hence "take (Suc (length xs) - n') xs @ y # ys ∈ traces P"
using Q by simp
ultimately have "y = None"
by (rule seq_sentences_none [OF A])
moreover have "None ∉ set (take (Suc (length xs) - n) xs)"
using C and R by (rule weakly_seq_sentences_none)
hence "y ≠ None"
using Q by (rule_tac not_sym, simp)
ultimately show False
next
assume P: "n' < n"
have "take (Suc (length xs) - n') xs =
take (Suc (length xs) - n) (take (Suc (length xs) - n') xs) @
drop (Suc (length xs) - n) (take (Suc (length xs) - n') xs)"
by (simp only: append_take_drop_id)
also have "… =
take (Suc (length xs) - n) xs @
drop (Suc (length xs) - n) (take (Suc (length xs) - n') xs)"
using P by (simp add: min_def)
also have "… =
take (Suc (length xs) - n) xs @
take (n - n') (drop (Suc (length xs) - n) xs)"
using G by (subst drop_take, simp)
finally have "take (Suc (length xs) - n') xs =
take (Suc (length xs) - n) xs @
take (n - n') (drop (Suc (length xs) - n) xs)" .
moreover have "take (n - n') (drop (Suc (length xs) - n) xs) ≠ []"
proof (rule_tac notI, simp, erule disjE)
assume "n ≤ n'"
thus False
using P by simp
next
assume "length xs ≤ Suc (length xs) - n"
moreover have "Suc (length xs) - n < Suc (length xs) - n'"
using G and P by simp
hence "Suc (length xs) - n < length xs"
using N by simp
ultimately show False
by simp
qed
hence "∃y ys. take (n - n') (drop (Suc (length xs) - n) xs) = y # ys"
by (cases "take (n - n') (drop (Suc (length xs) - n) xs)", simp_all)
then obtain y and ys where
"take (n - n') (drop (Suc (length xs) - n) xs) = y # ys"
by blast
ultimately have Q: "take (Suc (length xs) - n') xs =
take (Suc (length xs) - n) xs @ y # ys"
by simp
have "take (Suc (length xs) - n) xs ∈ sentences P"
using I ..
moreover have R: "take (Suc (length xs) - n') xs ∈ sentences P"
using O ..
hence "take (Suc (length xs) - n') xs @ [None] ∈ traces P"
hence "take (Suc (length xs) - n') xs ∈ traces P"
by (rule process_rule_2_traces)
hence "take (Suc (length xs) - n) xs @ y # ys ∈ traces P"
using Q by simp
ultimately have "y = None"
by (rule seq_sentences_none [OF A])
moreover have "None ∉ set (take (Suc (length xs) - n') xs)"
using C and R by (rule weakly_seq_sentences_none)
hence "y ≠ None"
using Q by (rule_tac not_sym, simp)
ultimately show False
by (