header {* Type System for Ensuring SIFUM-Security of Commands *}
theory TypeSystem
imports Main Preliminaries Security Language Compositionality
begin
subsection {* Typing Rules *}
type_synonym Type = Sec
type_synonym 'Var TyEnv = "'Var \<rightharpoonup> Type"
locale sifum_types =
sifum_lang ev⇩A ev⇩B + sifum_security dma Stop eval⇩w
for ev⇩A :: "('Var, 'Val) Mem => 'AExp => 'Val"
and ev⇩B :: "('Var, 'Val) Mem => 'BExp => bool"
context sifum_types
begin
abbreviation mm_equiv_abv2 :: "(_, _, _) LocalConf => (_, _, _) LocalConf => bool"
(infix "≈" 60)
where "mm_equiv_abv2 c c' ≡ mm_equiv_abv c c'"
abbreviation eval_abv2 :: "(_, 'Var, 'Val) LocalConf => (_, _, _) LocalConf => bool"
(infixl "\<leadsto>" 70)
where
"x \<leadsto> y ≡ (x, y) ∈ eval⇩w"
abbreviation low_indistinguishable_abv :: "'Var Mds => ('Var, 'AExp, 'BExp) Stmt => (_, _, _) Stmt => bool"
("_ ∼\<index> _" [100, 100] 80)
where
"c ∼⇘mds⇙ c' ≡ low_indistinguishable mds c c'"
definition to_total :: "'Var TyEnv => 'Var => Sec"
where "to_total Γ v ≡ if v ∈ dom Γ then the (Γ v) else dma v"
definition max_dom :: "Sec set => Sec"
where "max_dom xs ≡ if High ∈ xs then High else Low"
inductive type_aexpr :: "'Var TyEnv => 'AExp => Type => bool" ("_ \<turnstile>⇩a _ ∈ _" [120, 120, 120] 1000)
where
type_aexpr [intro!]: "Γ \<turnstile>⇩a e ∈ max_dom (image (λ x. to_total Γ x) (aexp_vars e))"
inductive_cases type_aexpr_elim [elim]: "Γ \<turnstile>⇩a e ∈ t"
inductive type_bexpr :: "'Var TyEnv => 'BExp => Type => bool" ("_ \<turnstile>⇩b _ ∈ _ " [120, 120, 120] 1000)
where
type_bexpr [intro!]: "Γ \<turnstile>⇩b e ∈ max_dom (image (λ x. to_total Γ x) (bexp_vars e))"
inductive_cases type_bexpr_elim [elim]: "Γ \<turnstile>⇩b e ∈ t"
definition mds_consistent :: "'Var Mds => 'Var TyEnv => bool"
where "mds_consistent mds Γ ≡
dom Γ = {(x :: 'Var). (dma x = Low ∧ x ∈ mds AsmNoRead) ∨
(dma x = High ∧ x ∈ mds AsmNoWrite)}"
fun add_anno_dom :: "'Var TyEnv => 'Var ModeUpd => 'Var set"
where
"add_anno_dom Γ (Acq v AsmNoRead) = (if dma v = Low then dom Γ ∪ {v} else dom Γ)" |
"add_anno_dom Γ (Acq v AsmNoWrite) = (if dma v = High then dom Γ ∪ {v} else dom Γ)" |
"add_anno_dom Γ (Acq v _) = dom Γ" |
"add_anno_dom Γ (Rel v AsmNoRead) = (if dma v = Low then dom Γ - {v} else dom Γ)" |
"add_anno_dom Γ (Rel v AsmNoWrite) = (if dma v = High then dom Γ - {v} else dom Γ)" |
"add_anno_dom Γ (Rel v _) = dom Γ"
definition add_anno :: "'Var TyEnv => 'Var ModeUpd => 'Var TyEnv" (infix "⊕" 60)
where
"Γ ⊕ upd = ((λx. Some (to_total Γ x)) |` add_anno_dom Γ upd)"
definition context_le :: "'Var TyEnv => 'Var TyEnv => bool" (infixr "\<sqsubseteq>⇩c" 100)
where
"Γ \<sqsubseteq>⇩c Γ' ≡ (dom Γ = dom Γ') ∧ (∀ x ∈ dom Γ. the (Γ x) \<sqsubseteq> the (Γ' x))"
inductive has_type :: "'Var TyEnv => ('Var, 'AExp, 'BExp) Stmt => 'Var TyEnv => bool"
("\<turnstile> _ {_} _" [120, 120, 120] 1000)
where
stop_type [intro]: "\<turnstile> Γ {Stop} Γ" |
skip_type [intro] : "\<turnstile> Γ {Skip} Γ" |
assign⇩1 : "[| x ∉ dom Γ ; Γ \<turnstile>⇩a e ∈ t; t \<sqsubseteq> dma x |] ==> \<turnstile> Γ {x \<leftarrow> e} Γ" |
assign⇩2 : "[| x ∈ dom Γ ; Γ \<turnstile>⇩a e ∈ t |] ==> has_type Γ (x \<leftarrow> e) (Γ (x := Some t))" |
if_type [intro]: "[| Γ \<turnstile>⇩b e ∈ High -->
((∀ mds. mds_consistent mds Γ --> (low_indistinguishable mds c⇩1 c⇩2)) ∧
(∀ x ∈ dom Γ'. Γ' x = Some High))
; \<turnstile> Γ { c⇩1 } Γ'
; \<turnstile> Γ { c⇩2 } Γ' |] ==>
\<turnstile> Γ { If e c⇩1 c⇩2 } Γ'" |
while_type [intro]: "[| Γ \<turnstile>⇩b e ∈ Low ; \<turnstile> Γ { c } Γ |] ==> \<turnstile> Γ { While e c } Γ" |
anno_type [intro]: "[| Γ' = Γ ⊕ upd ; \<turnstile> Γ' { c } Γ'' ; c ≠ Stop ;
∀ x. to_total Γ x \<sqsubseteq> to_total Γ' x |] ==> \<turnstile> Γ { c@[upd] } Γ''" |
seq_type [intro]: "[| \<turnstile> Γ { c⇩1 } Γ' ; \<turnstile> Γ' { c⇩2 } Γ'' |] ==> \<turnstile> Γ { c⇩1 ;; c⇩2 } Γ''" |
sub : "[| \<turnstile> Γ⇩1 { c } Γ⇩1' ; Γ⇩2 \<sqsubseteq>⇩c Γ⇩1 ; Γ⇩1' \<sqsubseteq>⇩c Γ⇩2' |] ==> \<turnstile> Γ⇩2 { c } Γ⇩2'"
subsection {* Typing Soundness *}
text {* The following predicate is needed to exclude some pathological
cases, that abuse the @{term Stop} command which is not allowed to
occur in actual programs. *}
fun has_annotated_stop :: "('Var, 'AExp, 'BExp) Stmt => bool"
where
"has_annotated_stop (c@[_]) = (if c = Stop then True else has_annotated_stop c)" |
"has_annotated_stop (Seq p q) = (has_annotated_stop p ∨ has_annotated_stop q)" |
"has_annotated_stop (If _ p q) = (has_annotated_stop p ∨ has_annotated_stop q)" |
"has_annotated_stop (While _ p) = has_annotated_stop p" |
"has_annotated_stop _ = False"
inductive_cases has_type_elim: "\<turnstile> Γ { c } Γ'"
inductive_cases has_type_stop_elim: "\<turnstile> Γ { Stop } Γ'"
definition tyenv_eq :: "'Var TyEnv => ('Var, 'Val) Mem => ('Var, 'Val) Mem => bool"
(infix "=\<index>" 60)
where "mem⇩1 =⇘Γ⇙ mem⇩2 ≡ ∀ x. (to_total Γ x = Low --> mem⇩1 x = mem⇩2 x)"
lemma tyenv_eq_sym: "mem⇩1 =⇘Γ⇙ mem⇩2 ==> mem⇩2 =⇘Γ⇙ mem⇩1"
by (auto simp: tyenv_eq_def)
inductive_set \<R>⇩1 :: "'Var TyEnv => (('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf rel"
and \<R>⇩1_abv :: "'Var TyEnv =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
bool" ("_ \<R>⇧1\<index> _" [120, 120] 1000)
for Γ' :: "'Var TyEnv"
where
"x \<R>⇧1⇘Γ⇙ y ≡ (x, y) ∈ \<R>⇩1 Γ" |
intro [intro!] : "[| \<turnstile> Γ { c } Γ' ; mds_consistent mds Γ ; mem⇩1 =⇘Γ⇙ mem⇩2 |] ==> 〈c, mds, mem⇩1〉 \<R>⇧1⇘Γ'⇙ 〈c, mds, mem⇩2〉"
inductive_set \<R>⇩2 :: "'Var TyEnv => (('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf rel"
and \<R>⇩2_abv :: "'Var TyEnv =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
bool" ("_ \<R>⇧2\<index> _" [120, 120] 1000)
for Γ' :: "'Var TyEnv"
where
"x \<R>⇧2⇘Γ⇙ y ≡ (x, y) ∈ \<R>⇩2 Γ" |
intro [intro!] : "[| 〈c⇩1, mds, mem⇩1〉 ≈ 〈c⇩2, mds, mem⇩2〉 ;
∀ x ∈ dom Γ'. Γ' x = Some High ;
\<turnstile> Γ⇩1 { c⇩1 } Γ' ; \<turnstile> Γ⇩2 { c⇩2 } Γ' ;
mds_consistent mds Γ⇩1 ; mds_consistent mds Γ⇩2 |] ==>
〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
inductive \<R>⇩3_aux :: "'Var TyEnv => (('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
bool" ("_ \<R>⇧3\<index> _" [120, 120] 1000)
and \<R>⇩3 :: "'Var TyEnv => (('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf rel"
where
"\<R>⇩3 Γ' ≡ {(lc⇩1, lc⇩2). \<R>⇩3_aux Γ' lc⇩1 lc⇩2}" |
intro⇩1 [intro] : "[| 〈c⇩1, mds, mem⇩1〉 \<R>⇧1⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉; \<turnstile> Γ { c } Γ' |] ==>
〈Seq c⇩1 c, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈Seq c⇩2 c, mds, mem⇩2〉" |
intro⇩2 [intro] : "[| 〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉; \<turnstile> Γ { c } Γ' |] ==>
〈Seq c⇩1 c, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈Seq c⇩2 c, mds, mem⇩2〉" |
intro⇩3 [intro] : "[| 〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉; \<turnstile> Γ { c } Γ' |] ==>
〈Seq c⇩1 c, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈Seq c⇩2 c, mds, mem⇩2〉"
definition weak_bisim :: "(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf rel =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf rel => bool"
where "weak_bisim \<T>⇩1 \<T> ≡ ∀ c⇩1 c⇩2 mds mem⇩1 mem⇩2 c⇩1' mds' mem⇩1'.
((〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds, mem⇩2〉) ∈ \<T>⇩1 ∧
(〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds', mem⇩1'〉)) -->
(∃ c⇩2' mem⇩2'. 〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧
(〈c⇩1', mds', mem⇩1'〉, 〈c⇩2', mds', mem⇩2'〉) ∈ \<T>)"
inductive_set \<R> :: "'Var TyEnv =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf rel"
and \<R>_abv :: "'Var TyEnv =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
bool" ("_ \<R>⇧u\<index> _" [120, 120] 1000)
for Γ :: "'Var TyEnv"
where
"x \<R>⇧u⇘Γ⇙ y ≡ (x, y) ∈ \<R> Γ" |
intro⇩1: "lc \<R>⇧1⇘Γ⇙ lc' ==> (lc, lc') ∈ \<R> Γ" |
intro⇩2: "lc \<R>⇧2⇘Γ⇙ lc' ==> (lc, lc') ∈ \<R> Γ" |
intro⇩3: "lc \<R>⇧3⇘Γ⇙ lc' ==> (lc, lc') ∈ \<R> Γ"
inductive_cases \<R>⇩1_elim [elim]: "〈c⇩1, mds, mem⇩1〉 \<R>⇧1⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉"
inductive_cases \<R>⇩2_elim [elim]: "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉"
inductive_cases \<R>⇩3_elim [elim]: "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉"
inductive_cases \<R>_elim [elim]: "(〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds, mem⇩2〉) ∈ \<R> Γ"
inductive_cases \<R>_elim': "(〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds⇩2, mem⇩2〉) ∈ \<R> Γ"
inductive_cases \<R>⇩1_elim' : "〈c⇩1, mds, mem⇩1〉 \<R>⇧1⇘Γ⇙ 〈c⇩2, mds⇩2, mem⇩2〉"
inductive_cases \<R>⇩2_elim' : "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ⇙ 〈c⇩2, mds⇩2, mem⇩2〉"
inductive_cases \<R>⇩3_elim' : "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ⇙ 〈c⇩2, mds⇩2, mem⇩2〉"
lemma \<R>⇩1_sym: "sym (\<R>⇩1 Γ)"
unfolding sym_def
apply auto
by (metis (no_types) \<R>⇩1.intro \<R>⇩1_elim' tyenv_eq_sym)
lemma \<R>⇩2_sym: "sym (\<R>⇩2 Γ)"
unfolding sym_def
apply clarify
by (metis (no_types) \<R>⇩2.intro \<R>⇩2_elim' mm_equiv_sym)
lemma \<R>⇩3_sym: "sym (\<R>⇩3 Γ)"
unfolding sym_def
proof (clarify)
fix c⇩1 mds mem⇩1 c⇩2 mds' mem⇩2
assume asm: "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ⇙ 〈c⇩2, mds', mem⇩2〉"
hence [simp]: "mds' = mds"
using \<R>⇩3_elim' by blast
from asm show "〈c⇩2, mds', mem⇩2〉 \<R>⇧3⇘Γ⇙ 〈c⇩1, mds, mem⇩1〉"
apply auto
apply (induct rule: \<R>⇩3_aux.induct)
apply (metis (lifting) \<R>⇩1_sym \<R>⇩3_aux.intro⇩1 symD)
apply (metis (lifting) \<R>⇩2_sym \<R>⇩3_aux.intro⇩2 symD)
by (metis (lifting) \<R>⇩3_aux.intro⇩3)
qed
lemma \<R>_mds [simp]: "〈c⇩1, mds, mem⇩1〉 \<R>⇧u⇘Γ⇙ 〈c⇩2, mds', mem⇩2〉 ==> mds = mds'"
apply (rule \<R>_elim')
apply (auto)
apply (metis \<R>⇩1_elim')
apply (metis \<R>⇩2_elim')
apply (insert \<R>⇩3_elim')
by blast
lemma \<R>_sym: "sym (\<R> Γ)"
unfolding sym_def
proof (clarify)
fix c⇩1 mds mem⇩1 c⇩2 mds⇩2 mem⇩2
assume asm: "(〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds⇩2, mem⇩2〉) ∈ \<R> Γ"
with \<R>_mds have [simp]: "mds⇩2 = mds"
by blast
from asm show "(〈c⇩2, mds⇩2, mem⇩2〉, 〈c⇩1, mds, mem⇩1〉) ∈ \<R> Γ"
using \<R>.intro⇩1 [of Γ] and \<R>.intro⇩2 [of Γ] and \<R>.intro⇩3 [of Γ]
using \<R>⇩1_sym [of Γ] and \<R>⇩2_sym [of Γ] and \<R>⇩3_sym [of Γ]
apply simp
apply (erule \<R>_elim)
by (auto simp: sym_def)
qed
lemma \<R>⇩1_closed_glob_consistent: "closed_glob_consistent (\<R>⇩1 Γ')"
unfolding closed_glob_consistent_def
proof (clarify)
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 x Γ'
assume R1: "〈c⇩1, mds, mem⇩1〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
hence [simp]: "c⇩2 = c⇩1" by blast
from R1 obtain Γ where Γ_props: "\<turnstile> Γ { c⇩1 } Γ'" "mem⇩1 =⇘Γ⇙ mem⇩2" "mds_consistent mds Γ"
by blast
hence "!! v. 〈c⇩1, mds, mem⇩1 (x := v)〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2 (x := v)〉"
by (auto simp: tyenv_eq_def mds_consistent_def)
moreover
from Γ_props have "!! v⇩1 v⇩2. [| dma x = High ; x ∉ mds AsmNoWrite |] ==>
〈c⇩1, mds, mem⇩1(x := v⇩1)〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2(x := v⇩2)〉"
apply (auto simp: mds_consistent_def tyenv_eq_def)
by (metis (lifting, full_types) Sec.simps(2) mem_Collect_eq to_total_def)
ultimately show
"(dma x = High ∧ x ∉ mds AsmNoWrite -->
(∀v⇩1 v⇩2. 〈c⇩1, mds, mem⇩1(x := v⇩1)〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2(x := v⇩2)〉))
∧
(dma x = Low ∧ x ∉ mds AsmNoWrite -->
(∀v. 〈c⇩1, mds, mem⇩1(x := v)〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2(x := v)〉))"
using intro⇩1
by auto
qed
lemma \<R>⇩2_closed_glob_consistent: "closed_glob_consistent (\<R>⇩2 Γ')"
unfolding closed_glob_consistent_def
proof (clarify)
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 x Γ'
assume R2: "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
then obtain Γ⇩1 Γ⇩2 where Γ_prop: "\<turnstile> Γ⇩1 { c⇩1 } Γ'" "\<turnstile> Γ⇩2 { c⇩2 } Γ'"
"mds_consistent mds Γ⇩1" "mds_consistent mds Γ⇩2"
by blast
from R2 have bisim: "〈c⇩1, mds, mem⇩1〉 ≈ 〈c⇩2, mds, mem⇩2〉"
by blast
then obtain \<R>' where \<R>'_prop: "(〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds, mem⇩2〉) ∈ \<R>' ∧ strong_low_bisim_mm \<R>'"
apply (rule mm_equiv_elim)
by (auto simp: strong_low_bisim_mm_def)
from \<R>'_prop have \<R>'_cons: "closed_glob_consistent \<R>'"
by (auto simp: strong_low_bisim_mm_def)
moreover
from Γ_prop and \<R>'_prop
have "!!mem⇩1 mem⇩2. (〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds, mem⇩2〉) ∈ \<R>' ==> 〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
using \<R>⇩2.intro [where Γ' = Γ' and Γ⇩1 = Γ⇩1 and Γ⇩2 = Γ⇩2]
using mm_equiv_intro and R2
by blast
ultimately show
"(dma x = High ∧ x ∉ mds AsmNoWrite -->
(∀v⇩1 v⇩2. 〈c⇩1, mds, mem⇩1(x := v⇩1)〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2(x := v⇩2)〉))
∧
(dma x = Low ∧ x ∉ mds AsmNoWrite -->
(∀v. 〈c⇩1, mds, mem⇩1(x := v)〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2(x := v)〉))"
using \<R>'_prop
unfolding closed_glob_consistent_def
by simp
qed
fun closed_glob_helper :: "'Var TyEnv => (('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf => (('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf => bool"
where
"closed_glob_helper Γ' 〈c⇩1, mds, mem⇩1〉 〈c⇩2, mds⇩2, mem⇩2〉 =
(∀ x. ((dma x = High ∧ x ∉ mds AsmNoWrite) -->
(∀ v⇩1 v⇩2. (〈 c⇩1, mds, mem⇩1 (x := v⇩1) 〉, 〈 c⇩2, mds, mem⇩2 (x := v⇩2) 〉) ∈ \<R>⇩3 Γ')) ∧
((dma x = Low ∧ x ∉ mds AsmNoWrite) -->
(∀ v. (〈 c⇩1, mds, mem⇩1 (x := v) 〉, 〈 c⇩2, mds, mem⇩2 (x := v) 〉) ∈ \<R>⇩3 Γ')))"
lemma \<R>⇩3_closed_glob_consistent:
assumes R3: "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
shows "∀ x.
(dma x = High ∧ x ∉ mds AsmNoWrite -->
(∀v⇩1 v⇩2. (〈c⇩1, mds, mem⇩1(x := v⇩1)〉, 〈c⇩2, mds, mem⇩2(x := v⇩2)〉) ∈ \<R>⇩3 Γ')) ∧
(dma x = Low ∧ x ∉ mds AsmNoWrite --> (∀v. (〈c⇩1, mds, mem⇩1(x := v)〉, 〈c⇩2, mds, mem⇩2(x := v)〉) ∈ \<R>⇩3 Γ'))"
proof -
from R3 have "closed_glob_helper Γ' 〈c⇩1, mds, mem⇩1〉 〈c⇩2, mds, mem⇩2〉"
proof (induct rule: \<R>⇩3_aux.induct)
case (intro⇩1 Γ c⇩1 mds mem⇩1 c⇩2 mem⇩2 c Γ')
thus ?case
using \<R>⇩1_closed_glob_consistent [of Γ] and \<R>⇩3_aux.intro⇩1
unfolding closed_glob_consistent_def
by (simp, blast)
next
case (intro⇩2 Γ c⇩1 mds mem⇩1 c⇩2 mem⇩2 c Γ')
thus ?case
using \<R>⇩2_closed_glob_consistent [of Γ] and \<R>⇩3_aux.intro⇩2
unfolding closed_glob_consistent_def
by (simp, blast)
next
case intro⇩3
thus ?case
using \<R>⇩3_aux.intro⇩3
by (simp, blast)
qed
thus ?thesis by simp
qed
lemma \<R>_closed_glob_consistent: "closed_glob_consistent (\<R> Γ')"
unfolding closed_glob_consistent_def
proof (clarify, erule \<R>_elim, simp_all)
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 x
assume R1: "〈c⇩1, mds, mem⇩1〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
with \<R>⇩1_closed_glob_consistent show
"(dma x = High ∧ x ∉ mds AsmNoWrite -->
(∀v⇩1 v⇩2. (〈c⇩1, mds, mem⇩1(x := v⇩1)〉, 〈c⇩2, mds, mem⇩2(x := v⇩2)〉) ∈ \<R> Γ')) ∧
(dma x = Low ∧ x ∉ mds AsmNoWrite -->
(∀v. (〈c⇩1, mds, mem⇩1(x := v)〉, 〈c⇩2, mds, mem⇩2(x := v)〉) ∈ \<R> Γ'))"
unfolding closed_glob_consistent_def
using intro⇩1
apply clarify
by metis
next
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 x
assume R2: "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
with \<R>⇩2_closed_glob_consistent show
"(dma x = High ∧ x ∉ mds AsmNoWrite -->
(∀v⇩1 v⇩2. (〈c⇩1, mds, mem⇩1(x := v⇩1)〉, 〈c⇩2, mds, mem⇩2(x := v⇩2)〉) ∈ \<R> Γ'))
∧
(dma x = Low ∧ x ∉ mds AsmNoWrite -->
(∀v. (〈c⇩1, mds, mem⇩1(x := v)〉, 〈c⇩2, mds, mem⇩2(x := v)〉) ∈ \<R> Γ'))"
unfolding closed_glob_consistent_def
using intro⇩2
apply clarify
by metis
next
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 x Γ'
assume R3: "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
thus
"(dma x = High ∧ x ∉ mds AsmNoWrite -->
(∀v⇩1 v⇩2. (〈c⇩1, mds, mem⇩1(x := v⇩1)〉, 〈c⇩2, mds, mem⇩2(x := v⇩2)〉) ∈ \<R> Γ'))
∧
(dma x = Low ∧ x ∉ mds AsmNoWrite -->
(∀v. (〈c⇩1, mds, mem⇩1(x := v)〉, 〈c⇩2, mds, mem⇩2(x := v)〉) ∈ \<R> Γ'))"
using \<R>⇩3_closed_glob_consistent
apply auto
apply (metis \<R>.intro⇩3)
by (metis (lifting) \<R>.intro⇩3)
qed
lemma type_low_vars_low:
assumes typed: "Γ \<turnstile>⇩a e ∈ Low"
assumes mds_cons: "mds_consistent mds Γ"
assumes x_in_vars: "x ∈ aexp_vars e"
shows "to_total Γ x = Low"
using assms
by (metis (full_types) Sec.exhaust imageI max_dom_def type_aexpr_elim)
lemma type_low_vars_low_b:
assumes typed : "Γ \<turnstile>⇩b e ∈ Low"
assumes mds_cons: "mds_consistent mds Γ"
assumes x_in_vars: "x ∈ bexp_vars e"
shows "to_total Γ x = Low"
using assms
by (metis (full_types) Sec.exhaust imageI max_dom_def type_bexpr.simps)
lemma mode_update_add_anno:
"mds_consistent mds Γ ==> mds_consistent (update_modes upd mds) (Γ ⊕ upd)"
apply (induct arbitrary: Γ rule: add_anno_dom.induct)
by (auto simp: add_anno_def mds_consistent_def)
lemma context_le_trans: "[| Γ \<sqsubseteq>⇩c Γ' ; Γ' \<sqsubseteq>⇩c Γ'' |] ==> Γ \<sqsubseteq>⇩c Γ''"
apply (auto simp: context_le_def)
by (metis domI order_trans the.simps)
lemma context_le_refl [simp]: "Γ \<sqsubseteq>⇩c Γ"
by (metis context_le_def order_refl)
lemma stop_cxt :
"[| \<turnstile> Γ { c } Γ' ; c = Stop |] ==> Γ \<sqsubseteq>⇩c Γ'"
apply (induct rule: has_type.induct)
apply auto
by (metis context_le_trans)
lemma preservation:
assumes typed: "\<turnstile> Γ { c } Γ'"
assumes eval: "〈c, mds, mem〉 \<leadsto> 〈c', mds', mem'〉"
shows "∃ Γ''. (\<turnstile> Γ'' { c' } Γ') ∧ (mds_consistent mds Γ --> mds_consistent mds' Γ'')"
using typed eval
proof (induct arbitrary: c' mds rule: has_type.induct)
case (anno_type Γ'' Γ upd c⇩1 Γ')
hence "〈c⇩1, update_modes upd mds, mem〉 \<leadsto> 〈c', mds', mem'〉"
by (metis upd_elim)
with anno_type(3) obtain Γ''' where
"\<turnstile> Γ''' { c' } Γ' ∧ (mds_consistent (update_modes upd mds) Γ'' -->
mds_consistent mds' Γ''')"
by auto
moreover
have "mds_consistent mds Γ --> mds_consistent (update_modes upd mds) Γ''"
using anno_type
apply auto
by (metis mode_update_add_anno)
ultimately show ?case
by blast
next
case stop_type
with stop_no_eval show ?case ..
next
case skip_type
hence "c' = Stop ∧ mds' = mds"
by (metis skip_elim)
thus ?case
by (metis stop_type)
next
case (assign⇩1 x Γ e t c' mds)
hence "c' = Stop ∧ mds' = mds"
by (metis assign_elim)
thus ?case
by (metis stop_type)
next
case (assign⇩2 x Γ e t c' mds)
hence "c' = Stop ∧ mds' = mds"
by (metis assign_elim)
thus ?case
apply (rule_tac x = "Γ (x \<mapsto> t)" in exI)
apply (auto simp: mds_consistent_def)
apply (metis Sec.exhaust)
apply (metis (lifting, full_types) CollectD domI local.assign⇩2(1))
apply (metis (lifting, full_types) CollectD domI local.assign⇩2(1))
apply (metis (lifting) CollectE domI local.assign⇩2(1))
apply (metis (lifting, full_types) domD mem_Collect_eq)
by (metis (lifting, full_types) domD mem_Collect_eq)
next
case (if_type Γ e th el Γ' c' mds)
thus ?case
apply (rule_tac x = Γ in exI)
by force
next
case (while_type Γ e c c' mds)
hence [simp]: "mds' = mds ∧ c' = If e (c ;; While e c) Stop"
by (metis while_elim)
thus ?case
apply (rule_tac x = Γ in exI)
apply auto
by (metis Sec.simps(2) has_type.while_type if_type local.while_type(1) local.while_type(2) seq_type stop_type type_bexpr_elim)
next
case (seq_type Γ c⇩1 Γ⇩1 c⇩2 Γ⇩2 c' mds)
thus ?case
proof (cases "c⇩1 = Stop")
assume [simp]: "c⇩1 = Stop"
with seq_type have [simp]: "mds' = mds ∧ c' = c⇩2"
by (metis seq_stop_elim)
thus ?case
apply auto
by (metis (lifting) `c⇩1 = Stop` context_le_refl local.seq_type(1) local.seq_type(3) stop_cxt sub)
next
assume "c⇩1 ≠ Stop"
then obtain c⇩1' where "〈c⇩1, mds, mem〉 \<leadsto> 〈c⇩1', mds', mem'〉 ∧ c' = (c⇩1' ;; c⇩2)"
by (metis seq_elim seq_type.prems)
then obtain Γ''' where "\<turnstile> Γ''' {c⇩1'} Γ⇩1 ∧
(mds_consistent mds Γ --> mds_consistent mds' Γ''')"
using seq_type(2)
by auto
moreover
from seq_type have "\<turnstile> Γ⇩1 { c⇩2 } Γ⇩2" by auto
moreover
ultimately show ?case
apply (rule_tac x = Γ''' in exI)
by (metis (lifting) `〈c⇩1, mds, mem〉 \<leadsto> 〈c⇩1', mds', mem'〉 ∧ c' = c⇩1' ;; c⇩2` has_type.seq_type)
qed
next
case (sub Γ⇩1 c Γ⇩1' Γ⇩2 Γ⇩2' c' mds)
then obtain Γ'' where "\<turnstile> Γ'' { c' } Γ⇩1' ∧
(mds_consistent mds Γ⇩1 --> mds_consistent mds' Γ'')"
by auto
thus ?case
apply (rule_tac x = Γ'' in exI)
apply (rule conjI)
apply (metis (lifting) has_type.sub local.sub(4) stop_cxt stop_type)
apply (simp add: mds_consistent_def)
by (metis context_le_def sub.hyps(3))
qed
lemma \<R>⇩1_mem_eq: "〈c⇩1, mds, mem⇩1〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉 ==> mem⇩1 =⇘mds⇙⇧l mem⇩2"
apply (rule \<R>⇩1_elim)
apply (auto simp: tyenv_eq_def mds_consistent_def to_total_def)
by (metis (lifting) Sec.simps(1) low_mds_eq_def)
lemma \<R>⇩2_mem_eq: "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉 ==> mem⇩1 =⇘mds⇙⇧l mem⇩2"
apply (rule \<R>⇩2_elim)
by (auto simp: mm_equiv_elim strong_low_bisim_mm_def)
fun bisim_helper :: "(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf =>
(('Var, 'AExp, 'BExp) Stmt, 'Var, 'Val) LocalConf => bool"
where
"bisim_helper 〈c⇩1, mds, mem⇩1〉 〈c⇩2, mds⇩2, mem⇩2〉 = mem⇩1 =⇘mds⇙⇧l mem⇩2"
lemma \<R>⇩3_mem_eq: "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉 ==> mem⇩1 =⇘mds⇙⇧l mem⇩2"
apply (subgoal_tac "bisim_helper 〈c⇩1, mds, mem⇩1〉 〈c⇩2, mds, mem⇩2〉")
apply simp
apply (induct rule: \<R>⇩3_aux.induct)
by (auto simp: \<R>⇩1_mem_eq \<R>⇩2_mem_eq)
lemma \<R>⇩2_bisim_step:
assumes case2: "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
assumes eval: "〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds', mem⇩1'〉"
shows "∃ c⇩2' mem⇩2'. 〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧ 〈c⇩1', mds', mem⇩1'〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2', mds', mem⇩2'〉"
proof -
from case2 have aux: "〈c⇩1, mds, mem⇩1〉 ≈ 〈c⇩2, mds, mem⇩2〉" "∀ x ∈ dom Γ'. Γ' x = Some High"
by (rule \<R>⇩2_elim, auto)
with eval obtain c⇩2' mem⇩2' where c⇩2'_props:
"〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧
〈c⇩1', mds', mem⇩1'〉 ≈ 〈c⇩2', mds', mem⇩2'〉"
using mm_equiv_strong_low_bisim strong_low_bisim_mm_def
by metis
from case2 obtain Γ⇩1 Γ⇩2 where "\<turnstile> Γ⇩1 { c⇩1 } Γ'" "\<turnstile> Γ⇩2 { c⇩2 } Γ'"
"mds_consistent mds Γ⇩1" "mds_consistent mds Γ⇩2"
by (metis \<R>⇩2_elim')
with preservation and c⇩2'_props obtain Γ⇩1' Γ⇩2' where
"\<turnstile> Γ⇩1' {c⇩1'} Γ'" "mds_consistent mds' Γ⇩1'"
"\<turnstile> Γ⇩2' {c⇩2'} Γ'" "mds_consistent mds' Γ⇩2'"
using eval
by metis
with c⇩2'_props show ?thesis
using \<R>⇩2.intro aux(2) c⇩2'_props
by blast
qed
lemma \<R>⇩2_weak_bisim:
"weak_bisim (\<R>⇩2 Γ') (\<R> Γ')"
unfolding weak_bisim_def
using \<R>.intro⇩2
apply auto
by (metis \<R>⇩2_bisim_step)
lemma \<R>⇩2_bisim: "strong_low_bisim_mm (\<R>⇩2 Γ')"
unfolding strong_low_bisim_mm_def
by (auto simp: \<R>⇩2_sym \<R>⇩2_closed_glob_consistent \<R>⇩2_mem_eq \<R>⇩2_bisim_step)
lemma annotated_no_stop: "[| ¬ has_annotated_stop (c@[upd]) |] ==> ¬ has_annotated_stop c"
apply (cases c)
by auto
lemma typed_no_annotated_stop:
"[| \<turnstile> Γ { c } Γ' |] ==> ¬ has_annotated_stop c"
by (induct rule: has_type.induct, auto)
lemma not_stop_eval:
"[| c ≠ Stop ; ¬ has_annotated_stop c |] ==>
∀ mds mem. ∃ c' mds' mem'. 〈c, mds, mem〉 \<leadsto> 〈c', mds', mem'〉"
proof (induct)
case (Assign x exp)
thus ?case
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.assign eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
next
case Skip
thus ?case
by (metis cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.skip)
next
case (ModeDecl c mu)
hence "¬ has_annotated_stop c ∧ c ≠ Stop"
by (metis has_annotated_stop.simps(1))
with ModeDecl show ?case
apply (clarify, rename_tac mds mem)
apply simp
apply (erule_tac x = "update_modes mu mds" in allE)
apply (erule_tac x = mem in allE)
apply (erule exE)+
by (metis cxt_to_stmt.simps(1) eval⇩w.decl)
next
case (Seq c⇩1 c⇩2)
thus ?case
proof (cases "c⇩1 = Stop")
assume "c⇩1 = Stop"
thus ?case
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.seq_stop eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
next
assume "c⇩1 ≠ Stop"
with Seq show ?case
by (metis eval⇩w.seq has_annotated_stop.simps(2))
qed
next
case (If bexp c⇩1 c⇩2)
thus ?case
apply (clarify, rename_tac mds mem)
apply (case_tac "ev⇩B mem bexp")
apply (metis cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.if_true)
by (metis cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.if_false)
next
case (While bexp c)
thus ?case
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.while eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
next
case Stop
thus ?case by blast
qed
lemma stop_bisim:
assumes bisim: "〈Stop, mds, mem⇩1〉 ≈ 〈c, mds, mem⇩2〉"
assumes typeable: "\<turnstile> Γ { c } Γ'"
shows "c = Stop"
proof (rule ccontr)
let ?lc⇩1 = "〈Stop, mds, mem⇩1〉" and
?lc⇩2 = "〈c, mds, mem⇩2〉"
assume "c ≠ Stop"
from typeable have "¬ has_annotated_stop c"
by (metis typed_no_annotated_stop)
with `c ≠ Stop` obtain c' mds' mem⇩2' where "?lc⇩2 \<leadsto> 〈c', mds', mem⇩2'〉"
using not_stop_eval
by blast
moreover
from bisim have "?lc⇩2 ≈ ?lc⇩1"
by (metis mm_equiv_sym)
ultimately obtain c⇩1' mds⇩1' mem⇩1'
where "〈Stop, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds⇩1', mem⇩1'〉"
using mm_equiv_strong_low_bisim
unfolding strong_low_bisim_mm_def
by blast
thus False
by (metis (lifting) stop_no_eval)
qed
lemma \<R>_typed_step:
"[| \<turnstile> Γ { c⇩1 } Γ' ;
mds_consistent mds Γ ;
mem⇩1 =⇘Γ⇙ mem⇩2 ;
〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds', mem⇩1'〉 |] ==>
(∃ c⇩2' mem⇩2'. 〈c⇩1, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧
〈c⇩1', mds', mem⇩1'〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2', mds', mem⇩2'〉)"
proof (induct arbitrary: mds c⇩1' rule: has_type.induct)
case (seq_type Γ c⇩1 Γ'' c⇩2 Γ' mds)
show ?case
proof (cases "c⇩1 = Stop")
assume "c⇩1 = Stop"
hence [simp]: "c⇩1' = c⇩2" "mds' = mds" "mem⇩1' = mem⇩1"
using seq_type
by (auto simp: seq_stop_elim)
from seq_type `c⇩1 = Stop` have "Γ \<sqsubseteq>⇩c Γ''"
by (metis stop_cxt)
hence "\<turnstile> Γ { c⇩2 } Γ'"
by (metis context_le_refl local.seq_type(3) sub)
have "〈c⇩2, mds, mem⇩1〉 \<R>⇧1⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
apply (rule \<R>⇩1.intro [of Γ])
by (auto simp: seq_type `\<turnstile> Γ { c⇩2 } Γ'`)
thus ?case
using \<R>.intro⇩1
apply clarify
apply (rule_tac x = c⇩2 in exI)
apply (rule_tac x = mem⇩2 in exI)
apply (auto simp: `c⇩1 = Stop`)
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.seq_stop eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
next
assume "c⇩1 ≠ Stop"
with `〈c⇩1 ;; c⇩2, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds', mem⇩1'〉` obtain c⇩1'' where c⇩1''_props:
"〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1'', mds', mem⇩1'〉 ∧ c⇩1' = c⇩1'' ;; c⇩2"
by (metis seq_elim)
with seq_type(2) obtain c⇩2'' mem⇩2' where c⇩2''_props:
"〈c⇩1, mds, mem⇩2〉 \<leadsto> 〈c⇩2'', mds', mem⇩2'〉 ∧ 〈c⇩1'', mds', mem⇩1'〉 \<R>⇧u⇘Γ''⇙ 〈c⇩2'', mds', mem⇩2'〉"
by (metis local.seq_type(5) local.seq_type(6))
hence "〈c⇩1'' ;; c⇩2, mds', mem⇩1'〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2'' ;; c⇩2, mds', mem⇩2'〉"
apply (rule conjE)
apply (erule \<R>_elim, auto)
apply (metis \<R>.intro⇩3 \<R>⇩3_aux.intro⇩1 local.seq_type(3))
apply (metis \<R>.intro⇩3 \<R>⇩3_aux.intro⇩2 local.seq_type(3))
by (metis \<R>.intro⇩3 \<R>⇩3_aux.intro⇩3 local.seq_type(3))
moreover
from c⇩2''_props have "〈c⇩1 ;; c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2'' ;; c⇩2, mds', mem⇩2'〉"
by (metis eval⇩w.seq)
ultimately show ?case
by (metis c⇩1''_props)
qed
next
case (anno_type Γ' Γ upd c Γ'' mds)
have "mem⇩1 =⇘Γ'⇙ mem⇩2"
by (metis less_eq_Sec_def local.anno_type(5) local.anno_type(7) tyenv_eq_def)
have "mds_consistent (update_modes upd mds) Γ'"
by (metis (lifting) local.anno_type(1) local.anno_type(6) mode_update_add_anno)
then obtain c⇩2' mem⇩2' where "(〈c, update_modes upd mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧
〈c⇩1', mds', mem⇩1'〉 \<R>⇧u⇘Γ''⇙ 〈c⇩2', mds', mem⇩2'〉)"
using anno_type
apply auto
by (metis `mem⇩1 =⇘Γ'⇙ mem⇩2` local.anno_type(1) upd_elim)
thus ?case
apply (rule_tac x = c⇩2' in exI)
apply (rule_tac x = mem⇩2' in exI)
apply auto
by (metis cxt_to_stmt.simps(1) eval⇩w.decl)
next
case stop_type
with stop_no_eval show ?case by auto
next
case (skip_type Γ mds)
moreover
with skip_type have [simp]: "mds' = mds" "c⇩1' = Stop" "mem⇩1' = mem⇩1"
using skip_elim
by (metis, metis, metis)
with skip_type have "〈Stop, mds, mem⇩1〉 \<R>⇧1⇘Γ⇙ 〈Stop, mds, mem⇩2〉"
by auto
thus ?case
using \<R>.intro⇩1 and unannotated [where c = Skip and E = "[]"]
apply auto
by (metis eval⇩w_simple.skip)
next
case (assign⇩1 x Γ e t mds)
hence [simp]: "c⇩1' = Stop" "mds' = mds" "mem⇩1' = mem⇩1 (x := ev⇩A mem⇩1 e)"
using assign_elim
by (auto, metis)
have "mem⇩1 (x := ev⇩A mem⇩1 e) =⇘Γ⇙ mem⇩2 (x := ev⇩A mem⇩2 e)"
proof (cases "to_total Γ x")
assume "to_total Γ x = High"
thus ?thesis
using assign⇩1 tyenv_eq_def
by auto
next
assume "to_total Γ x = Low"
with assign⇩1 have [simp]: "t = Low"
by (metis less_eq_Sec_def to_total_def)
hence "dma x = Low"
using assign⇩1 `to_total Γ x = Low`
by (metis to_total_def)
with assign⇩1 have "∀ v ∈ aexp_vars e. to_total Γ v = Low"
using type_low_vars_low
by auto
thus ?thesis
using eval_vars_det⇩A
apply (auto simp: tyenv_eq_def)
apply (metis (no_types) local.assign⇩1(5) tyenv_eq_def)
by (metis local.assign⇩1(5) tyenv_eq_def)
qed
hence "〈x \<leftarrow> e, mds, mem⇩2〉 \<leadsto> 〈Stop, mds', mem⇩2 (x := ev⇩A mem⇩2 e)〉"
"〈Stop, mds', mem⇩1 (x := ev⇩A mem⇩1 e)〉 \<R>⇧u⇘Γ⇙ 〈Stop, mds', mem⇩2 (x := ev⇩A mem⇩2 e)〉"
apply auto
apply (metis cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.assign)
by (rule \<R>.intro⇩1, auto simp: assign⇩1)
thus ?case
using `c⇩1' = Stop` and `mem⇩1' = mem⇩1 (x := ev⇩A mem⇩1 e)`
by blast
next
case (assign⇩2 x Γ e t mds)
hence [simp]: "c⇩1' = Stop" "mds' = mds" "mem⇩1' = mem⇩1 (x := ev⇩A mem⇩1 e)"
using assign_elim assign⇩2
by (auto, metis)
let ?Γ' = "Γ (x \<mapsto> t)"
have "〈x \<leftarrow> e, mds, mem⇩2〉 \<leadsto> 〈Stop, mds, mem⇩2 (x := ev⇩A mem⇩2 e)〉"
using assign⇩2
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.assign eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
moreover
have "〈Stop, mds, mem⇩1 (x := ev⇩A mem⇩1 e)〉 \<R>⇧1⇘?Γ'⇙ 〈Stop, mds, mem⇩2 (x := ev⇩A mem⇩2 e)〉"
proof (auto)
from assign⇩2 show "mds_consistent mds ?Γ'"
apply (simp add: mds_consistent_def)
by (metis (lifting) insert_absorb local.assign⇩2(1))
next
show "mem⇩1 (x := ev⇩A mem⇩1 e) =⇘?Γ'⇙ mem⇩2 (x := ev⇩A mem⇩2 e)"
unfolding tyenv_eq_def
proof (auto)
assume "to_total (Γ(x \<mapsto> t)) x = Low"
with `Γ \<turnstile>⇩a e ∈ t` have "!! x. x ∈ aexp_vars e ==> to_total Γ x = Low"
by (metis assign⇩2.prems(1) domI fun_upd_same the.simps to_total_def type_low_vars_low)
thus "ev⇩A mem⇩1 e = ev⇩A mem⇩2 e"
by (metis assign⇩2.prems(2) eval_vars_det⇩A tyenv_eq_def)
next
fix y
assume "y ≠ x" and "to_total (Γ (x \<mapsto> t)) y = Low"
thus "mem⇩1 y = mem⇩2 y"
by (metis (full_types) assign⇩2.prems(2) domD domI fun_upd_other to_total_def tyenv_eq_def)
qed
qed
ultimately have "〈x \<leftarrow> e, mds, mem⇩2〉 \<leadsto> 〈Stop, mds', mem⇩2 (x := ev⇩A mem⇩2 e)〉"
"〈Stop, mds', mem⇩1 (x := ev⇩A mem⇩1 e)〉 \<R>⇧u⇘Γ(x \<mapsto> t)⇙ 〈Stop, mds', mem⇩2 (x := ev⇩A mem⇩2 e)〉"
using \<R>.intro⇩1
by auto
thus ?case
using `mds' = mds` `c⇩1' = Stop` `mem⇩1' = mem⇩1(x := ev⇩A mem⇩1 e)`
by blast
next
case (if_type Γ e th el Γ')
have "(〈c⇩1', mds, mem⇩1〉, 〈c⇩1', mds, mem⇩2〉) ∈ \<R> Γ'"
apply (rule intro⇩1)
apply clarify
apply (rule \<R>⇩1.intro [where Γ = Γ and Γ' = Γ'])
apply (auto simp: if_type)
by (metis (lifting) if_elim local.if_type(2) local.if_type(4) local.if_type(8))
have eq_condition: "ev⇩B mem⇩1 e = ev⇩B mem⇩2 e ==> ?case"
proof -
assume "ev⇩B mem⇩1 e = ev⇩B mem⇩2 e"
with if_type(8) have "(〈If e th el, mds, mem⇩2〉 \<leadsto> 〈c⇩1', mds, mem⇩2〉)"
apply (cases "ev⇩B mem⇩1 e")
apply (subgoal_tac "c⇩1' = th")
apply clarify
apply (metis cxt_to_stmt.simps(1) eval⇩w_simplep.if_true eval⇩wp.unannotated eval⇩wp_eval⇩w_eq local.if_type(8))
apply (metis if_elim local.if_type(8))
apply (subgoal_tac "c⇩1' = el")
apply (metis (hide_lams, mono_tags) cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.if_false local.if_type(8))
by (metis if_elim local.if_type(8))
thus ?thesis
by (metis `〈c⇩1', mds, mem⇩1〉 \<R>⇧u⇘Γ'⇙ 〈c⇩1', mds, mem⇩2〉` if_elim local.if_type(8))
qed
have "mem⇩1 =⇘mds⇙⇧l mem⇩2"
apply (auto simp: low_mds_eq_def mds_consistent_def)
apply (subgoal_tac "x ∉ dom Γ")
apply (metis local.if_type(7) to_total_def tyenv_eq_def)
by (metis (lifting, mono_tags) CollectD Sec.simps(2) local.if_type(6) mds_consistent_def)
obtain t where "Γ \<turnstile>⇩b e ∈ t"
by (metis type_bexpr.intros)
from if_type show ?case
proof (cases t)
assume "t = High"
with if_type show ?thesis
proof (cases "ev⇩B mem⇩1 e = ev⇩B mem⇩2 e")
assume "ev⇩B mem⇩1 e = ev⇩B mem⇩2 e"
with eq_condition show ?thesis by auto
next
assume neq: "ev⇩B mem⇩1 e ≠ ev⇩B mem⇩2 e"
from if_type `t = High` have "th ∼⇘mds⇙ el"
by (metis `Γ \<turnstile>⇩b e ∈ t`)
from neq show ?thesis
proof (cases "ev⇩B mem⇩1 e")
assume "ev⇩B mem⇩1 e"
hence "c⇩1' = th"
by (metis (lifting) if_elim local.if_type(8))
hence "〈If e th el, mds, mem⇩2〉 \<leadsto> 〈el, mds, mem⇩2〉"
by (metis `ev⇩B mem⇩1 e` cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.if_false local.if_type(8) neq)
moreover
with `mem⇩1 =⇘mds⇙⇧l mem⇩2` have "〈th, mds, mem⇩1〉 ≈ 〈el, mds, mem⇩2〉"
by (metis low_indistinguishable_def `th ∼⇘mds⇙ el`)
have "∀ x ∈ dom Γ'. Γ' x = Some High"
using if_type `t = High`
by (metis `Γ \<turnstile>⇩b e ∈ t`)
have "〈th, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈el, mds, mem⇩2〉"
by (metis (lifting) \<R>⇩2.intro `∀x∈dom Γ'. Γ' x = Some High` `〈th, mds, mem⇩1〉 ≈ 〈el, mds, mem⇩2〉` local.if_type(2) local.if_type(4) local.if_type(6))
ultimately show ?thesis
using \<R>.intro⇩2
apply clarify
by (metis `c⇩1' = th` if_elim local.if_type(8))
next
assume "¬ ev⇩B mem⇩1 e"
hence [simp]: "c⇩1' = el"
by (metis (lifting) if_type(8) if_elim)
hence "〈If e th el, mds, mem⇩2〉 \<leadsto> 〈th, mds, mem⇩2〉"
by (metis (hide_lams, mono_tags) `¬ ev⇩B mem⇩1 e` cxt_to_stmt.simps(1) eval⇩w.unannotated eval⇩w_simple.if_true local.if_type(8) neq)
moreover
from `th ∼⇘mds⇙ el` have "el ∼⇘mds⇙ th"
by (metis low_indistinguishable_sym)
with `mem⇩1 =⇘mds⇙⇧l mem⇩2` have "〈el, mds, mem⇩1〉 ≈ 〈th, mds, mem⇩2〉"
by (metis low_indistinguishable_def)
have "∀ x ∈ dom Γ'. Γ' x = Some High"
using if_type `t = High`
by (metis `Γ \<turnstile>⇩b e ∈ t`)
have "〈el, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈th, mds, mem⇩2〉"
apply (rule \<R>⇩2.intro [where Γ⇩1 = Γ and Γ⇩2 = Γ])
by (auto simp: if_type `〈el, mds, mem⇩1〉 ≈ 〈th, mds, mem⇩2〉` `∀ x ∈ dom Γ'. Γ' x = Some High`)
ultimately show ?thesis
using \<R>.intro⇩2
apply clarify
by (metis `c⇩1' = el` if_elim local.if_type(8))
qed
qed
next
assume "t = Low"
with if_type have "ev⇩B mem⇩1 e = ev⇩B mem⇩2 e"
using eval_vars_det⇩B
apply (simp add: tyenv_eq_def `Γ \<turnstile>⇩b e ∈ t` type_low_vars_low_b)
by (metis (lifting) `Γ \<turnstile>⇩b e ∈ t` type_low_vars_low_b)
with eq_condition show ?thesis by auto
qed
next
case (while_type Γ e c)
hence [simp]: "c⇩1' = (If e (c ;; While e c) Stop)" and
[simp]: "mds' = mds" and
[simp]: "mem⇩1' = mem⇩1"
by (auto simp: while_elim)
with while_type have "〈While e c, mds, mem⇩2〉 \<leadsto> 〈c⇩1', mds, mem⇩2〉"
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.while eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
moreover
have "〈c⇩1', mds, mem⇩1〉 \<R>⇧1⇘Γ⇙ 〈c⇩1', mds, mem⇩2〉"
apply (rule \<R>⇩1.intro [where Γ = Γ])
apply (auto simp: while_type)
apply (rule if_type)
apply (metis (lifting) Sec.simps(1) local.while_type(1) type_bexpr_elim)
apply (rule seq_type [where Γ' = Γ])
by (auto simp: while_type)
ultimately show ?case
using \<R>.intro⇩1 [of Γ]
by (auto, blast)
next
case (sub Γ⇩1 c Γ⇩1' Γ Γ' mds c⇩1')
hence "dom Γ⇩1 ⊆ dom Γ" "dom Γ' ⊆ dom Γ⇩1'"
apply (metis (lifting) context_le_def equalityE)
by (metis context_le_def local.sub(4) order_refl)
hence "mds_consistent mds Γ⇩1"
using sub
apply (auto simp: mds_consistent_def)
apply (metis (lifting, full_types) context_le_def domD mem_Collect_eq)
by (metis (lifting, full_types) context_le_def domD mem_Collect_eq)
moreover have "mem⇩1 =⇘Γ⇩1⇙ mem⇩2"
unfolding tyenv_eq_def
by (metis (lifting, no_types) context_le_def less_eq_Sec_def sub.hyps(3) sub.prems(2) to_total_def tyenv_eq_def)
ultimately obtain c⇩2' mem⇩2' where c⇩2'_props: "〈c, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉"
"〈c⇩1', mds', mem⇩1'〉 \<R>⇧u⇘Γ⇩1'⇙ 〈c⇩2', mds', mem⇩2'〉"
using sub
by blast
moreover
have "!! c⇩1 mds mem⇩1 c⇩2 mem⇩2. 〈c⇩1, mds, mem⇩1〉 \<R>⇧u⇘Γ⇩1'⇙ 〈c⇩2, mds, mem⇩2〉 ==>
〈c⇩1, mds, mem⇩1〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
proof -
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2
let ?lc⇩1 = "〈c⇩1, mds, mem⇩1〉" and ?lc⇩2 = "〈c⇩2, mds, mem⇩2〉"
assume asm: "?lc⇩1 \<R>⇧u⇘Γ⇩1'⇙ ?lc⇩2"
moreover
have "?lc⇩1 \<R>⇧1⇘Γ⇩1'⇙ ?lc⇩2 ==> ?lc⇩1 \<R>⇧1⇘Γ'⇙ ?lc⇩2"
apply (erule \<R>⇩1_elim)
apply auto
by (metis (lifting) has_type.sub local.sub(4) stop_cxt stop_type)
moreover
have "?lc⇩1 \<R>⇧2⇘Γ⇩1'⇙ ?lc⇩2 ==> ?lc⇩1 \<R>⇧2⇘Γ'⇙ ?lc⇩2"
proof -
assume r2: "?lc⇩1 \<R>⇧2⇘Γ⇩1'⇙ ?lc⇩2"
then obtain Λ⇩1 Λ⇩2 where "\<turnstile> Λ⇩1 { c⇩1 } Γ⇩1'" "\<turnstile> Λ⇩2 { c⇩2 } Γ⇩1'" "mds_consistent mds Λ⇩1"
"mds_consistent mds Λ⇩2"
by (metis \<R>⇩2_elim)
hence "\<turnstile> Λ⇩1 { c⇩1 } Γ'"
using sub(4)
by (metis context_le_refl has_type.sub local.sub(4))
moreover
have "\<turnstile> Λ⇩2 { c⇩2 } Γ'"
by (metis `\<turnstile> Λ⇩2 {c⇩2} Γ⇩1'` context_le_refl has_type.sub local.sub(4))
moreover
from r2 have "∀ x ∈ dom Γ⇩1'. Γ⇩1' x = Some High"
apply (rule \<R>⇩2_elim)
by auto
hence "∀ x ∈ dom Γ'. Γ' x = Some High"
by (metis Sec.simps(2) `dom Γ' ⊆ dom Γ⇩1'` context_le_def domD less_eq_Sec_def local.sub(4) set_rev_mp the.simps)
ultimately show ?thesis
by (metis (no_types) \<R>⇩2.intro \<R>⇩2_elim' `mds_consistent mds Λ⇩1` `mds_consistent mds Λ⇩2` r2)
qed
moreover
have "?lc⇩1 \<R>⇧3⇘Γ⇩1'⇙ ?lc⇩2 ==> ?lc⇩1 \<R>⇧3⇘Γ'⇙ ?lc⇩2"
apply (erule \<R>⇩3_elim)
proof -
fix Γ c⇩1'' c⇩2''' c
assume [simp]: "c⇩1 = c⇩1'' ;; c" "c⇩2 = c⇩2''' ;; c"
assume case1: "\<turnstile> Γ {c} Γ⇩1'" "〈c⇩1'', mds, mem⇩1〉 \<R>⇧1⇘Γ⇙ 〈c⇩2''', mds, mem⇩2〉"
hence "\<turnstile> Γ {c} Γ'"
using context_le_refl has_type.sub sub.hyps(4)
by blast
with case1 show "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
using \<R>⇩3_aux.intro⇩1 by simp
next
fix Γ c⇩1'' c⇩2''' c''
assume [simp]: "c⇩1 = c⇩1'' ;; c''" "c⇩2 = c⇩2''' ;; c''"
assume "〈c⇩1'', mds, mem⇩1〉 \<R>⇧2⇘Γ⇙ 〈c⇩2''', mds, mem⇩2〉" "\<turnstile> Γ {c''} Γ⇩1'"
thus "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
using \<R>⇩3_aux.intro⇩2
apply simp
apply (rule \<R>⇩3_aux.intro⇩2 [where Γ = Γ])
apply simp
by (metis context_le_refl has_type.sub sub.hyps(4))
next
fix Γ c⇩1'' c⇩2''' c''
assume [simp]: "c⇩1 = c⇩1'' ;; c''" "c⇩2 = c⇩2''' ;; c''"
assume "〈c⇩1'', mds, mem⇩1〉 \<R>⇧3⇘Γ⇙ 〈c⇩2''', mds, mem⇩2〉" "\<turnstile> Γ {c''} Γ⇩1'"
thus "〈c⇩1, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
using \<R>⇩3_aux.intro⇩3
apply auto
by (metis (hide_lams, no_types) context_le_refl has_type.sub sub.hyps(4))
qed
ultimately show "?thesis c⇩1 mds mem⇩1 c⇩2 mem⇩2"
by (auto simp: \<R>.intros)
qed
with c⇩2'_props show ?case
by blast
qed
lemma \<R>⇩1_weak_bisim:
"weak_bisim (\<R>⇩1 Γ') (\<R> Γ')"
unfolding weak_bisim_def
using \<R>⇩1_elim \<R>_typed_step
by auto
lemma \<R>_to_\<R>⇩3: "[| 〈c⇩1, mds, mem⇩1〉 \<R>⇧u⇘Γ⇙ 〈c⇩2, mds, mem⇩2〉 ; \<turnstile> Γ { c } Γ' |] ==>
〈c⇩1 ;; c, mds, mem⇩1〉 \<R>⇧3⇘Γ'⇙ 〈c⇩2 ;; c, mds, mem⇩2〉"
apply (erule \<R>_elim)
by auto
lemma \<R>⇩2_implies_typeable: "〈c⇩1, mds, mem⇩1〉 \<R>⇧2⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉 ==> ∃ Γ⇩1. \<turnstile> Γ⇩1 { c⇩2 } Γ'"
apply (erule \<R>⇩2_elim)
by auto
lemma \<R>⇩3_weak_bisim:
"weak_bisim (\<R>⇩3 Γ') (\<R> Γ')"
proof -
{
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 c⇩1' mds' mem⇩1'
assume case3: "(〈c⇩1, mds, mem⇩1〉, 〈c⇩2, mds, mem⇩2〉) ∈ \<R>⇩3 Γ'"
assume eval: "〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds', mem⇩1'〉"
have "∃ c⇩2' mem⇩2'. 〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧ 〈c⇩1', mds', mem⇩1'〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2', mds', mem⇩2'〉"
using case3 eval
apply simp
proof (induct arbitrary: c⇩1' rule: \<R>⇩3_aux.induct)
case (intro⇩1 Γ c⇩1 mds mem⇩1 c⇩2 mem⇩2 c Γ')
hence [simp]: "c⇩2 = c⇩1"
by (metis (lifting) \<R>⇩1_elim)
thus ?case
proof (cases "c⇩1 = Stop")
assume [simp]: "c⇩1 = Stop"
from intro⇩1(1) show ?thesis
apply (rule \<R>⇩1_elim)
apply simp
apply (rule_tac x = c in exI)
apply (rule_tac x = mem⇩2 in exI)
apply (rule conjI)
apply (metis `c⇩1 = Stop` cxt_to_stmt.simps(1) eval⇩w_simplep.seq_stop eval⇩wp.unannotated eval⇩wp_eval⇩w_eq intro⇩1.prems seq_stop_elim)
apply (rule \<R>.intro⇩1, clarify)
by (metis (no_types) \<R>⇩1.intro `c⇩1 = Stop` context_le_refl intro⇩1.prems local.intro⇩1(2) seq_stop_elim stop_cxt sub)
next
assume "c⇩1 ≠ Stop"
from intro⇩1
obtain c⇩1'' where "〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1'', mds', mem⇩1'〉 ∧ c⇩1' = (c⇩1'' ;; c)"
by (metis `c⇩1 ≠ Stop` intro⇩1.prems seq_elim)
with intro⇩1
obtain c⇩2'' mem⇩2' where "〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2'', mds', mem⇩2'〉" "〈c⇩1'', mds', mem⇩1'〉 \<R>⇧u⇘Γ⇙ 〈c⇩2'', mds', mem⇩2'〉"
using \<R>⇩1_weak_bisim and weak_bisim_def
by blast
thus ?thesis
using intro⇩1(2) \<R>_to_\<R>⇩3
apply (rule_tac x = "c⇩2'' ;; c" in exI)
apply (rule_tac x = mem⇩2' in exI)
apply (rule conjI)
apply (metis eval⇩w.seq)
apply auto
apply (rule \<R>.intro⇩3)
by (metis (hide_lams, no_types) `〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1'', mds', mem⇩1'〉 ∧ c⇩1' = c⇩1'' ;; c`)
qed
next
case (intro⇩2 Γ c⇩1 mds mem⇩1 c⇩2 mem⇩2 cn Γ')
thus ?case
proof (cases "c⇩1 = Stop")
assume [simp]: "c⇩1 = Stop"
hence [simp]: "c⇩1' = cn" "mds' = mds" "mem⇩1' = mem⇩1"
using eval intro⇩2 seq_stop_elim
by auto
from intro⇩2 have bisim: "〈c⇩1, mds, mem⇩1〉 ≈ 〈c⇩2, mds, mem⇩2〉"
by (metis (lifting) \<R>⇩2_elim')
from intro⇩2 obtain Γ⇩1 where "\<turnstile> Γ⇩1 { c⇩2 } Γ"
by (metis \<R>⇩2_implies_typeable)
with bisim have [simp]: "c⇩2 = Stop"
apply auto
apply (rule stop_bisim [of mds mem⇩1 c⇩2 mem⇩2 Γ⇩1 Γ])
by simp_all
have "〈c⇩2 ;; cn, mds, mem⇩2〉 \<leadsto> 〈cn, mds', mem⇩2〉"
apply (auto simp: intro⇩2)
by (metis cxt_to_stmt.simps(1) eval⇩w_simplep.seq_stop eval⇩wp.unannotated eval⇩wp_eval⇩w_eq)
moreover
from intro⇩2(1) have "mds_consistent mds Γ"
apply auto
apply (erule \<R>⇩2_elim)
apply (simp add: mds_consistent_def)
by (metis context_le_def stop_cxt)
moreover
from bisim have "mem⇩1 =⇘mds⇙⇧l mem⇩2"
by (auto simp: mm_equiv.simps strong_low_bisim_mm_def)
have "∀ x ∈ dom Γ. Γ x = Some High"
using intro⇩2(1)
by (metis \<R>⇩2_elim')
hence "mem⇩1 =⇘Γ⇙ mem⇩2"
using `mds_consistent mds Γ` `mem⇩1 =⇘mds⇙⇧l mem⇩2`
apply (auto simp: tyenv_eq_def low_mds_eq_def mds_consistent_def)
by (metis Sec.simps(1) `∀x∈dom Γ. Γ x = Some High` `mds' = mds` domI the.simps to_total_def)
ultimately have "〈cn, mds, mem⇩1〉 \<R>⇧1⇘Γ'⇙ 〈cn, mds, mem⇩2〉"
by (metis (lifting) \<R>⇩1.intro local.intro⇩2(2))
thus "?thesis"
using \<R>.intro⇩1
apply auto
by (metis `〈c⇩2 ;; cn, mds, mem⇩2〉 \<leadsto> 〈cn, mds', mem⇩2〉` `c⇩2 = Stop` `mds' = mds`)
next
assume "c⇩1 ≠ Stop"
then obtain c⇩1''' where "c⇩1' = c⇩1''' ;; cn" "〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1''', mds', mem⇩1'〉"
by (metis (no_types) intro⇩2.prems seq_elim)
then obtain c⇩2''' mem⇩2' where c⇩2'''_props:
"〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2''', mds', mem⇩2'〉 ∧
〈c⇩1''', mds', mem⇩1'〉 \<R>⇧2⇘Γ⇙ 〈c⇩2''', mds', mem⇩2'〉"
using \<R>⇩2_bisim_step intro⇩2
by blast
let ?c⇩2' = "c⇩2''' ;; cn"
from c⇩2'''_props have "〈c⇩2 ;; cn, mds, mem⇩2〉 \<leadsto> 〈?c⇩2', mds', mem⇩2'〉"
by (metis (lifting) intro⇩2 eval⇩w.seq)
moreover
have "(〈c⇩1''' ;; cn, mds', mem⇩1'〉, 〈?c⇩2', mds', mem⇩2'〉) ∈ \<R>⇩3 Γ'"
by (metis (lifting) \<R>⇩3_aux.intro⇩2 c⇩2'''_props local.intro⇩2(2) mem_Collect_eq splitI)
ultimately show ?thesis
using \<R>.intro⇩3
by (metis (lifting) \<R>⇩3_aux.intro⇩2 `c⇩1' = c⇩1''' ;; cn` c⇩2'''_props local.intro⇩2(2))
qed
next
case (intro⇩3 Γ c⇩1 mds mem⇩1 c⇩2 mem⇩2 c Γ')
thus ?case
apply (cases "c⇩1 = Stop")
apply blast
proof -
assume "c⇩1 ≠ Stop"
then obtain c⇩1'' where "〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1'', mds', mem⇩1'〉" "c⇩1' = (c⇩1'' ;; c)"
by (metis intro⇩3.prems seq_elim)
then obtain c⇩2'' mem⇩2' where "〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2'', mds', mem⇩2'〉" "〈c⇩1'', mds', mem⇩1'〉 \<R>⇧u⇘Γ⇙ 〈c⇩2'', mds', mem⇩2'〉"
using local.intro⇩3(2) mem_Collect_eq splitI
by metis
thus ?thesis
apply (rule_tac x = "c⇩2'' ;; c" in exI)
apply (rule_tac x = mem⇩2' in exI)
apply (rule conjI)
apply (metis eval⇩w.seq)
apply (erule \<R>_elim)
apply simp_all
apply (metis \<R>.intro⇩3 \<R>_to_\<R>⇩3 `〈c⇩1'', mds', mem⇩1'〉 \<R>⇧u⇘Γ⇙ 〈c⇩2'', mds', mem⇩2'〉` `c⇩1' = c⇩1'' ;; c` local.intro⇩3(3))
apply (metis (lifting) \<R>.intro⇩3 \<R>_to_\<R>⇩3 `〈c⇩1'', mds', mem⇩1'〉 \<R>⇧u⇘Γ⇙ 〈c⇩2'', mds', mem⇩2'〉` `c⇩1' = c⇩1'' ;; c` local.intro⇩3(3))
by (metis (lifting) \<R>.intro⇩3 \<R>⇩3_aux.intro⇩3 `c⇩1' = c⇩1'' ;; c` local.intro⇩3(3))
qed
qed
}
thus ?thesis
unfolding weak_bisim_def
by auto
qed
lemma \<R>_bisim: "strong_low_bisim_mm (\<R> Γ')"
unfolding strong_low_bisim_mm_def
proof (auto)
from \<R>_sym show "sym (\<R> Γ')" .
next
from \<R>_closed_glob_consistent show "closed_glob_consistent (\<R> Γ')" .
next
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2
assume "〈c⇩1, mds, mem⇩1〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
thus "mem⇩1 =⇘mds⇙⇧l mem⇩2"
apply (rule \<R>_elim)
by (auto simp: \<R>⇩1_mem_eq \<R>⇩2_mem_eq \<R>⇩3_mem_eq)
next
fix c⇩1 mds mem⇩1 c⇩2 mem⇩2 c⇩1' mds' mem⇩1'
assume eval: "〈c⇩1, mds, mem⇩1〉 \<leadsto> 〈c⇩1', mds', mem⇩1'〉"
assume R: "〈c⇩1, mds, mem⇩1〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2, mds, mem⇩2〉"
from R show "∃ c⇩2' mem⇩2'. 〈c⇩2, mds, mem⇩2〉 \<leadsto> 〈c⇩2', mds', mem⇩2'〉 ∧
〈c⇩1', mds', mem⇩1'〉 \<R>⇧u⇘Γ'⇙ 〈c⇩2', mds', mem⇩2'〉"
apply (rule \<R>_elim)
apply (insert \<R>⇩1_weak_bisim \<R>⇩2_weak_bisim \<R>⇩3_weak_bisim eval weak_bisim_def)
apply (clarify, blast)+
by (metis mem_Collect_eq prod_caseI)
qed
lemma Typed_in_\<R>:
assumes typeable: "\<turnstile> Γ { c } Γ'"
assumes mds_cons: "mds_consistent mds Γ"
assumes mem_eq: "∀ x. to_total Γ x = Low --> mem⇩1 x = mem⇩2 x"
shows "〈c, mds, mem⇩1〉 \<R>⇧u⇘Γ'⇙ 〈c, mds, mem⇩2〉"
apply (rule \<R>.intro⇩1 [of Γ'])
apply clarify
apply (rule \<R>⇩1.intro [of Γ])
by (auto simp: assms tyenv_eq_def)
theorem type_soundness:
assumes well_typed: "\<turnstile> Γ { c } Γ'"
assumes mds_cons: "mds_consistent mds Γ"
assumes mem_eq: "∀ x. to_total Γ x = Low --> mem⇩1 x = mem⇩2 x"
shows "〈c, mds, mem⇩1〉 ≈ 〈c, mds, mem⇩2〉"
using \<R>_bisim Typed_in_\<R>
by (metis mds_cons mem_eq mm_equiv.simps well_typed)
definition "Γ⇩0" :: "'Var TyEnv"
where "Γ⇩0 x = None"
inductive type_global :: "('Var, 'AExp, 'BExp) Stmt list => bool"
("\<turnstile> _" [120] 1000)
where
"[| list_all (λ c. \<turnstile> Γ⇩0 { c } Γ⇩0) cs ;
∀ mem. sound_mode_use (add_initial_modes cs, mem) |] ==>
type_global cs"
inductive_cases type_global_elim: "\<turnstile> cs"
lemma mds⇩s_consistent: "mds_consistent mds⇩s Γ⇩0"
by (auto simp: mds⇩s_def mds_consistent_def Γ⇩0_def)
lemma typed_secure:
"[| \<turnstile> Γ⇩0 { c } Γ⇩0 |] ==> com_sifum_secure c"
apply (auto simp: com_sifum_secure_def low_indistinguishable_def mds_consistent_def type_soundness)
apply (auto simp: low_mds_eq_def)
apply (rule type_soundness [of Γ⇩0 c Γ⇩0])
apply (auto simp: mds⇩s_consistent to_total_def Γ⇩0_def)
by (metis empty_iff mds⇩s_def)
lemma "[| mds_consistent mds Γ⇩0 ; dma x = Low |] ==> x ∉ mds AsmNoRead"
by (auto simp: mds_consistent_def Γ⇩0_def)
lemma list_all_set: "∀ x ∈ set xs. P x ==> list_all P xs"
by (metis (lifting) list_all_iff)
theorem type_soundness_global:
assumes typeable: "\<turnstile> cs"
assumes no_assms_term: "no_assumptions_on_termination cs"
shows "prog_sifum_secure cs"
using typeable
apply (rule type_global_elim)
apply (subgoal_tac "∀ c ∈ set cs. com_sifum_secure c")
apply (metis list_all_set no_assms_term sifum_compositionality sound_mode_use.simps)
by (metis (lifting) list_all_iff typed_secure)
end
end