Theory Correctness_Theorem
section "Sufficiency of well-typedness for information flow correctness: main theorem"
theory Correctness_Theorem
imports Correctness_Lemmas
begin
text ‹
\null
The purpose of this section is to prove that type system @{const [names_short] noninterf.ctyping2}
is correct in that it guarantees that well-typed programs satisfy the information flow correctness
criterion expressed by predicate @{const [names_short] noninterf.correct}, namely that if the type
system outputs a value other than @{const None} (that is, a \emph{pass} verdict) when it is input
program @{term c}, @{typ "state set"} @{term A}, and @{typ "vname set"} @{term X}, then
@{prop "correct c A X"} (theorem @{text ctyping2_correct}).
This proof makes use of the lemma @{text ctyping2_approx} proven in a previous section.
›
subsection "Local context proofs"
context noninterf
begin
lemma ctyping2_correct_aux_skip [elim!]:
"⟦(SKIP, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1);
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)⟧ ⟹
ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
by (fastforce dest: small_stepsl_skip)
lemma ctyping2_correct_aux_assign:
assumes
A: "(U, v) ⊨ x ::= a (⊆ A, X) = Some (C, Y)" and
B: "s ∈ Univ A (⊆ state ∩ X)" and
C: "(x ::= a, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)" and
D: "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
from A have E: "∀(B, Y) ∈ insert (Univ? A X, avars a) U. B: Y ↝ {x}"
by (simp split: if_split_asm)
have
"(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (x ::= a, s, f, vs⇩0, ws⇩0) ∨
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (SKIP, s(x := aval a s), f, vs⇩0, ws⇩0)"
(is "?P ∨ ?Q")
using C by (blast dest: small_stepsl_assign)
thus ?thesis
proof
assume ?P
hence "(x ::= a, s, f, vs⇩0, ws⇩0) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
using D by simp
hence
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (x ::= a, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [] ∨
(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s(x := aval a s), f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [x ::= a]"
(is "?P' ∨ _")
by (rule small_stepsl_assign)
thus ?thesis
proof (rule disjE, erule_tac [2] conjE)
assume ?P'
with `?P` show ?thesis
by fastforce
next
assume
F: "(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s(x := aval a s), f, vs⇩0, ws⇩0)" and
G: "flow cfs⇩2 = [x ::= a]"
(is "?cs = _")
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
let ?t⇩2 = "t⇩1(x := aval a t⇩1)"
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ SKIP], rule exI [of _ ?t⇩2],
rule exI [of _ vs⇩1'], rule exI [of _ ws⇩1'])
{
fix S
assume "S ⊆ {y. s = t⇩1 (⊆ sources [x ::= a] vs⇩0 s f y)}" and
"x ∈ S"
hence "s = t⇩1 (⊆ avars a)"
using B by (rule eq_states_assign, insert E, simp)
hence "aval a s = aval a t⇩1"
by (rule avars_aval)
}
moreover {
fix S y
assume "S ⊆ {y. s = t⇩1 (⊆ sources [x ::= a] vs⇩0 s f y)}" and
"y ∈ S"
hence "s = t⇩1 (⊆ sources [x ::= a] vs⇩0 s f y)"
by blast
moreover assume "y ≠ x"
ultimately have "s y = t⇩1 y"
by (subst (asm) append_Nil [symmetric],
simp only: sources.simps, simp)
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 SKIP s⇩1 t⇩1 ?t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩1' ws⇩1' ws⇩1' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 ?t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩1' ?cs"
using F and G and `?P` by auto
qed
qed (insert E G, fastforce)
qed
next
assume ?Q
moreover from this have
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s⇩1, f, vs⇩1, ws⇩1) ∧ flow cfs⇩2 = []"
using D by (blast intro!: small_stepsl_skip)
ultimately show ?thesis
by fastforce
qed
qed
lemma ctyping2_correct_aux_input:
assumes
A: "(U, v) ⊨ IN x (⊆ A, X) = Some (C, Y)" and
B: "(IN x, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)" and
C: "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
from A have D: "∀(B, Y) ∈ U. B: Y ↝ {x}"
by (simp split: if_split_asm)
let ?n = "length [p←vs⇩0. fst p = x]"
have
"(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (IN x, s, f, vs⇩0, ws⇩0) ∨
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) =
(SKIP, s(x := f x ?n), f, vs⇩0 @ [(x, f x ?n)], ws⇩0)"
(is "?P ∨ ?Q")
using B by (auto dest: small_stepsl_input simp: Let_def)
thus ?thesis
proof
assume ?P
hence "(IN x, s, f, vs⇩0, ws⇩0) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
using C by simp
hence
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (IN x, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [] ∨
(c⇩2, s⇩2, f, vs⇩2, ws⇩2) =
(SKIP, s(x := f x ?n), f, vs⇩0 @ [(x, f x ?n)], ws⇩0) ∧
flow cfs⇩2 = [IN x]"
(is "?P' ∨ _")
by (auto dest: small_stepsl_input simp: Let_def)
thus ?thesis
proof (rule disjE, erule_tac [2] conjE)
assume ?P'
with `?P` show ?thesis
by fastforce
next
assume
E: "(c⇩2, s⇩2, f, vs⇩2, ws⇩2) =
(SKIP, s(x := f x ?n), f, vs⇩0 @ [(x, f x ?n)], ws⇩0)" and
F: "flow cfs⇩2 = [IN x]"
(is "?cs = _")
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
let ?n' = "length [p←vs⇩1' :: inputs. fst p = x]"
let ?t⇩2 = "t⇩1(x := f' x ?n') :: state" and
?vs⇩2' = "vs⇩1' @ [(x, f' x ?n')]"
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ SKIP], rule exI [of _ ?t⇩2],
rule exI [of _ ?vs⇩2'], rule exI [of _ ws⇩1'])
{
fix S
assume "f = f' (⊆ vs⇩0, vs⇩1',
⋃ {tags [IN x] vs⇩0 s f y | y. y ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
moreover assume "x ∈ S"
hence "tags [IN x] vs⇩0 s f x ⊆ ?T"
by blast
ultimately have "f = f' (⊆ vs⇩0, vs⇩1', tags [IN x] vs⇩0 s f x)"
by (rule eq_streams_subset)
moreover have "tags [IN x] vs⇩0 s f x = {(x, 0)}"
by (subst append_Nil [symmetric],
simp only: tags.simps, simp)
ultimately have "f x (length [p←vs⇩0. fst p = x]) =
f' x (length [p←vs⇩1'. fst p = x])"
by (simp add: eq_streams_def)
}
moreover
{
fix S y
assume "S ⊆ {y. s = t⇩1 (⊆ sources [IN x] vs⇩0 s f y)}" and
"y ∈ S"
hence "s = t⇩1 (⊆ sources [IN x] vs⇩0 s f y)"
by blast
moreover assume "y ≠ x"
ultimately have "s y = t⇩1 y"
by (subst (asm) append_Nil [symmetric],
simp only: sources.simps, simp)
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 SKIP s⇩1 t⇩1 ?t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 ?vs⇩2' ws⇩1' ws⇩1' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 ?t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩1' ?cs"
using E and F and `?P` by auto
qed
qed (insert D F, fastforce)
qed
next
assume ?Q
moreover from this have
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s⇩1, f, vs⇩1, ws⇩1) ∧ flow cfs⇩2 = []"
using C by (blast intro!: small_stepsl_skip)
ultimately show ?thesis
by fastforce
qed
qed
lemma ctyping2_correct_aux_output:
assumes
A: "(U, v) ⊨ OUT x (⊆ A, X) = Some (B, Y)" and
B: "(OUT x, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)" and
C: "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
from A have D: "∀(B, Y) ∈ U. B: Y ↝ {x}"
by (simp split: if_split_asm)
have
"(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (OUT x, s, f, vs⇩0, ws⇩0) ∨
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (SKIP, s, f, vs⇩0, ws⇩0 @ [(x, s x)])"
(is "?P ∨ ?Q")
using B by (blast dest: small_stepsl_output)
thus ?thesis
proof
assume ?P
hence "(OUT x, s, f, vs⇩0, ws⇩0) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
using C by simp
hence
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (OUT x, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [] ∨
(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s, f, vs⇩0, ws⇩0 @ [(x, s x)]) ∧
flow cfs⇩2 = [OUT x]"
(is "?P' ∨ _")
by (rule small_stepsl_output)
thus ?thesis
proof (rule disjE, erule_tac [2] conjE)
assume ?P'
with `?P` show ?thesis
by fastforce
next
assume
E: "(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s, f, vs⇩0, ws⇩0 @ [(x, s x)])" and
F: "flow cfs⇩2 = [OUT x]"
(is "?cs = _")
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
let ?ws⇩2' = "ws⇩1' @ [(x, t⇩1 x)] :: outputs"
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ SKIP], rule exI [of _ t⇩1],
rule exI [of _ vs⇩1'], rule exI [of _ ?ws⇩2'])
{
fix S y
assume "S ⊆ {y. s = t⇩1 (⊆ sources [OUT x] vs⇩0 s f y)}" and
"y ∈ S"
hence "s = t⇩1 (⊆ sources [OUT x] vs⇩0 s f y)"
by blast
hence "s y = t⇩1 y"
by (subst (asm) append_Nil [symmetric],
simp only: sources.simps, simp)
}
moreover {
fix S
assume "S ⊆ {y. s = t⇩1 (⊆ sources_out [OUT x] vs⇩0 s f y)}" and
"x ∈ S"
hence "s = t⇩1 (⊆ sources_out [OUT x] vs⇩0 s f x)"
by blast
hence "s x = t⇩1 x"
by (subst (asm) append_Nil [symmetric],
simp only: sources_out.simps, simp)
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 SKIP s⇩1 t⇩1 t⇩1 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩1' ws⇩1' ?ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩1 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ?ws⇩2' ?cs"
using E and F and `?P` by auto
qed
qed (insert D F, fastforce)
qed
next
assume ?Q
moreover from this have
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s⇩1, f, vs⇩1, ws⇩1) ∧ flow cfs⇩2 = []"
using C by (blast intro!: small_stepsl_skip)
ultimately show ?thesis
by fastforce
qed
qed
lemma ctyping2_correct_aux_seq:
assumes
A: "(U, v) ⊨ c⇩1;; c⇩2 (⊆ A, X) = Some (C, Z)" and
B: "⋀B Y c' c'' s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(U, v) ⊨ c⇩1 (⊆ A, X) = Some (B, Y) ⟹
s ∈ Univ A (⊆ state ∩ X) ⟹
(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ⟹
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
C: "⋀p B Y C Z c' c'' s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(U, v) ⊨ c⇩1 (⊆ A, X) = Some p ⟹ (B, Y) = p ⟹
(U, v) ⊨ c⇩2 (⊆ B, Y) = Some (C, Z) ⟹
s ∈ Univ B (⊆ state ∩ Y) ⟹
(c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ⟹
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
D: "s ∈ Univ A (⊆ state ∩ X)" and
E: "(c⇩1;; c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1)" and
F: "(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
from A obtain B and Y where
G: "(U, v) ⊨ c⇩1 (⊆ A, X) = Some (B, Y)" and
H: "(U, v) ⊨ c⇩2 (⊆ B, Y) = Some (C, Z)"
by (auto split: option.split_asm)
have
"(∃c cfs. c' = c;; c⇩2 ∧
(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs} (c, s⇩1, f, vs⇩1, ws⇩1)) ∨
(∃s' p cfs cfs'.
(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs} (SKIP, s', p) ∧
(c⇩2, s', p) →*{cfs'} (c', s⇩1, f, vs⇩1, ws⇩1))"
using E by (fastforce dest: small_stepsl_seq)
thus ?thesis
proof (rule disjE, (erule_tac exE)+, (erule_tac [2] exE)+,
erule_tac [!] conjE)
fix c⇩1' cfs
assume
I: "c' = c⇩1';; c⇩2" and
J: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs} (c⇩1', s⇩1, f, vs⇩1, ws⇩1)"
hence "(c⇩1';; c⇩2, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)"
using F by simp
hence
"(∃d cfs'. c'' = d;; c⇩2 ∧
(c⇩1', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (d, s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = flow cfs') ∨
(∃p cfs' cfs''.
(c⇩1', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, p) ∧
(c⇩2, p) →*{cfs''} (c'', s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = flow cfs' @ flow cfs'')"
by (blast dest: small_stepsl_seq)
thus ?thesis
proof (rule disjE, (erule_tac exE)+, (erule_tac [2] exE)+,
(erule_tac [!] conjE)+)
fix c⇩1'' cfs'
assume
K: "c'' = c⇩1'';; c⇩2" and
L: "(c⇩1', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (c⇩1'', s⇩2, f, vs⇩2, ws⇩2)" and
M: "flow cfs⇩2 = flow cfs'"
(is "?cs = ?cs'")
have N: "ok_flow_aux U c⇩1' c⇩1'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 ?cs'"
using B [OF G D J L] .
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩1' c⇩1'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
(is "?P1 ∧ ?P2 ∧ ?P3")
using M and N by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ "c⇩2';; c⇩2"], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume "S ≠ {}" and
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_aux ?cs vs⇩1 s⇩1 f x | x. x ∈ S})"
hence
"(c', t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2';; c⇩2, t⇩2, f', vs⇩2', ws⇩2') ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
using I and `?P1` by (blast intro: star_seq2)
}
thus
"ok_flow_aux_1 c' c'' (c⇩2';; c⇩2) s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using K and `?P2` and `?P3` by simp
qed
qed (simp add: M N)
next
fix p cfs' cfs''
assume "(c⇩1', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, p)"
moreover from this obtain s⇩1' and vs and ws where
K: "p = (s⇩1', f, vs, ws)"
by (blast dest: small_stepsl_stream)
ultimately have
L: "(c⇩1', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, s⇩1', f, vs, ws)"
by simp
assume "(c⇩2, p) →*{cfs''} (c'', s⇩2, f, vs⇩2, ws⇩2)"
with K have
M: "(c⇩2, s⇩1', f, vs, ws) →*{cfs''} (c'', s⇩2, f, vs⇩2, ws⇩2)"
by simp
assume N: "flow cfs⇩2 = flow cfs' @ flow cfs''"
(is "(?cs :: flow) = ?cs' @ ?cs''")
have O: "ok_flow_aux U c⇩1' SKIP s⇩1 s⇩1' f vs⇩1 vs ws⇩1 ws ?cs'"
using B [OF G D J L] .
have "(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs @ cfs'} (SKIP, s⇩1', f, vs, ws)"
using J and L by (simp add: small_stepsl_append)
hence "(c⇩1, s, f, vs⇩0, ws⇩0) ⇒ (s⇩1', f, vs, ws)"
by (auto dest: small_stepsl_steps simp: big_iff_small)
hence P: "s⇩1' ∈ Univ B (⊆ state ∩ Y)"
using G and D by (rule ctyping2_approx)
have Q: "ok_flow_aux U c⇩2 c'' s⇩1' s⇩2 f vs vs⇩2 ws ws⇩2 ?cs''"
using C [OF G _ H P _ M, of vs ws "[]"] by simp
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩1'' and t⇩1' and vs⇩1'' and ws⇩1'' where
"ok_flow_aux_1 c⇩1' SKIP c⇩1'' s⇩1 t⇩1 t⇩1' f f'
vs⇩1 vs⇩1' vs vs⇩1'' ws⇩1' ws⇩1'' ?cs' ∧
ok_flow_aux_2 s⇩1 s⇩1' t⇩1 t⇩1' f f' vs⇩1 vs⇩1' ?cs' ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws ws⇩1'' ?cs'"
(is "_ ∧ ?P2 ∧ ?P3")
using O by fastforce
hence
"ok_flow_aux_1 c⇩1' SKIP SKIP s⇩1 t⇩1 t⇩1' f f'
vs⇩1 vs⇩1' vs vs⇩1'' ws⇩1' ws⇩1'' ?cs'"
(is ?P1) and ?P2 and ?P3 by auto
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩2 c'' c⇩2' s⇩1' t⇩1' t⇩2 f f'
vs vs⇩1'' vs⇩2 vs⇩2' ws⇩1'' ws⇩2' ?cs'' ∧
ok_flow_aux_2 s⇩1' s⇩2 t⇩1' t⇩2 f f' vs vs⇩1'' ?cs'' ∧
ok_flow_aux_3 s⇩1' t⇩1' f f' vs vs⇩1'' ws ws⇩1'' ws⇩2 ws⇩2' ?cs''"
(is "?P1' ∧ ?P2' ∧ ?P3'")
using Q by fastforce
hence ?P1' and ?P2' and ?P3' by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ c⇩2'], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
R: "S ≠ {}" and
S: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x)}" and
T: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have "∀x. sources_aux ?cs' vs⇩1 s⇩1 f x ⊆
sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}"
using S by blast
moreover have "⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
with T have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have
"(c⇩1', t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩1', f', vs⇩1'', ws⇩1'') ∧
map fst [p←drop (length vs⇩1) vs. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩1''. fst p ∈ S]"
(is "?Q1 ∧ ?Q2")
using R and `?P1` by simp
hence ?Q1 and ?Q2 by auto
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_aux ?cs'' vs s⇩1' f x)}"
by (rule sources_aux_rhs [OF S T L `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_aux ?cs'' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_aux_rhs [OF S T L `?Q1` `?P1`])
ultimately have
"(c⇩2, t⇩1', f', vs⇩1'', ws⇩1'') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c'' = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1'') vs⇩2'. fst p ∈ S]"
(is "?Q1' ∧ ?R2 ∧ ?Q2'")
using R and `?P1'` by simp
hence ?Q1' and ?R2 and ?Q2' by auto
from I and `?Q1` and `?Q1'` have
"(c', t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
(is ?R1)
by (blast intro: star_seq2 star_trans)
moreover have
"map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
by (rule small_steps_inputs [OF L M `?Q1` `?Q1'` `?Q2` `?Q2'`])
ultimately have "?R1 ∧ ?R2 ∧ ?this"
using `?R2` by simp
}
moreover {
fix S
assume
R: "S ≠ {}" and
S: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources (?cs' @ ?cs'') vs⇩1 s⇩1 f x)}" and
T: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags (?cs' @ ?cs'') vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have "∀x. sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x ⊆
sources (?cs' @ ?cs'') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources])
moreover have "∀x. sources_aux ?cs' vs⇩1 s⇩1 f x ⊆
sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have U: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}"
using S by blast
have "⋃ {tags_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags])
moreover have "⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T'"
(is "?T'' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "?T'' ⊆ ?T"
by simp
with T have "f = f' (⊆ vs⇩1, vs⇩1', ?T'')"
by (rule eq_streams_subset)
hence V: "(c⇩1', t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩1', f', vs⇩1'', ws⇩1'')"
using R and U and `?P1` by simp
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources ?cs'' vs s⇩1' f x)}"
by (rule sources_rhs [OF S T L `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags ?cs'' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_rhs [OF S T L V `?P1`])
ultimately have "s⇩2 = t⇩2 (⊆ S)"
using `?P2'` by blast
}
moreover {
fix S
assume
R: "S ≠ {}" and
S: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out (?cs' @ ?cs'') vs⇩1 s⇩1 f x)}" and
T: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out (?cs' @ ?cs'') vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have U: "∀x. sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x ⊆
sources_out (?cs' @ ?cs'') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
moreover have "∀x. sources_aux ?cs' vs⇩1 s⇩1 f x ⊆
sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have V: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}"
using S by blast
have W: "⋃ {tags_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags_out])
moreover have "⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T'"
(is "?T'' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "?T'' ⊆ ?T"
by simp
with T have "f = f' (⊆ vs⇩1, vs⇩1', ?T'')"
by (rule eq_streams_subset)
hence X: "(c⇩1', t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩1', f', vs⇩1'', ws⇩1'')"
using R and V and `?P1` by simp
have Y: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux (?cs' @ ?cs'') vs⇩1 s⇩1 f x)}"
using S and U by blast
have Z: "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
using T and W by (rule eq_streams_subset)
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_aux ?cs'' vs s⇩1' f x)}"
by (rule sources_aux_rhs [OF Y Z L `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_aux ?cs'' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_aux_rhs [OF Y Z L X `?P1`])
ultimately have AA:
"(c⇩2, t⇩1', f', vs⇩1'', ws⇩1'') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using R and `?P1'` by simp
have "∀x. sources_out ?cs' vs⇩1 s⇩1 f x ⊆
sources_out (?cs' @ ?cs'') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_append])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs' vs⇩1 s⇩1 f x)}"
using S by blast
moreover have "⋃ {tags_out ?cs' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_out_append])
with T have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have AB: "[p←drop (length ws⇩1) ws. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩1''. fst p ∈ S]"
using R and `?P3` by simp
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_out ?cs'' vs s⇩1' f x)}"
by (rule sources_out_rhs [OF S T L `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_out ?cs'' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_out_rhs [OF S T L X `?P1`])
ultimately have "[p←drop (length ws) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1'') ws⇩2'. fst p ∈ S]"
using R and `?P3'` by simp
hence "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
by (rule small_steps_outputs [OF L M X AA AB])
}
ultimately show
"ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using N by auto
qed
qed (simp add: no_upd_append N O Q)
qed
next
fix s' p cfs cfs'
assume I: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs} (SKIP, s', p)"
hence "(c⇩1, s, f, vs⇩0, ws⇩0) ⇒ (s', p)"
by (auto dest: small_stepsl_steps simp: big_iff_small)
hence J: "s' ∈ Univ B (⊆ state ∩ Y)"
using G and D by (rule ctyping2_approx)
assume "(c⇩2, s', p) →*{cfs'} (c', s⇩1, f, vs⇩1, ws⇩1)"
moreover obtain vs and ws where "p = (f, vs, ws)"
using I by (blast dest: small_stepsl_stream)
ultimately have K: "(c⇩2, s', f, vs, ws) →*{cfs'} (c', s⇩1, f, vs⇩1, ws⇩1)"
by simp
show ?thesis
using C [OF G _ H J K F] by simp
qed
qed
lemma ctyping2_correct_aux_or:
assumes
A: "(U, v) ⊨ c⇩1 OR c⇩2 (⊆ A, X) = Some (C, Y)" and
B: "⋀C Y c' c'' s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(U, v) ⊨ c⇩1 (⊆ A, X) = Some (C, Y) ⟹
s ∈ Univ A (⊆ state ∩ X) ⟹
(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ⟹
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
C: "⋀C Y c' c'' s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(U, v) ⊨ c⇩2 (⊆ A, X) = Some (C, Y) ⟹
s ∈ Univ A (⊆ state ∩ X) ⟹
(c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ⟹
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
D: "s ∈ Univ A (⊆ state ∩ X)" and
E: "(c⇩1 OR c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1)" and
F: "(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
from A obtain C⇩1 and Y⇩1 and C⇩2 and Y⇩2 where
G: "(U, v) ⊨ c⇩1 (⊆ A, X) = Some (C⇩1, Y⇩1)" and
H: "(U, v) ⊨ c⇩2 (⊆ A, X) = Some (C⇩2, Y⇩2)"
by (auto split: option.split_asm)
have
"(c', s⇩1, f, vs⇩1, ws⇩1) = (c⇩1 OR c⇩2, s, f, vs⇩0, ws⇩0) ∨
(c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ∨
(c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1)"
(is "?P ∨ ?Q ∨ ?R")
using E by (blast dest: small_stepsl_or)
thus ?thesis
proof (rule disjE, erule_tac [2] disjE)
assume ?P
hence "(c⇩1 OR c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)"
using F by simp
hence
"(c'', s⇩2, f, vs⇩2, ws⇩2) = (c⇩1 OR c⇩2, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [] ∨
(c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = flow (tl cfs⇩2) ∨
(c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = flow (tl cfs⇩2)"
(is "?P' ∨ _")
by (rule small_stepsl_or)
thus ?thesis
proof (rule disjE, erule_tac [2] disjE, erule_tac [2-3] conjE)
assume ?P'
with `?P` show ?thesis
by fastforce
next
assume
I: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)" and
J: "flow cfs⇩2 = flow (tl cfs⇩2)"
(is "?cs = ?cs'")
have K: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{[]} (c⇩1, s, f, vs⇩0, ws⇩0)"
by simp
hence L: "ok_flow_aux U c⇩1 c'' s s⇩2 f vs⇩0 vs⇩2 ws⇩0 ws⇩2 ?cs'"
by (rule B [OF G D _ I])
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩1 c'' c⇩2' s t⇩1 t⇩2 f f'
vs⇩0 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs' ∧
ok_flow_aux_2 s s⇩2 t⇩1 t⇩2 f f' vs⇩0 vs⇩1' ?cs' ∧
ok_flow_aux_3 s t⇩1 f f' vs⇩0 vs⇩1' ws⇩0 ws⇩1' ws⇩2 ws⇩2' ?cs'"
(is "?P1 ∧ ?P2 ∧ ?P3")
using L by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ "c⇩2'"], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
"S ≠ {}" and
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
hence
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c'' = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is "?Q1 ∧ ?Q2 ∧ ?Q3")
using `?P` and `?P1` by simp
hence ?Q1 and ?Q2 and ?Q3 by auto
moreover have "(c⇩1 OR c⇩2, t⇩1, f', vs⇩1', ws⇩1') →
(c⇩1, t⇩1, f', vs⇩1', ws⇩1')" ..
hence "(c', t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using `?P` and `?Q1` by (blast intro: star_trans)
ultimately have "?this ∧ ?Q2 ∧ ?Q3"
by simp
}
moreover {
fix S
assume
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources ?cs' vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
hence "s⇩2 = t⇩2 (⊆ S)"
using `?P` and `?P2` by blast
}
moreover {
fix S
assume
"S ≠ {}" and
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs' vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_out ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
hence "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using `?P` and `?P3` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using J by auto
qed
qed (simp add: B [OF G D K I] J)
next
assume
I: "(c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)" and
J: "flow cfs⇩2 = flow (tl cfs⇩2)"
(is "?cs = ?cs'")
have K: "(c⇩2, s, f, vs⇩0, ws⇩0) →*{[]} (c⇩2, s, f, vs⇩0, ws⇩0)"
by simp
hence L: "ok_flow_aux U c⇩2 c'' s s⇩2 f vs⇩0 vs⇩2 ws⇩0 ws⇩2 ?cs'"
by (rule C [OF H D _ I])
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩2 c'' c⇩2' s t⇩1 t⇩2 f f'
vs⇩0 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs' ∧
ok_flow_aux_2 s s⇩2 t⇩1 t⇩2 f f' vs⇩0 vs⇩1' ?cs' ∧
ok_flow_aux_3 s t⇩1 f f' vs⇩0 vs⇩1' ws⇩0 ws⇩1' ws⇩2 ws⇩2' ?cs'"
(is "?P1 ∧ ?P2 ∧ ?P3")
using L by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ "c⇩2'"], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
"S ≠ {}" and
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
hence
"(c⇩2, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c'' = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is "?Q1 ∧ ?Q2 ∧ ?Q3")
using `?P` and `?P1` by simp
hence ?Q1 and ?Q2 and ?Q3 by auto
moreover have "(c⇩1 OR c⇩2, t⇩1, f', vs⇩1', ws⇩1') →
(c⇩2, t⇩1, f', vs⇩1', ws⇩1')" ..
hence "(c', t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using `?P` and `?Q1` by (blast intro: star_trans)
ultimately have "?this ∧ ?Q2 ∧ ?Q3"
by simp
}
moreover {
fix S
assume
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources ?cs' vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
hence "s⇩2 = t⇩2 (⊆ S)"
using `?P` and `?P2` by blast
}
moreover {
fix S
assume
"S ≠ {}" and
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs' vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_out ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
hence "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using `?P` and `?P3` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using J by auto
qed
qed (simp add: C [OF H D K I] J)
qed
next
assume ?Q
thus ?thesis
by (rule B [OF G D _ F])
next
assume ?R
thus ?thesis
by (rule C [OF H D _ F])
qed
qed
lemma ctyping2_correct_aux_if:
assumes
A: "(U, v) ⊨ IF b THEN c⇩1 ELSE c⇩2 (⊆ A, X) = Some (C, Y)" and
B: "⋀U' p B⇩1 B⇩2 C⇩1 Y⇩1 c' c'' s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(U', p) = (insert (Univ? A X, bvars b) U, ⊨ b (⊆ A, X)) ⟹
(B⇩1, B⇩2) = p ⟹
(U', v) ⊨ c⇩1 (⊆ B⇩1, X) = Some (C⇩1, Y⇩1) ⟹
s ∈ Univ B⇩1 (⊆ state ∩ X) ⟹
(c⇩1, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ⟹
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux U' c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
C: "⋀U' p B⇩1 B⇩2 C⇩2 Y⇩2 c' c'' s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(U', p) = (insert (Univ? A X, bvars b) U, ⊨ b (⊆ A, X)) ⟹
(B⇩1, B⇩2) = p ⟹
(U', v) ⊨ c⇩2 (⊆ B⇩2, X) = Some (C⇩2, Y⇩2) ⟹
s ∈ Univ B⇩2 (⊆ state ∩ X) ⟹
(c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ⟹
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux U' c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
D: "s ∈ Univ A (⊆ state ∩ X)" and
E: "(IF b THEN c⇩1 ELSE c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩1}
(c', s⇩1, f, vs⇩1, ws⇩1)" and
F: "(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
let ?U' = "insert (Univ? A X, bvars b) U"
from A obtain B⇩1 and B⇩2 and C⇩1 and C⇩2 and Y⇩1 and Y⇩2 where
G: "⊨ b (⊆ A, X) = (B⇩1, B⇩2)" and
H: "(?U', v) ⊨ c⇩1 (⊆ B⇩1, X) = Some (C⇩1, Y⇩1)" and
I: "(?U', v) ⊨ c⇩2 (⊆ B⇩2, X) = Some (C⇩2, Y⇩2)"
by (auto split: option.split_asm prod.split_asm)
have
"(c', s⇩1, f, vs⇩1, ws⇩1) = (IF b THEN c⇩1 ELSE c⇩2, s, f, vs⇩0, ws⇩0) ∨
bval b s ∧ (c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1) ∨
¬ bval b s ∧ (c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1)"
(is "?P ∨ _")
using E by (blast dest: small_stepsl_if)
thus ?thesis
proof (rule disjE, erule_tac [2] disjE, erule_tac [2-3] conjE)
assume ?P
hence "(IF b THEN c⇩1 ELSE c⇩2, s, f, vs⇩0, ws⇩0) →*{cfs⇩2}
(c'', s⇩2, f, vs⇩2, ws⇩2)"
using F by simp
hence
"(c'', s⇩2, f, vs⇩2, ws⇩2) = (IF b THEN c⇩1 ELSE c⇩2, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [] ∨
bval b s ∧ (c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = ⟨bvars b⟩ # flow (tl cfs⇩2) ∨
¬ bval b s ∧ (c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = ⟨bvars b⟩ # flow (tl cfs⇩2)"
(is "?P' ∨ _")
by (rule small_stepsl_if)
thus ?thesis
proof (rule disjE, erule_tac [2] disjE, (erule_tac [2-3] conjE)+)
assume ?P'
with `?P` show ?thesis
by fastforce
next
assume
J: "bval b s" and
K: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)" and
L: "flow cfs⇩2 = ⟨bvars b⟩ # flow (tl cfs⇩2)"
(is "?cs = _ # ?cs'")
have M: "s ∈ Univ B⇩1 (⊆ state ∩ X)"
using J by (insert btyping2_approx [OF G D], simp)
have N: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{[]} (c⇩1, s, f, vs⇩0, ws⇩0)"
by simp
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (cases "bval b t⇩1")
assume O: "bval b t⇩1"
have "ok_flow_aux ?U' c⇩1 c'' s s⇩2 f vs⇩0 vs⇩2 ws⇩0 ws⇩2 ?cs'"
using B [OF _ _ H M N K] and G by simp
then obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩1 c'' c⇩2' s t⇩1 t⇩2 f f'
vs⇩0 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs' ∧
ok_flow_aux_2 s s⇩2 t⇩1 t⇩2 f f' vs⇩0 vs⇩1' ?cs' ∧
ok_flow_aux_3 s t⇩1 f f' vs⇩0 vs⇩1' ws⇩0 ws⇩1' ws⇩2 ws⇩2' ?cs'"
(is "?P1 ∧ ?P2 ∧ ?P3")
by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show ?thesis
proof (rule exI [of _ c⇩2'], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
P: "S ≠ {}" and
Q: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
R: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_aux ?cs' vs⇩1 s⇩1 f x ⊆
sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}"
using Q by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using R by (simp add: tags_aux_observe_tl)
ultimately have
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c'' = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is "?Q1 ∧ ?Q2 ∧ ?Q3")
using P and `?P` and `?P1` by simp
hence ?Q1 and ?Q2 and ?Q3 by auto
moreover have "(IF b THEN c⇩1 ELSE c⇩2, t⇩1, f', vs⇩1', ws⇩1') →
(c⇩1, t⇩1, f', vs⇩1', ws⇩1')"
using O ..
hence "(c', t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using `?P` and `?Q1` by (blast intro: star_trans)
ultimately have "?this ∧ ?Q2 ∧ ?Q3"
by simp
}
moreover {
fix S
assume
P: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
Q: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources ?cs' vs⇩1 s⇩1 f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources ?cs' vs⇩1 s⇩1 f x)}"
using P by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using Q by (simp add: tags_observe_tl)
ultimately have "s⇩2 = t⇩2 (⊆ S)"
using `?P` and `?P2` by blast
}
moreover {
fix S
assume
P: "S ≠ {}" and
Q: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
R: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_out ?cs' vs⇩1 s⇩1 f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs' vs⇩1 s⇩1 f x)}"
using Q by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using R by (simp add: tags_out_observe_tl)
ultimately have "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using P and `?P` and `?P3` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using L by auto
qed
next
assume O: "¬ bval b t⇩1"
show ?thesis
proof (cases "∃S ≠ {}. S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}")
from O have "(IF b THEN c⇩1 ELSE c⇩2, t⇩1, f', vs⇩1', ws⇩1') →
(c⇩2, t⇩1, f', vs⇩1', ws⇩1')" ..
moreover assume "∃S ≠ {}. S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}"
then obtain S where
P: "S ≠ {}" and
Q: "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
using `?P` by blast
have R: "Univ? A X: bvars b ↝| S"
using Q and D by (rule sources_aux_bval, insert J O, simp)
have "∃p. (c⇩2, t⇩1, f', vs⇩1', ws⇩1') ⇒ p"
using I by (rule ctyping2_term, insert P R, auto)
then obtain t⇩2 and f'' and vs⇩2' and ws⇩2' where
S: "(c⇩2, t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩2, f'', vs⇩2', ws⇩2')"
by (auto simp: big_iff_small)
ultimately have
"(c', t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩2, f', vs⇩2', ws⇩2')"
(is ?Q1)
using `?P` by (blast dest: small_steps_stream
intro: star_trans)
have T: "(c⇩2, t⇩1, f', vs⇩1', ws⇩1') ⇒ (t⇩2, f'', vs⇩2', ws⇩2')"
using S by (simp add: big_iff_small)
show ?thesis
proof (cases "c'' = SKIP")
assume "c'' = SKIP"
(is ?Q2)
show ?thesis
proof (rule exI [of _ SKIP], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
hence U: "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "[p←drop (length vs⇩1') vs⇩2'. fst p ∈ S] = []"
using I and T by (blast dest: ctyping2_confine)
moreover have "no_upd ?cs' S"
using B [OF _ _ H M N K] and G and U by simp
hence "[p←in_flow ?cs' vs⇩1 f. fst p ∈ S] = []"
by (rule no_upd_in_flow)
moreover have "vs⇩2 = vs⇩0 @ in_flow ?cs' vs⇩0 f"
using K by (rule small_stepsl_in_flow)
ultimately have "[p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
[p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
using `?P` by simp
hence "?Q1 ∧ ?Q2 ∧ ?this"
using `?Q1` and `?Q2` by simp
}
moreover {
fix S
assume U: "S ⊆ {x. s = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have
"∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence V: "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "t⇩1 = t⇩2 (⊆ S)"
using I and T by (blast dest: ctyping2_confine)
moreover have W: "no_upd ?cs' S"
using B [OF _ _ H M N K] and G and V by simp
hence "run_flow ?cs' vs⇩0 s f = s (⊆ S)"
by (rule no_upd_run_flow)
moreover have "s⇩2 = run_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_run_flow)
moreover have
"∀x ∈ S. x ∈ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (rule no_upd_sources, simp add: W)
hence "s = t⇩1 (⊆ S)"
using U by blast
ultimately have "s⇩2 = t⇩2 (⊆ S)"
by simp
}
moreover {
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have
"∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence U: "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S] = []"
using I and T by (blast dest: ctyping2_confine)
moreover have "no_upd ?cs' S"
using B [OF _ _ H M N K] and G and U by simp
hence "[p←out_flow ?cs' vs⇩1 s f. fst p ∈ S] = []"
by (rule no_upd_out_flow)
moreover have "ws⇩2 = ws⇩0 @ out_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_out_flow)
ultimately have
"[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using `?P` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' SKIP s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using L and `?P` by auto
qed
next
assume "c'' ≠ SKIP"
(is ?Q2)
show ?thesis
proof (rule exI [of _ c'], rule exI [of _ t⇩1],
rule exI [of _ vs⇩1'], rule exI [of _ ws⇩1'])
{
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
hence "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "no_upd ?cs' S"
using B [OF _ _ H M N K] and G by simp
hence "[p←in_flow ?cs' vs⇩1 f. fst p ∈ S] = []"
by (rule no_upd_in_flow)
moreover have "vs⇩2 = vs⇩0 @ in_flow ?cs' vs⇩0 f"
using K by (rule small_stepsl_in_flow)
ultimately have
"[p←drop (length vs⇩1) vs⇩2. fst p ∈ S] = []"
using `?P` by simp
hence "?Q2 ∧ ?this"
using `?Q2` by simp
}
moreover {
fix S
assume U: "S ⊆ {x. s = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have
"∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence V: "no_upd ?cs' S"
using B [OF _ _ H M N K] and G by simp
hence "run_flow ?cs' vs⇩0 s f = s (⊆ S)"
by (rule no_upd_run_flow)
moreover have "s⇩2 = run_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_run_flow)
moreover have
"∀x ∈ S. x ∈ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (rule no_upd_sources, simp add: V)
hence "s = t⇩1 (⊆ S)"
using U by blast
ultimately have "s⇩2 = t⇩1 (⊆ S)"
by simp
}
moreover {
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have
"∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "no_upd ?cs' S"
using B [OF _ _ H M N K] and G by simp
hence "[p←out_flow ?cs' vs⇩1 s f. fst p ∈ S] = []"
by (rule no_upd_out_flow)
moreover have "ws⇩2 = ws⇩0 @ out_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_out_flow)
ultimately have
"[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] = []"
using `?P` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' c' s⇩1 t⇩1 t⇩1 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩1' ws⇩1' ws⇩1' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩1 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩1' ?cs"
using L and `?P` by auto
qed
qed
next
assume "∄S. S ≠ {} ∧ S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}"
hence O: "∀c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using L by (auto intro!: ok_flow_aux_degen)
show ?thesis
by (rule exI [of _ SKIP], rule exI [of _ "λx. 0"],
rule exI [of _ "[]"], rule exI [of _ "[]"],
simp add: O [rule_format, of SKIP "λx. 0" "[]" "[]"])
qed
qed
qed (simp add: B [OF _ _ H M N K] G L)
next
assume
J: "¬ bval b s" and
K: "(c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2} (c'', s⇩2, f, vs⇩2, ws⇩2)" and
L: "flow cfs⇩2 = ⟨bvars b⟩ # flow (tl cfs⇩2)"
(is "?cs = _ # ?cs'")
have M: "s ∈ Univ B⇩2 (⊆ state ∩ X)"
using J by (insert btyping2_approx [OF G D], simp)
have N: "(c⇩2, s, f, vs⇩0, ws⇩0) →*{[]} (c⇩2, s, f, vs⇩0, ws⇩0)"
by simp
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (cases "bval b t⇩1", cases "∃S ≠ {}.
S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}")
assume O: "¬ bval b t⇩1"
have "ok_flow_aux ?U' c⇩2 c'' s s⇩2 f vs⇩0 vs⇩2 ws⇩0 ws⇩2 ?cs'"
using C [OF _ _ I M N K] and G by simp
then obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩2 c'' c⇩2' s t⇩1 t⇩2 f f'
vs⇩0 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs' ∧
ok_flow_aux_2 s s⇩2 t⇩1 t⇩2 f f' vs⇩0 vs⇩1' ?cs' ∧
ok_flow_aux_3 s t⇩1 f f' vs⇩0 vs⇩1' ws⇩0 ws⇩1' ws⇩2 ws⇩2' ?cs'"
(is "?P1 ∧ ?P2 ∧ ?P3")
by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show ?thesis
proof (rule exI [of _ c⇩2'], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
P: "S ≠ {}" and
Q: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
R: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_aux ?cs' vs⇩1 s⇩1 f x ⊆
sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}"
using Q by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using R by (simp add: tags_aux_observe_tl)
ultimately have
"(c⇩2, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c'' = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is "?Q1 ∧ ?Q2 ∧ ?Q3")
using P and `?P` and `?P1` by simp
hence ?Q1 and ?Q2 and ?Q3 by auto
moreover have "(IF b THEN c⇩1 ELSE c⇩2, t⇩1, f', vs⇩1', ws⇩1') →
(c⇩2, t⇩1, f', vs⇩1', ws⇩1')"
using O ..
hence "(c', t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using `?P` and `?Q1` by (blast intro: star_trans)
ultimately have "?this ∧ ?Q2 ∧ ?Q3"
by simp
}
moreover {
fix S
assume
P: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
Q: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources ?cs' vs⇩1 s⇩1 f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources ?cs' vs⇩1 s⇩1 f x)}"
using P by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using Q by (simp add: tags_observe_tl)
ultimately have "s⇩2 = t⇩2 (⊆ S)"
using `?P` and `?P2` by blast
}
moreover {
fix S
assume
P: "S ≠ {}" and
Q: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
R: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_out ?cs' vs⇩1 s⇩1 f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs' vs⇩1 s⇩1 f x)}"
using Q by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using R by (simp add: tags_out_observe_tl)
ultimately have "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using P and `?P` and `?P3` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using L by auto
qed
next
assume O: "bval b t⇩1"
hence "(IF b THEN c⇩1 ELSE c⇩2, t⇩1, f', vs⇩1', ws⇩1') →
(c⇩1, t⇩1, f', vs⇩1', ws⇩1')" ..
moreover assume "∃S ≠ {}.
S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}"
then obtain S where
P: "S ≠ {}" and
Q: "S ⊆ {x. s = t⇩1 (⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
using `?P` by blast
have R: "Univ? A X: bvars b ↝| S"
using Q and D by (rule sources_aux_bval, insert J O, simp)
have "∃p. (c⇩1, t⇩1, f', vs⇩1', ws⇩1') ⇒ p"
using H by (rule ctyping2_term, insert P R, auto)
then obtain t⇩2 and f'' and vs⇩2' and ws⇩2' where
S: "(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩2, f'', vs⇩2', ws⇩2')"
by (auto simp: big_iff_small)
ultimately have
"(c', t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩2, f', vs⇩2', ws⇩2')"
(is ?Q1)
using `?P` by (blast dest: small_steps_stream intro: star_trans)
have T: "(c⇩1, t⇩1, f', vs⇩1', ws⇩1') ⇒ (t⇩2, f'', vs⇩2', ws⇩2')"
using S by (simp add: big_iff_small)
show ?thesis
proof (cases "c'' = SKIP")
assume "c'' = SKIP"
(is ?Q2)
show ?thesis
proof (rule exI [of _ SKIP], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
hence U: "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "[p←drop (length vs⇩1') vs⇩2'. fst p ∈ S] = []"
using H and T by (blast dest: ctyping2_confine)
moreover have "no_upd ?cs' S"
using C [OF _ _ I M N K] and G and U by simp
hence "[p←in_flow ?cs' vs⇩1 f. fst p ∈ S] = []"
by (rule no_upd_in_flow)
moreover have "vs⇩2 = vs⇩0 @ in_flow ?cs' vs⇩0 f"
using K by (rule small_stepsl_in_flow)
ultimately have "[p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
[p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
using `?P` by simp
hence "?Q1 ∧ ?Q2 ∧ ?this"
using `?Q1` and `?Q2` by simp
}
moreover {
fix S
assume U: "S ⊆ {x. s = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have "∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence V: "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "t⇩1 = t⇩2 (⊆ S)"
using H and T by (blast dest: ctyping2_confine)
moreover have W: "no_upd ?cs' S"
using C [OF _ _ I M N K] and G and V by simp
hence "run_flow ?cs' vs⇩0 s f = s (⊆ S)"
by (rule no_upd_run_flow)
moreover have "s⇩2 = run_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_run_flow)
moreover have "∀x ∈ S. x ∈ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (rule no_upd_sources, simp add: W)
hence "s = t⇩1 (⊆ S)"
using U by blast
ultimately have "s⇩2 = t⇩2 (⊆ S)"
by simp
}
moreover {
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have "∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence U: "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S] = []"
using H and T by (blast dest: ctyping2_confine)
moreover have "no_upd ?cs' S"
using C [OF _ _ I M N K] and G and U by simp
hence "[p←out_flow ?cs' vs⇩1 s f. fst p ∈ S] = []"
by (rule no_upd_out_flow)
moreover have "ws⇩2 = ws⇩0 @ out_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_out_flow)
ultimately have
"[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using `?P` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' SKIP s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using L and `?P` by auto
qed
next
assume "c'' ≠ SKIP"
(is ?Q2)
show ?thesis
proof (rule exI [of _ c'], rule exI [of _ t⇩1],
rule exI [of _ vs⇩1'], rule exI [of _ ws⇩1'])
{
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
hence "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "no_upd ?cs' S"
using C [OF _ _ I M N K] and G by simp
hence "[p←in_flow ?cs' vs⇩1 f. fst p ∈ S] = []"
by (rule no_upd_in_flow)
moreover have "vs⇩2 = vs⇩0 @ in_flow ?cs' vs⇩0 f"
using K by (rule small_stepsl_in_flow)
ultimately have "[p←drop (length vs⇩1) vs⇩2. fst p ∈ S] = []"
using `?P` by simp
hence "?Q2 ∧ ?this"
using `?Q2` by simp
}
moreover {
fix S
assume U: "S ⊆ {x. s = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have "∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence V: "no_upd ?cs' S"
using C [OF _ _ I M N K] and G by simp
hence "run_flow ?cs' vs⇩0 s f = s (⊆ S)"
by (rule no_upd_run_flow)
moreover have "s⇩2 = run_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_run_flow)
moreover have "∀x ∈ S. x ∈ sources (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (rule no_upd_sources, simp add: V)
hence "s = t⇩1 (⊆ S)"
using U by blast
ultimately have "s⇩2 = t⇩1 (⊆ S)"
by simp
}
moreover {
fix S
assume "S ⊆ {x. s = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
moreover have "∀x. sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
ultimately have "S ⊆ {x. s = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s f x)}"
by blast
hence "Univ? A X: bvars b ↝| S"
using D by (rule sources_aux_bval, insert J O, simp)
hence "no_upd ?cs' S"
using C [OF _ _ I M N K] and G by simp
hence "[p←out_flow ?cs' vs⇩1 s f. fst p ∈ S] = []"
by (rule no_upd_out_flow)
moreover have "ws⇩2 = ws⇩0 @ out_flow ?cs' vs⇩0 s f"
using K by (rule small_stepsl_out_flow)
ultimately have "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] = []"
using `?P` by simp
}
ultimately show
"ok_flow_aux_1 c' c'' c' s⇩1 t⇩1 t⇩1 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩1' ws⇩1' ws⇩1' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩1 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩1' ?cs"
using L and `?P` by auto
qed
qed
next
assume "∄S. S ≠ {} ∧
S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}"
hence O: "∀c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using L by (auto intro!: ok_flow_aux_degen)
show ?thesis
by (rule exI [of _ SKIP], rule exI [of _ "λx. 0"],
rule exI [of _ "[]"], rule exI [of _ "[]"],
simp add: O [rule_format, of SKIP "λx. 0" "[]" "[]"])
qed
qed (simp add: C [OF _ _ I M N K] G L)
qed
next
assume "bval b s"
hence J: "s ∈ Univ B⇩1 (⊆ state ∩ X)"
by (insert btyping2_approx [OF G D], simp)
assume K: "(c⇩1, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1)"
show ?thesis
using B [OF _ _ H J K F] and G by simp
next
assume "¬ bval b s"
hence J: "s ∈ Univ B⇩2 (⊆ state ∩ X)"
by (insert btyping2_approx [OF G D], simp)
assume K: "(c⇩2, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c', s⇩1, f, vs⇩1, ws⇩1)"
show ?thesis
using C [OF _ _ I J K F] and G by simp
qed
qed
lemma ctyping2_correct_aux_while:
assumes
A: "(U, v) ⊨ WHILE b DO c (⊆ A, X) = Some (B, W)" and
B: "⋀B⇩1 B⇩2 C Y B⇩1' B⇩2' D Z c⇩1 c⇩2 s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(B⇩1, B⇩2) = ⊨ b (⊆ A, X) ⟹
(C, Y) = ⊢ c (⊆ B⇩1, X) ⟹
(B⇩1', B⇩2') = ⊨ b (⊆ C, Y) ⟹
∀(B, W) ∈ insert (Univ? A X ∪ Univ? C Y, bvars b) U.
B: W ↝ UNIV ⟹
({}, False) ⊨ c (⊆ B⇩1, X) = Some (D, Z) ⟹
s ∈ Univ B⇩1 (⊆ state ∩ X) ⟹
(c, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1) ⟹
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux {} c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
C: "⋀B⇩1 B⇩2 C Y B⇩1' B⇩2' D' Z' c⇩1 c⇩2 s s⇩1 s⇩2 vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2.
(B⇩1, B⇩2) = ⊨ b (⊆ A, X) ⟹
(C, Y) = ⊢ c (⊆ B⇩1, X) ⟹
(B⇩1', B⇩2') = ⊨ b (⊆ C, Y) ⟹
∀(B, W) ∈ insert (Univ? A X ∪ Univ? C Y, bvars b) U.
B: W ↝ UNIV ⟹
({}, False) ⊨ c (⊆ B⇩1', Y) = Some (D', Z') ⟹
s ∈ Univ B⇩1' (⊆ state ∩ Y) ⟹
(c, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1) ⟹
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2) ⟹
ok_flow_aux {} c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)" and
D: "s ∈ Univ A (⊆ state ∩ X)" and
E: "(WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)" and
F: "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
shows "ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof -
from A obtain B⇩1 B⇩2 C Y B⇩1' B⇩2' D Z D' Z' where
G: "⊨ b (⊆ A, X) = (B⇩1, B⇩2)" and
H: "⊢ c (⊆ B⇩1, X) = (C, Y)" and
I: "⊨ b (⊆ C, Y) = (B⇩1', B⇩2')" and
J: "({}, False) ⊨ c (⊆ B⇩1, X) = Some (D, Z)" and
K: "({}, False) ⊨ c (⊆ B⇩1', Y) = Some (D', Z')" and
L: "∀(B, W) ∈ insert (Univ? A X ∪ Univ? C Y, bvars b) U. B: W ↝ UNIV"
by (fastforce split: if_split_asm option.split_asm prod.split_asm)
from UnI1 [OF D, of "Univ C (⊆ state ∩ Y)"] and E and F show ?thesis
proof (induction "cfs⇩1 @ cfs⇩2" arbitrary: cfs⇩1 cfs⇩2 s vs⇩0 ws⇩0 c⇩1 s⇩1 vs⇩1 ws⇩1
rule: length_induct)
fix cfs⇩1 cfs⇩2 s vs⇩0 ws⇩0 c⇩1 s⇩1 vs⇩1 ws⇩1
assume
M: "∀cfs. length cfs < length (cfs⇩1 @ cfs⇩2) ⟶
(∀cfs' cfs''. cfs = cfs' @ cfs'' ⟶
(∀s. s ∈ Univ A (⊆ state ∩ X) ∪ Univ C (⊆ state ∩ Y) ⟶
(∀vs⇩0 ws⇩0 c⇩1 s⇩1 vs⇩1 ws⇩1.
(WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{cfs'} (c⇩1, s⇩1, f, vs⇩1, ws⇩1) ⟶
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs''} (c⇩2, s⇩2, f, vs⇩2, ws⇩2) ⟶
ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs''))))" and
N: "s ∈ Univ A (⊆ state ∩ X) ∪ Univ C (⊆ state ∩ Y)" and
O: "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
assume "(WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)"
hence
"(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (WHILE b DO c, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩1 = [] ∨
bval b s ∧
(c;; WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1) ∧
flow cfs⇩1 = ⟨bvars b⟩ # flow (tl cfs⇩1) ∨
¬ bval b s ∧
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (SKIP, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩1 = [⟨bvars b⟩]"
by (rule small_stepsl_while)
thus "ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
proof (rule disjE, erule_tac [2] disjE, erule_tac conjE,
(erule_tac [2-3] conjE)+)
assume P: "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (WHILE b DO c, s, f, vs⇩0, ws⇩0)"
hence "(WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
using O by simp
hence
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (WHILE b DO c, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [] ∨
bval b s ∧
(c;; WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2}
(c⇩2, s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = ⟨bvars b⟩ # flow (tl cfs⇩2) ∨
¬ bval b s ∧
(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s, f, vs⇩0, ws⇩0) ∧
flow cfs⇩2 = [⟨bvars b⟩]"
by (rule small_stepsl_while)
thus ?thesis
proof (rule disjE, erule_tac [2] disjE, erule_tac conjE,
(erule_tac [2-3] conjE)+)
assume
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (WHILE b DO c, s, f, vs⇩0, ws⇩0)" and
"flow cfs⇩2 = []"
thus ?thesis
using P by fastforce
next
assume
Q: "bval b s" and
R: "flow cfs⇩2 = ⟨bvars b⟩ # flow (tl cfs⇩2)"
(is "?cs = _ # ?cs'")
assume "(c;; WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩2}
(c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
hence
"(∃c' cfs.
c⇩2 = c';; WHILE b DO c ∧
(c, s, f, vs⇩0, ws⇩0) →*{cfs} (c', s⇩2, f, vs⇩2, ws⇩2) ∧
?cs' = flow cfs) ∨
(∃p cfs' cfs''.
length cfs'' < length (tl cfs⇩2) ∧
(c, s, f, vs⇩0, ws⇩0) →*{cfs'} (SKIP, p) ∧
(WHILE b DO c, p) →*{cfs''} (c⇩2, s⇩2, f, vs⇩2, ws⇩2) ∧
?cs' = flow cfs' @ flow cfs'')"
by (rule small_stepsl_seq)
thus ?thesis
apply (rule disjE)
apply (erule exE)+
apply (erule conjE)+
subgoal for c' cfs
proof -
assume
S: "c⇩2 = c';; WHILE b DO c" and
T: "(c, s, f, vs⇩0, ws⇩0) →*{cfs} (c', s⇩2, f, vs⇩2, ws⇩2)" and
U: "?cs' = flow cfs"
have V: "(c, s, f, vs⇩0, ws⇩0) →*{[]} (c, s, f, vs⇩0, ws⇩0)"
by simp
from N have
"ok_flow_aux {} c c' s s⇩2 f vs⇩0 vs⇩2 ws⇩0 ws⇩2 (flow cfs)"
proof
assume W: "s ∈ Univ A (⊆ state ∩ X)"
have X: "s ∈ Univ B⇩1 (⊆ state ∩ X)"
using Q by (insert btyping2_approx [OF G W], simp)
show ?thesis
by (rule B [OF G [symmetric] H [symmetric] I [symmetric]
L J X V T])
next
assume W: "s ∈ Univ C (⊆ state ∩ Y)"
have X: "s ∈ Univ B⇩1' (⊆ state ∩ Y)"
using Q by (insert btyping2_approx [OF I W], simp)
show ?thesis
by (rule C [OF G [symmetric] H [symmetric] I [symmetric]
L K X V T])
qed
hence W: "ok_flow_aux {} c c' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 ?cs'"
using P and U by simp
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c c' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs' ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs' ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs'"
(is "?P1 ∧ ?P2 ∧ ?P3")
using W by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ "c⇩2';; WHILE b DO c"], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
X: "S ≠ {}" and
Y: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
Z: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_aux ?cs' vs⇩1 s⇩1 f x ⊆
sources_aux (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs' vs⇩1 s⇩1 f x)}"
using Y by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using Z by (simp add: tags_aux_observe_tl)
ultimately have
"(c, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is "?Q1 ∧ ?Q2")
using X and `?P1` by simp
hence ?Q1 and ?Q2 by auto
have "s⇩1 = t⇩1 (⊆ bvars b)"
by (rule eq_states_while [OF Y X], insert L N P, simp+)
hence "bval b t⇩1"
using P and Q by (blast dest: bvars_bval)
hence "(WHILE b DO c, t⇩1, f', vs⇩1', ws⇩1') →
(c;; WHILE b DO c, t⇩1, f', vs⇩1', ws⇩1')" ..
hence "(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →*
(c⇩2';; WHILE b DO c, t⇩2, f', vs⇩2', ws⇩2')"
using P and `?Q1` by (blast intro: star_seq2 star_trans)
hence "?this ∧ ?Q2"
using `?Q2` by simp
}
moreover {
fix S
assume
X: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
Y: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources ?cs' vs⇩1 s⇩1 f x ⊆
sources (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources ?cs' vs⇩1 s⇩1 f x)}"
using X by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using Y by (simp add: tags_observe_tl)
ultimately have "s⇩2 = t⇩2 (⊆ S)"
using `?P2` by blast
}
moreover {
fix S
assume
X: "S ≠ {}" and
Y: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x)}" and
Z: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_out ?cs' vs⇩1 s⇩1 f x ⊆
sources_out (⟨bvars b⟩ # ?cs') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_observe_tl])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs' vs⇩1 s⇩1 f x)}"
using Y by blast
moreover have "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out ?cs' vs⇩1 s⇩1 f x | x. x ∈ S})"
using Z by (simp add: tags_out_observe_tl)
ultimately have "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using X and `?P3` by simp
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 (c⇩2';; WHILE b DO c) s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using R and S by auto
qed
qed (insert L, auto simp: no_upd_empty)
qed
apply (erule exE)+
apply (erule conjE)+
subgoal for p cfs' cfs''
proof -
assume "(c, s, f, vs⇩0, ws⇩0) →*{cfs'} (SKIP, p)"
moreover from this obtain s⇩1' and vs and ws where
S: "p = (s⇩1', f, vs, ws)"
by (blast dest: small_stepsl_stream)
ultimately have
T: "(c, s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, s⇩1', f, vs, ws)"
using P by simp
assume "(WHILE b DO c, p) →*{cfs''} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
with S have
U: "(WHILE b DO c, s⇩1', f, vs, ws) →*{cfs''}
(c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
by simp
assume V: "?cs' = flow cfs' @ flow cfs''"
(is "(_ :: flow) = ?cs⇩1' @ ?cs⇩2'")
have W: "(c, s⇩1, f, vs⇩1, ws⇩1) →*{[]} (c, s⇩1, f, vs⇩1, ws⇩1)"
by simp
from N have "ok_flow_aux {} c SKIP s⇩1 s⇩1' f vs⇩1 vs ws⇩1 ws ?cs⇩1'"
proof
assume X: "s ∈ Univ A (⊆ state ∩ X)"
have Y: "s⇩1 ∈ Univ B⇩1 (⊆ state ∩ X)"
using P and Q by (insert btyping2_approx [OF G X], simp)
show ?thesis
by (rule B [OF G [symmetric] H [symmetric] I [symmetric]
L J Y W T])
next
assume X: "s ∈ Univ C (⊆ state ∩ Y)"
have Y: "s⇩1 ∈ Univ B⇩1' (⊆ state ∩ Y)"
using P and Q by (insert btyping2_approx [OF I X], simp)
show ?thesis
by (rule C [OF G [symmetric] H [symmetric] I [symmetric]
L K Y W T])
qed
hence X: "ok_flow_aux {} c SKIP s⇩1 s⇩1' f vs⇩1 vs ws⇩1 ws ?cs⇩1'"
using P by simp
assume "length cfs'' < length (tl cfs⇩2)"
hence "length ([] @ cfs'') < length (cfs⇩1 @ cfs⇩2)"
by simp
moreover have "[] @ cfs'' = [] @ cfs''" ..
moreover from T have "(c, s, f, vs⇩0, ws⇩0) ⇒ (s⇩1', f, vs, ws)"
using P by (auto dest: small_stepsl_steps simp: big_iff_small)
hence "s⇩1' ∈ Univ A (⊆ state ∩ X) ∪ Univ C (⊆ state ∩ Y)"
by (rule univ_states_while [OF _ G H I J K Q N])
moreover have "(WHILE b DO c, s⇩1', f, vs, ws) →*{[]}
(WHILE b DO c, s⇩1', f, vs, ws)"
by simp
ultimately have
Y: "ok_flow_aux U (WHILE b DO c) c⇩2 s⇩1' s⇩2 f vs vs⇩2 ws ws⇩2 ?cs⇩2'"
using U by (rule M [rule_format])
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩1'' and t⇩1' and vs⇩1'' and ws⇩1'' where
"ok_flow_aux_1 c SKIP c⇩1'' s⇩1 t⇩1 t⇩1' f f'
vs⇩1 vs⇩1' vs vs⇩1'' ws⇩1' ws⇩1'' ?cs⇩1' ∧
ok_flow_aux_2 s⇩1 s⇩1' t⇩1 t⇩1' f f' vs⇩1 vs⇩1' ?cs⇩1' ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws ws⇩1'' ?cs⇩1'"
(is "_ ∧ ?P2 ∧ ?P3")
using X by fastforce
hence
"ok_flow_aux_1 c SKIP SKIP s⇩1 t⇩1 t⇩1' f f'
vs⇩1 vs⇩1' vs vs⇩1'' ws⇩1' ws⇩1'' ?cs⇩1'"
(is ?P1) and ?P2 and ?P3 by auto
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 (WHILE b DO c) c⇩2 c⇩2' s⇩1' t⇩1' t⇩2 f f'
vs vs⇩1'' vs⇩2 vs⇩2' ws⇩1'' ws⇩2' ?cs⇩2' ∧
ok_flow_aux_2 s⇩1' s⇩2 t⇩1' t⇩2 f f' vs vs⇩1'' ?cs⇩2' ∧
ok_flow_aux_3 s⇩1' t⇩1' f f' vs vs⇩1'' ws ws⇩1'' ws⇩2 ws⇩2' ?cs⇩2'"
(is "?P1' ∧ ?P2' ∧ ?P3'")
using Y by fastforce
hence ?P1' and ?P2' and ?P3' by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ c⇩2'], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
Z: "S ≠ {}" and
AA: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux
(⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}" and
AB: "f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_aux
(⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x ⊆
sources_aux (⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_observe_tl])
hence AC: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}"
using AA by blast
moreover have "∀x. sources_aux ?cs⇩1' vs⇩1 s⇩1 f x ⊆
sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have
AD: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs⇩1' vs⇩1 s⇩1 f x)}"
by blast
have AE: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
using AB by (simp add: tags_aux_observe_tl)
moreover have
"⋃ {tags_aux ?cs⇩1' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
hence
"(c, t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩1', f', vs⇩1'', ws⇩1'') ∧
map fst [p←drop (length vs⇩1) vs. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩1''. fst p ∈ S]"
(is "?Q1 ∧ ?Q2")
using Z and AD and `?P1` by simp
hence ?Q1 and ?Q2 by auto
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_aux ?cs⇩2' vs s⇩1' f x)}"
by (rule sources_aux_rhs [OF AC AE T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_aux ?cs⇩2' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_aux_rhs [OF AC AE T `?Q1` `?P1`])
ultimately have
"(WHILE b DO c, t⇩1', f', vs⇩1'', ws⇩1'') →*
(c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c⇩2 = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1'') vs⇩2'. fst p ∈ S]"
(is "?Q1' ∧ ?R2 ∧ ?Q2'")
using Z and `?P1'` by simp
hence ?Q1' and ?R2 and ?Q2' by auto
have "s⇩1 = t⇩1 (⊆ bvars b)"
by (rule eq_states_while [OF AA Z], insert L N P, simp+)
hence "bval b t⇩1"
using P and Q by (blast dest: bvars_bval)
hence "(WHILE b DO c, t⇩1, f', vs⇩1', ws⇩1') →
(c;; WHILE b DO c, t⇩1, f', vs⇩1', ws⇩1')" ..
moreover have "(c;; WHILE b DO c, t⇩1, f', vs⇩1', ws⇩1') →*
(c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using `?Q1` and `?Q1'`
by (blast intro: star_seq2 star_trans)
ultimately have
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
(is ?R1)
using P by (blast intro: star_trans)
moreover have
"map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
by (rule small_steps_inputs
[OF T U `?Q1` `?Q1'` `?Q2` `?Q2'`])
ultimately have "?R1 ∧ ?R2 ∧ ?this"
using `?R2` by simp
}
moreover {
fix S
assume
Z: "S ≠ {}" and
AA: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources
(⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}" and
AB: "f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags
(⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x ⊆
sources (⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_observe_tl])
hence AC: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}"
using AA by blast
have "∀x. sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x ⊆
sources (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources])
moreover have "∀x. sources_aux ?cs⇩1' vs⇩1 s⇩1 f x ⊆
sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have
AD: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs⇩1' vs⇩1 s⇩1 f x)}"
using AC by blast
have AE: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
using AB by (simp add: tags_observe_tl)
have
"⋃ {tags_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags])
moreover have
"⋃ {tags_aux ?cs⇩1' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T'"
(is "?T'' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "?T'' ⊆ ?T"
by simp
with AE have "f = f' (⊆ vs⇩1, vs⇩1', ?T'')"
by (rule eq_streams_subset)
hence AF: "(c, t⇩1, f', vs⇩1', ws⇩1') →*
(SKIP, t⇩1', f', vs⇩1'', ws⇩1'')"
using Z and AD and `?P1` by simp
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources ?cs⇩2' vs s⇩1' f x)}"
by (rule sources_rhs [OF AC AE T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags ?cs⇩2' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_rhs [OF AC AE T AF `?P1`])
ultimately have "s⇩2 = t⇩2 (⊆ S)"
using `?P2'` by blast
}
moreover {
fix S
assume
Z: "S ≠ {}" and
AA: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out
(⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}" and
AB: "f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_out
(⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S})"
have "∀x. sources_out (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x ⊆
sources_out (⟨bvars b⟩ # ?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_observe_tl])
hence AC: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_out (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}"
using AA by blast
have AD: "∀x. sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x ⊆
sources_out (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
moreover have "∀x. sources_aux ?cs⇩1' vs⇩1 s⇩1 f x ⊆
sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have
AE: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs⇩1' vs⇩1 s⇩1 f x)}"
using AC by blast
have AF: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
using AB by (simp add: tags_out_observe_tl)
have AG:
"⋃ {tags_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags_out])
moreover have
"⋃ {tags_aux ?cs⇩1' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T'"
(is "?T'' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "?T'' ⊆ ?T"
by simp
with AF have "f = f' (⊆ vs⇩1, vs⇩1', ?T'')"
by (rule eq_streams_subset)
hence AH: "(c, t⇩1, f', vs⇩1', ws⇩1') →*
(SKIP, t⇩1', f', vs⇩1'', ws⇩1'')"
using Z and AE and `?P1` by simp
have AI: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x)}"
using AC and AD by blast
have AJ: "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
using AF and AG by (rule eq_streams_subset)
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_aux ?cs⇩2' vs s⇩1' f x)}"
by (rule sources_aux_rhs [OF AI AJ T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_aux ?cs⇩2' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_aux_rhs [OF AI AJ T AH `?P1`])
ultimately have AK:
"(WHILE b DO c, t⇩1', f', vs⇩1'', ws⇩1'') →*
(c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using Z and `?P1'` by simp
have "∀x. sources_out ?cs⇩1' vs⇩1 s⇩1 f x ⊆
sources_out (?cs⇩1' @ ?cs⇩2') vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_append])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs⇩1' vs⇩1 s⇩1 f x)}"
using AC by blast
moreover have
"⋃ {tags_out ?cs⇩1' vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_out_append])
with AF have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have AL:
"[p←drop (length ws⇩1) ws. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩1''. fst p ∈ S]"
using Z and `?P3` by simp
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_out ?cs⇩2' vs s⇩1' f x)}"
by (rule sources_out_rhs [OF AC AF T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_out ?cs⇩2' vs s⇩1' f x | x. x ∈ S})"
by (rule tags_out_rhs [OF AC AF T AH `?P1`])
ultimately have "[p←drop (length ws) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1'') ws⇩2'. fst p ∈ S]"
using Z and `?P3'` by simp
hence "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
by (rule small_steps_outputs [OF T U AH AK AL])
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using R and V by auto
qed
qed (insert L, auto simp: no_upd_empty)
qed
done
next
assume
Q: "¬ bval b s" and
R: "flow cfs⇩2 = [⟨bvars b⟩]"
(is "?cs = _")
assume "(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s, f, vs⇩0, ws⇩0)"
hence S: "(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s⇩1, f, vs⇩1, ws⇩1)"
using P by simp
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ SKIP], rule exI [of _ t⇩1],
rule exI [of _ vs⇩1'], rule exI [of _ ws⇩1'])
{
fix S
assume
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux [⟨bvars b⟩] vs⇩1 s⇩1 f x)}" and
"S ≠ {}"
hence "s⇩1 = t⇩1 (⊆ bvars b)"
by (rule eq_states_while, insert L N P, simp+)
hence "¬ bval b t⇩1"
using P and Q by (blast dest: bvars_bval)
hence "(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (SKIP, t⇩1, f', vs⇩1', ws⇩1')"
using P by simp
}
moreover {
fix S
assume "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources [⟨bvars b⟩] vs⇩1 s⇩1 f x)}"
moreover have "∀x. sources [] vs⇩1 s⇩1 f x ⊆
sources [⟨bvars b⟩] vs⇩1 s⇩1 f x"
by (blast intro!: sources_observe_tl)
ultimately have "s⇩1 = t⇩1 (⊆ S)"
by auto
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 SKIP s⇩1 t⇩1 t⇩1 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩1' ws⇩1' ws⇩1' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩1 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩1' ?cs"
using R and S by auto
qed
qed (insert L, auto simp: no_upd_empty)
qed
next
assume P: "bval b s"
assume "(c;; WHILE b DO c, s, f, vs⇩0, ws⇩0) →*{tl cfs⇩1}
(c⇩1, s⇩1, f, vs⇩1, ws⇩1)"
hence
"(∃c' cfs.
c⇩1 = c';; WHILE b DO c ∧
(c, s, f, vs⇩0, ws⇩0) →*{cfs} (c', s⇩1, f, vs⇩1, ws⇩1) ∧
flow (tl cfs⇩1) = flow cfs) ∨
(∃p cfs' cfs''.
length cfs'' < length (tl cfs⇩1) ∧
(c, s, f, vs⇩0, ws⇩0) →*{cfs'} (SKIP, p) ∧
(WHILE b DO c, p) →*{cfs''} (c⇩1, s⇩1, f, vs⇩1, ws⇩1) ∧
flow (tl cfs⇩1) = flow cfs' @ flow cfs'')"
by (rule small_stepsl_seq)
thus ?thesis
apply (rule disjE)
apply (erule exE)+
apply (erule conjE)+
subgoal for c' cfs
proof -
assume
Q: "(c, s, f, vs⇩0, ws⇩0) →*{cfs} (c', s⇩1, f, vs⇩1, ws⇩1)" and
R: "c⇩1 = c';; WHILE b DO c"
hence "(c';; WHILE b DO c, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2}
(c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
using O by simp
hence
"(∃c'' cfs'.
c⇩2 = c'';; WHILE b DO c ∧
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (c'', s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = flow cfs') ∨
(∃p cfs' cfs''.
length cfs'' < length cfs⇩2 ∧
(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, p) ∧
(WHILE b DO c, p) →*{cfs''} (c⇩2, s⇩2, f, vs⇩2, ws⇩2) ∧
flow cfs⇩2 = flow cfs' @ flow cfs'')"
by (rule small_stepsl_seq)
thus ?thesis
apply (rule disjE)
apply (erule exE)+
apply (erule conjE)+
subgoal for c'' cfs'
proof -
assume
S: "c⇩2 = c'';; WHILE b DO c" and
T: "(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (c'', s⇩2, f, vs⇩2, ws⇩2)" and
U: "flow cfs⇩2 = flow cfs'"
(is "?cs = ?cs'")
from N have "ok_flow_aux {} c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 ?cs'"
proof
assume V: "s ∈ Univ A (⊆ state ∩ X)"
have W: "s ∈ Univ B⇩1 (⊆ state ∩ X)"
using P by (insert btyping2_approx [OF G V], simp)
show ?thesis
by (rule B [OF G [symmetric] H [symmetric] I [symmetric]
L J W Q T])
next
assume V: "s ∈ Univ C (⊆ state ∩ Y)"
have W: "s ∈ Univ B⇩1' (⊆ state ∩ Y)"
using P by (insert btyping2_approx [OF I V], simp)
show ?thesis
by (rule C [OF G [symmetric] H [symmetric] I [symmetric]
L K W Q T])
qed
hence V: "ok_flow_aux {} c' c'' s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 ?cs"
using U by simp
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c' c'' c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
(is "?P1 ∧ ?P2 ∧ ?P3")
using V by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ "c⇩2';; WHILE b DO c"],
rule exI [of _ t⇩2], rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume "S ≠ {}" and
"S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs vs⇩1 s⇩1 f x)}" and
"f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux ?cs vs⇩1 s⇩1 f x | x. x ∈ S})"
hence
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →*
(c⇩2';; WHILE b DO c, t⇩2, f', vs⇩2', ws⇩2') ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
using R and `?P1` by (blast intro: star_seq2)
}
thus
"ok_flow_aux_1 c⇩1 c⇩2 (c⇩2';; WHILE b DO c) s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using S and `?P2` and `?P3` by simp
qed
qed (insert L, auto simp: no_upd_empty)
qed
apply (erule exE)+
apply (erule conjE)+
subgoal for p cfs' cfs''
proof -
assume "(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, p)"
moreover from this obtain s⇩1' and vs and ws where
S: "p = (s⇩1', f, vs, ws)"
by (blast dest: small_stepsl_stream)
ultimately have
T: "(c', s⇩1, f, vs⇩1, ws⇩1) →*{cfs'} (SKIP, s⇩1', f, vs, ws)"
by simp
assume "(WHILE b DO c, p) →*{cfs''} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
with S have
U: "(WHILE b DO c, s⇩1', f, vs, ws) →*{cfs''}
(c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
by simp
assume V: "flow cfs⇩2 = flow cfs' @ flow cfs''"
(is "(?cs :: flow) = ?cs⇩1 @ ?cs⇩2")
from N have
W: "ok_flow_aux {} c' SKIP s⇩1 s⇩1' f vs⇩1 vs ws⇩1 ws ?cs⇩1"
proof
assume X: "s ∈ Univ A (⊆ state ∩ X)"
have Y: "s ∈ Univ B⇩1 (⊆ state ∩ X)"
using P by (insert btyping2_approx [OF G X], simp)
show ?thesis
by (rule B [OF G [symmetric] H [symmetric] I [symmetric]
L J Y Q T])
next
assume X: "s ∈ Univ C (⊆ state ∩ Y)"
have Y: "s ∈ Univ B⇩1' (⊆ state ∩ Y)"
using P by (insert btyping2_approx [OF I X], simp)
show ?thesis
by (rule C [OF G [symmetric] H [symmetric] I [symmetric]
L K Y Q T])
qed
assume "length cfs'' < length cfs⇩2"
hence "length ([] @ cfs'') < length (cfs⇩1 @ cfs⇩2)"
by simp
moreover have "[] @ cfs'' = [] @ cfs''" ..
moreover have
"(c, s, f, vs⇩0, ws⇩0) →*{cfs @ cfs'} (SKIP, s⇩1', f, vs, ws)"
using Q and T by (rule small_stepsl_append)
hence "(c, s, f, vs⇩0, ws⇩0) ⇒ (s⇩1', f, vs, ws)"
by (auto dest: small_stepsl_steps simp: big_iff_small)
hence "s⇩1' ∈ Univ A (⊆ state ∩ X) ∪ Univ C (⊆ state ∩ Y)"
by (rule univ_states_while [OF _ G H I J K P N])
moreover have "(WHILE b DO c, s⇩1', f, vs, ws) →*{[]}
(WHILE b DO c, s⇩1', f, vs, ws)"
by simp
ultimately have X:
"ok_flow_aux U (WHILE b DO c) c⇩2 s⇩1' s⇩2 f vs vs⇩2 ws ws⇩2 ?cs⇩2"
using U by (rule M [rule_format])
show ?thesis
proof (rule conjI, clarify)
fix t⇩1 f' vs⇩1' ws⇩1'
obtain c⇩1'' and t⇩1' and vs⇩1'' and ws⇩1'' where
"ok_flow_aux_1 c' SKIP c⇩1'' s⇩1 t⇩1 t⇩1' f f'
vs⇩1 vs⇩1' vs vs⇩1'' ws⇩1' ws⇩1'' ?cs⇩1 ∧
ok_flow_aux_2 s⇩1 s⇩1' t⇩1 t⇩1' f f' vs⇩1 vs⇩1' ?cs⇩1 ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws ws⇩1'' ?cs⇩1"
(is "_ ∧ ?P2 ∧ ?P3")
using W by fastforce
hence
"ok_flow_aux_1 c' SKIP SKIP s⇩1 t⇩1 t⇩1' f f'
vs⇩1 vs⇩1' vs vs⇩1'' ws⇩1' ws⇩1'' ?cs⇩1"
(is ?P1) and ?P2 and ?P3 by auto
obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 (WHILE b DO c) c⇩2 c⇩2' s⇩1' t⇩1' t⇩2 f f'
vs vs⇩1'' vs⇩2 vs⇩2' ws⇩1'' ws⇩2' ?cs⇩2 ∧
ok_flow_aux_2 s⇩1' s⇩2 t⇩1' t⇩2 f f' vs vs⇩1'' ?cs⇩2 ∧
ok_flow_aux_3 s⇩1' t⇩1' f f' vs vs⇩1'' ws ws⇩1'' ws⇩2 ws⇩2' ?cs⇩2"
(is "?P1' ∧ ?P2' ∧ ?P3'")
using X by fastforce
hence ?P1' and ?P2' and ?P3' by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ c⇩2'], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
Y: "S ≠ {}" and
Z: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x)}" and
AA: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have "∀x. sources_aux ?cs⇩1 vs⇩1 s⇩1 f x ⊆
sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs⇩1 vs⇩1 s⇩1 f x)}"
using Z by blast
moreover have
"⋃ {tags_aux ?cs⇩1 vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
with AA have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have
"(c', t⇩1, f', vs⇩1', ws⇩1') →*
(SKIP, t⇩1', f', vs⇩1'', ws⇩1'') ∧
map fst [p←drop (length vs⇩1) vs. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩1''. fst p ∈ S]"
(is "?Q1 ∧ ?Q2")
using Y and `?P1` by simp
hence ?Q1 and ?Q2 by auto
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_aux ?cs⇩2 vs s⇩1' f x)}"
by (rule sources_aux_rhs [OF Z AA T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_aux ?cs⇩2 vs s⇩1' f x | x. x ∈ S})"
by (rule tags_aux_rhs [OF Z AA T `?Q1` `?P1`])
ultimately have
"(WHILE b DO c, t⇩1', f', vs⇩1'', ws⇩1'') →*
(c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c⇩2 = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1'') vs⇩2'. fst p ∈ S]"
(is "?Q1' ∧ ?R2 ∧ ?Q2'")
using Y and `?P1'` by simp
hence ?Q1' and ?R2 and ?Q2' by auto
from R and `?Q1` and `?Q1'` have
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
(is ?R1)
by (blast intro: star_seq2 star_trans)
moreover have
"map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
by (rule small_steps_inputs
[OF T U `?Q1` `?Q1'` `?Q2` `?Q2'`])
ultimately have "?R1 ∧ ?R2 ∧ ?this"
using `?R2` by simp
}
moreover {
fix S
assume
Y: "S ≠ {}" and
Z: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x)}" and
AA: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have "∀x. sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x ⊆
sources (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources])
moreover have "∀x. sources_aux ?cs⇩1 vs⇩1 s⇩1 f x ⊆
sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have
AB: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs⇩1 vs⇩1 s⇩1 f x)}"
using Z by blast
have
"⋃ {tags_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags])
moreover have
"⋃ {tags_aux ?cs⇩1 vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T'"
(is "?T'' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "?T'' ⊆ ?T"
by simp
with AA have "f = f' (⊆ vs⇩1, vs⇩1', ?T'')"
by (rule eq_streams_subset)
hence AC: "(c', t⇩1, f', vs⇩1', ws⇩1') →*
(SKIP, t⇩1', f', vs⇩1'', ws⇩1'')"
using Y and AB and `?P1` by simp
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources ?cs⇩2 vs s⇩1' f x)}"
by (rule sources_rhs [OF Z AA T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags ?cs⇩2 vs s⇩1' f x | x. x ∈ S})"
by (rule tags_rhs [OF Z AA T AC `?P1`])
ultimately have "s⇩2 = t⇩2 (⊆ S)"
using `?P2'` by blast
}
moreover {
fix S
assume
Y: "S ≠ {}" and
Z: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_out (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x)}" and
AA: "f = f' (⊆ vs⇩1, vs⇩1',
⋃ {tags_out (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have AB: "∀x. sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x ⊆
sources_out (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
moreover have "∀x. sources_aux ?cs⇩1 vs⇩1 s⇩1 f x ⊆
sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_append])
ultimately have
AC: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs⇩1 vs⇩1 s⇩1 f x)}"
using Z by blast
have AD:
"⋃ {tags_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags_out])
moreover have
"⋃ {tags_aux ?cs⇩1 vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T'"
(is "?T'' ⊆ _")
by (blast intro: subsetD [OF tags_aux_append])
ultimately have "?T'' ⊆ ?T"
by simp
with AA have "f = f' (⊆ vs⇩1, vs⇩1', ?T'')"
by (rule eq_streams_subset)
hence AE: "(c', t⇩1, f', vs⇩1', ws⇩1') →*
(SKIP, t⇩1', f', vs⇩1'', ws⇩1'')"
using Y and AC and `?P1` by simp
have AF: "S ⊆ {x. s⇩1 = t⇩1
(⊆ sources_aux (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x)}"
using Z and AB by blast
have AG: "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
using AA and AD by (rule eq_streams_subset)
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_aux ?cs⇩2 vs s⇩1' f x)}"
by (rule sources_aux_rhs [OF AF AG T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_aux ?cs⇩2 vs s⇩1' f x | x. x ∈ S})"
by (rule tags_aux_rhs [OF AF AG T AE `?P1`])
ultimately have
AH: "(WHILE b DO c, t⇩1', f', vs⇩1'', ws⇩1'') →*
(c⇩2', t⇩2, f', vs⇩2', ws⇩2')"
using Y and `?P1'` by simp
have "∀x. sources_out ?cs⇩1 vs⇩1 s⇩1 f x ⊆
sources_out (?cs⇩1 @ ?cs⇩2) vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_out_append])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs⇩1 vs⇩1 s⇩1 f x)}"
using Z by blast
moreover have
"⋃ {tags_out ?cs⇩1 vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_out_append])
with AA have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have AI:
"[p←drop (length ws⇩1) ws. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩1''. fst p ∈ S]"
using Y and `?P3` by simp
have "S ⊆ {x. s⇩1' = t⇩1' (⊆ sources_out ?cs⇩2 vs s⇩1' f x)}"
by (rule sources_out_rhs [OF Z AA T `?P2`])
moreover have "f = f' (⊆ vs, vs⇩1'',
⋃ {tags_out ?cs⇩2 vs s⇩1' f x | x. x ∈ S})"
by (rule tags_out_rhs [OF Z AA T AE `?P1`])
ultimately have "[p←drop (length ws) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1'') ws⇩2'. fst p ∈ S]"
using Y and `?P3'` by simp
hence "[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
by (rule small_steps_outputs [OF T U AE AH AI])
}
ultimately show
"ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f'
vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
using V by auto
qed
qed (insert L, auto simp: no_upd_empty)
qed
done
qed
apply (erule exE)+
apply (erule conjE)+
subgoal for p cfs' cfs''
proof -
assume "(c, s, f, vs⇩0, ws⇩0) →*{cfs'} (SKIP, p)"
moreover from this obtain s⇩1' and vs and ws where
Q: "p = (s⇩1', f, vs, ws)"
by (blast dest: small_stepsl_stream)
ultimately have
R: "(c, s, f, vs⇩0, ws⇩0) →*{cfs'} (SKIP, s⇩1', f, vs, ws)"
by simp
assume "(WHILE b DO c, p) →*{cfs''} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)"
with Q have S:
"(WHILE b DO c, s⇩1', f, vs, ws) →*{cfs''} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)"
by simp
assume "length cfs'' < length (tl cfs⇩1)"
hence "length (cfs'' @ cfs⇩2) < length (cfs⇩1 @ cfs⇩2)"
by simp
moreover have "cfs'' @ cfs⇩2 = cfs'' @ cfs⇩2" ..
moreover have "(c, s, f, vs⇩0, ws⇩0) ⇒ (s⇩1', f, vs, ws)"
using R by (auto dest: small_stepsl_steps simp: big_iff_small)
hence "s⇩1' ∈ Univ A (⊆ state ∩ X) ∪ Univ C (⊆ state ∩ Y)"
by (rule univ_states_while [OF _ G H I J K P N])
ultimately show ?thesis
using S and O by (rule M [rule_format])
qed
done
next
assume "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) = (SKIP, s, f, vs⇩0, ws⇩0)"
moreover from this have
"(c⇩2, s⇩2, f, vs⇩2, ws⇩2) = (SKIP, s⇩1, f, vs⇩1, ws⇩1) ∧ flow cfs⇩2 = []"
using O by (blast intro!: small_stepsl_skip)
ultimately show ?thesis
by (insert L, fastforce)
qed
qed
qed
lemma ctyping2_correct_aux:
"⟦(U, v) ⊨ c (⊆ A, X) = Some (B, Y); s ∈ Univ A (⊆ state ∩ X);
(c, s, f, vs⇩0, ws⇩0) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1);
(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)⟧ ⟹
ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 (flow cfs⇩2)"
apply (induction "(U, v)" c A X arbitrary: B Y U v c⇩1 c⇩2 s s⇩1 s⇩2
vs⇩0 vs⇩1 vs⇩2 ws⇩0 ws⇩1 ws⇩2 cfs⇩1 cfs⇩2 rule: ctyping2.induct)
apply fastforce
apply (erule ctyping2_correct_aux_assign, assumption+)
apply (erule ctyping2_correct_aux_input, assumption+)
apply (erule ctyping2_correct_aux_output, assumption+)
apply (erule ctyping2_correct_aux_seq, assumption+)
apply (erule ctyping2_correct_aux_or, assumption+)
apply (erule ctyping2_correct_aux_if, assumption+)
apply (erule ctyping2_correct_aux_while, assumption+)
done
theorem ctyping2_correct:
assumes A: "(U, v) ⊨ c (⊆ A, X) = Some (B, Y)"
shows "correct c A X"
proof (subst correct_def, clarify)
fix s t c⇩1 c⇩2 s⇩1 s⇩2 f vs vs⇩1 vs⇩2 ws ws⇩1 ws⇩2 cfs⇩2 t⇩1 f' vs⇩1' ws⇩1'
let ?cs = "flow cfs⇩2"
assume "t ∈ A" and "s = t (⊆ state ∩ X)"
hence "s ∈ Univ A (⊆ state ∩ X)"
by blast
moreover assume "(c, s, f, vs, ws) →* (c⇩1, s⇩1, f, vs⇩1, ws⇩1)"
then obtain cfs⇩1 where "(c, s, f, vs, ws) →*{cfs⇩1} (c⇩1, s⇩1, f, vs⇩1, ws⇩1)"
by (blast dest: small_steps_stepsl)
moreover assume "(c⇩1, s⇩1, f, vs⇩1, ws⇩1) →*{cfs⇩2} (c⇩2, s⇩2, f, vs⇩2, ws⇩2)"
ultimately have "ok_flow_aux U c⇩1 c⇩2 s⇩1 s⇩2 f vs⇩1 vs⇩2 ws⇩1 ws⇩2 ?cs"
by (rule ctyping2_correct_aux [OF A])
then obtain c⇩2' and t⇩2 and vs⇩2' and ws⇩2' where
"ok_flow_aux_1 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_aux_2 s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' ?cs ∧
ok_flow_aux_3 s⇩1 t⇩1 f f' vs⇩1 vs⇩1' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
(is "?P1 ∧ ?P2 ∧ ?P3")
by fastforce
hence ?P1 and ?P2 and ?P3 by auto
show "∃c⇩2' t⇩2 vs⇩2' ws⇩2'.
ok_flow_1 c⇩1 c⇩2 c⇩2' s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_2 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
proof (rule exI [of _ c⇩2'], rule exI [of _ t⇩2],
rule exI [of _ vs⇩2'], rule exI [of _ ws⇩2'])
{
fix S
assume
B: "S ≠ {}" and
C: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources ?cs vs⇩1 s⇩1 f x)}" and
D: "f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags ?cs vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have "∀x. sources_aux ?cs vs⇩1 s⇩1 f x ⊆ sources ?cs vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs vs⇩1 s⇩1 f x)}"
using C by blast
moreover have "⋃ {tags_aux ?cs vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags])
with D have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c⇩2 = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is ?Q)
using B and `?P1` by simp
moreover have "s⇩2 = t⇩2 (⊆ S)"
using B and C and D and `?P2` by simp
ultimately have "?Q ∧ ?this" ..
}
moreover {
fix S
assume
B: "S ≠ {}" and
C: "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_out ?cs vs⇩1 s⇩1 f x)}" and
D: "f = f' (⊆ vs⇩1, vs⇩1', ⋃ {tags_out ?cs vs⇩1 s⇩1 f x | x. x ∈ S})"
(is "_ = _ (⊆ _, _, ?T)")
have "∀x. sources_aux ?cs vs⇩1 s⇩1 f x ⊆ sources_out ?cs vs⇩1 s⇩1 f x"
by (blast intro: subsetD [OF sources_aux_sources_out])
hence "S ⊆ {x. s⇩1 = t⇩1 (⊆ sources_aux ?cs vs⇩1 s⇩1 f x)}"
using C by blast
moreover have "⋃ {tags_aux ?cs vs⇩1 s⇩1 f x | x. x ∈ S} ⊆ ?T"
(is "?T' ⊆ _")
by (blast intro: subsetD [OF tags_aux_tags_out])
with D have "f = f' (⊆ vs⇩1, vs⇩1', ?T')"
by (rule eq_streams_subset)
ultimately have
"(c⇩1, t⇩1, f', vs⇩1', ws⇩1') →* (c⇩2', t⇩2, f', vs⇩2', ws⇩2') ∧
(c⇩2 = SKIP) = (c⇩2' = SKIP) ∧
map fst [p←drop (length vs⇩1) vs⇩2. fst p ∈ S] =
map fst [p←drop (length vs⇩1') vs⇩2'. fst p ∈ S]"
(is ?Q)
using B and `?P1` by simp
moreover have
"[p←drop (length ws⇩1) ws⇩2. fst p ∈ S] =
[p←drop (length ws⇩1') ws⇩2'. fst p ∈ S]"
using B and C and D and `?P3` by simp
ultimately have "?Q ∧ ?this" ..
}
ultimately show
"ok_flow_1 c⇩1 c⇩2 c⇩2' s⇩1 s⇩2 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1' ws⇩2' ?cs ∧
ok_flow_2 c⇩1 c⇩2 c⇩2' s⇩1 t⇩1 t⇩2 f f' vs⇩1 vs⇩1' vs⇩2 vs⇩2' ws⇩1 ws⇩1' ws⇩2 ws⇩2' ?cs"
by auto
qed
qed
end
end