Theory Lightweight_Java_Proof
theory Lightweight_Java_Proof
imports Lightweight_Java_Equivalence "HOL-Library.Infinite_Set"
begin
lemmas wf_intros = wf_object_wf_varstate_wf_heap_wf_config_wf_stmt_wf_meth_wf_class_common_wf_class_wf_program.intros [simplified]
lemmas wf_induct = wf_object_wf_varstate_wf_heap_wf_config_wf_stmt_wf_meth_wf_class_common_wf_class_wf_program.induct [simplified]
lemmas wf_config_normalI = wf_object_wf_varstate_wf_heap_wf_config_wf_stmt_wf_meth_wf_class_common_wf_class_wf_program.wf_allI [simplified]
lemmas wf_objectE = wf_object.cases[simplified]
lemmas wf_varstateE = wf_varstate.cases[simplified]
lemmas wf_heapE = wf_heap.cases[simplified]
lemmas wf_configE = wf_config.cases[simplified]
lemmas wf_stmtE = wf_stmt.cases[simplified]
lemmas wf_methE = wf_meth.cases[simplified]
lemmas wf_class_cE = wf_class_common.cases[simplified]
lemmas wf_classE = wf_class.cases[simplified]
lemmas wf_programE = wf_program.cases[simplified]
lemma wf_subvarstateI:
"⟦wf_varstate P Γ H L; Γ x' = Some ty;
wf_object P H (Some v) (Some ty)⟧
⟹ wf_varstate P Γ H (L (x' ↦ v))"
apply(erule wf_varstateE) apply(rule wf_varstateI) apply(simp) apply(clarsimp)
done
lemma finite_super_varstate:
"finite (dom ((L ++ map_of (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list))(x' ↦ v_oid oid))) = finite (dom L)"
apply(induct y_cl_var_var'_v_list)
apply(clarsimp) apply(simp add: dom_def)
apply(subgoal_tac "{a. a ≠ x' ⟶ (∃y. L a = Some y)} = {a. a = x' ∨ (∃y. L a = Some y)}")
apply(simp add: Collect_disj_eq) apply(force)
apply(clarsimp simp add: map_add_def dom_def split: if_split_asm)
apply(subgoal_tac "{aa. aa ≠ x_var a ⟶ aa ≠ x' ⟶ (∃y. case_option (L aa) Some (map_of (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list) aa) = Some y)} =
{aa. aa = x_var a ∨ (aa = x' ∨ (∃y. case_option (L aa) Some (map_of (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list) aa) = Some y))}")
apply(simp add: Collect_disj_eq) apply(force)
done
lemma fst_map_elem:
"(y_k, ty_k, var_k, var'_k, v_k) ∈ set y_ty_var_var'_v_list ⟹
x_var var'_k ∈ fst ` (λ(y, ty, var, var', v). (x_var var', ty)) ` set y_ty_var_var'_v_list"
by (force)
lemma map_add_x_var[THEN mp]:
"var' ∈ set (map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list) ⟶
x_var var' ∈ set (map (λ(y, cl, var, var', v). x_var var) y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma map_of_map_and_x[simp]:
"⟦Γ x = Some ty_x; L x' = None; ∀x∈set y_cl_var_var'_v_list. (λ(y, cl, var, var', v). L (x_var var') = None) x;
∀x∈Map.dom Γ. wf_object Pa H (L x) (Γ x)⟧ ⟹
(if x = x' then Some ty
else (Γ ++ map_of (map (λ((y, cl, var, var', v), y', ty). (x_var var', ty)) (zip y_cl_var_var'_v_list y_ty_list))) x) =
Some ty_x"
apply(subgoal_tac "x ≠ x'") apply(subgoal_tac "∀(y, cl, var, var', v) ∈ set y_cl_var_var'_v_list. x_var var' ≠ x")
apply(case_tac "map_of (map (λ((y, cl, var, var', v), y', ty). (x_var var', ty)) (zip y_cl_var_var'_v_list y_ty_list)) x")
apply(clarsimp simp add: map_add_def)
apply(clarsimp) apply(drule map_of_SomeD) apply(clarsimp) apply(rename_tac y cl var var' v y' ty)
apply(drule_tac x = "(y, cl, var, var', v)" in bspec) apply(force simp add: set_zip)
apply(drule_tac x = "x_var var'" in bspec, simp add: domI) apply(erule wf_objectE, simp+)
apply(force elim: wf_objectE)+
done
lemma wf_stmt_in_G':
"(L x' = None ∧ (∀x∈set y_cl_var_var'_v_list. (λ(y, cl, var, var', v). L (x_var var') = None) x)
∧ (∀x∈dom Γ. wf_object P H (L x) (Γ x)) ∧ wf_stmt P Γ s ⟶
wf_stmt P ((Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))(x' ↦ ty)) s) ∧
(L x' = None ∧ (∀x∈set y_cl_var_var'_v_list. (λ(y, cl, var, var', v). L (x_var var') = None) x)
∧ (∀x∈dom Γ. wf_object P H (L x) (Γ x)) ∧ (∀s∈set ss. wf_stmt P Γ s) ⟶
(∀s∈set ss. wf_stmt P ((Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))(x' ↦ ty)) s))"
apply(rule tr_s_f_tr_ss_f.induct)
apply(clarsimp, erule wf_stmtE, simp_all, simp add: wf_blockI)
apply(clarify, erule wf_stmtE, simp_all)
apply(erule sty_option.cases, force intro: wf_var_assignI sty_optionI)
apply(clarify, erule wf_stmtE, simp_all)
apply(erule sty_option.cases, force intro: wf_field_readI sty_optionI)
apply(clarify, erule wf_stmtE, simp_all)
apply(erule sty_option.cases, force intro: wf_field_writeI sty_optionI)
apply(clarify, erule wf_stmtE, simp_all)
apply(clarsimp)
apply(rule wf_ifI)
apply(erule disjE)
apply(rule disjI1, erule sty_option.cases, force intro: sty_optionI)
apply(rule disjI2, erule sty_option.cases, force intro: sty_optionI)
apply(assumption+)
apply(clarify, erule wf_stmtE, simp_all)
apply(erule sty_option.cases, force intro: wf_newI sty_optionI)
apply(clarify, erule wf_stmtE, simp_all)
apply(rule wf_mcallI, simp, simp, simp)
apply(clarsimp split del: if_split) apply(rename_tac y_k ty_k)
apply(drule_tac x = "(y_k, ty_k)" in bspec, simp, clarify)
apply(erule_tac ?a3.0 = "Some ty_k" in sty_option.cases)
apply(force intro: sty_optionI)
apply(clarify)
apply(erule sty_option.cases)
apply(rule sty_optionI, simp+)
done
lemma map_three_in_four:
"var_k ∈ set (map (λ(y, cl, var, u). var) y_cl_var_var'_v_list)
⟶ (∃y cl u. (y, cl, var_k, u) ∈ set y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma map_var:
"⟦(cl_k, var_k, ty_k) ∈ set cl_var_ty_list;
map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list⟧
⟹ ∃y_k cl'_k u_k. (y_k, cl'_k, var_k, u_k) ∈ set y_cl_var_var'_v_list"
apply(subgoal_tac "var_k ∈ set (map (λ(y, cl, var, u). var) y_cl_var_var'_v_list)")
by (force simp add: map_three_in_four)+
lemma length_one_in_two:
"length y_ty_list = length (map fst y_ty_list)"
by (induct y_ty_list, auto)
lemma length_two_in_two:
"length y_ty_list = length (map snd y_ty_list)"
by (induct y_ty_list, auto)
lemma length_two_in_three:
"length cl_var_ty_list = length (map (λ(cl, var, ty). var) cl_var_ty_list)"
by (induct cl_var_ty_list, auto)
lemma length_three_in_three:
"length cl_var_ty_list = length (map (λ(cl, var, ty). ty) cl_var_ty_list)"
by (induct cl_var_ty_list, auto)
lemma length_three_in_four:
"length y_cl_var_var'_v_list = length (map (λ(y, cl, var, u). var) y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma length_one_in_five:
"length y_cl_var_var'_v_list = length (map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma length_three_in_five:
"length y_cl_var_var'_v_list = length (map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma map_length_list:
"length (map (λ((y, y'), yy, ty). (y', ty)) list) = length list"
by (induct list, auto)
lemma map_length_y:
"map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list ⟹
length y_cl_var_var'_v_list = length y_ty_list"
by (simp only: length_one_in_five length_one_in_two)
lemma map_length_y':
"map fst y_y'_list = map fst y_ty_list ⟹ length y_y'_list = length y_ty_list"
by (simp only: length_one_in_two length_two_in_two)
lemma map_length_var:
"map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list ⟹
length y_cl_var_var'_v_list = length cl_var_ty_list"
by (simp only: length_three_in_five length_two_in_three)
lemma map_length_ty:
"map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list ⟹
length cl_var_ty_list = length y_ty_list"
by (simp only: length_three_in_three length_two_in_two)
lemma map_length_var_ty:
"⟦map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list⟧ ⟹
length y_cl_var_var'_v_list = length y_ty_list"
apply(rule_tac s = "length cl_var_ty_list" in trans)
apply (simp only: length_three_in_four length_two_in_three)
apply(simp only: length_three_in_three length_two_in_two)
done
lemma fun_eq_fst:
"(fst ∘ (λ((y, cl, var, var', v), y', y). (x_var var', y))) = (λ((y, cl, var, var', v), y', y). (x_var var'))"
by (simp add: fun_eq_iff)
lemma fst_zip_eq:
"length y_cl_var_var'_v_list = length y_ty_list ⟹
(map fst (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list))) =
(map (λ(y, cl, var, var', v). x_var var') y_cl_var_var'_v_list)"
apply(simp)
apply(simp add: fun_eq_fst)
apply(rule nth_equalityI)
apply(force)
apply(clarsimp)
apply(frule nth_mem)
apply(subgoal_tac "∃x. (y_cl_var_var'_v_list ! i) = x")
apply(force)
apply(rule_tac x = "y_cl_var_var'_v_list ! i" in exI)
apply(simp)
done
lemma distinct_x_var:
"distinct (map (λ(y, cl, var, var', v). x_var var) y_cl_var_var'_v_list) =
distinct (map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list)"
apply (induct y_cl_var_var'_v_list)
by (force simp add: contrapos_np)+
lemma distinct_x_var':
"distinct (map (λ(y, cl, var, var', v). x_var var') y_cl_var_var'_v_list) =
distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list)"
apply(induct y_cl_var_var'_v_list)
by (force simp add: contrapos_np)+
lemma map_fst_two:
"map fst (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) =
map (λ(y, cl, var, var', v). x_var var) y_cl_var_var'_v_list"
by (induct y_cl_var_var'_v_list, auto)
lemma map_fst_two':
"map fst (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list) =
map (λ(y, cl, var, var', y). x_var var') y_cl_var_var'_v_list"
by (induct y_cl_var_var'_v_list, auto)
lemma map_fst_var':
"distinct (map fst (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list)) =
distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list)"
by (simp only: map_fst_two' distinct_x_var')
lemma distinct_var:
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list);
map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list⟧ ⟹
distinct (map fst (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list))"
by (simp only: map_fst_two distinct_x_var)
lemma distinct_var':
"⟦map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list⟧ ⟹
distinct (map fst (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list))) =
distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list)"
by (simp only: map_length_var_ty fst_zip_eq distinct_x_var')
lemma weaken_list_var:
"map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list =
map (λ(y, cl, var, u). var) y_cl_var_var'_v_list"
by (induct y_cl_var_var'_v_list, auto)
lemma weaken_list_fd:
"map (λ(y, cl, var, var', v). vd_def cl var) list = map (λ(y, cl, var, u). vd_def cl var) list"
by (induct list, auto)
lemma weaken_list_y:
"map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list =
map fst y_cl_var_var'_v_list"
by (induct y_cl_var_var'_v_list, auto)
lemma wf_cld_from_lu:
"⟦wf_program P; find_cld P ctx fqn (Some (ctx', cld'))⟧ ⟹ wf_class P cld'"
apply(clarsimp) apply(drule find_to_mem) apply(erule wf_programE) by (simp add: member_def)
lemma meth_def_in_set[rule_format]:
"find_meth_def_in_list meth_defs meth (Some meth_def) ⟶ meth_def ∈ set meth_defs"
apply(clarsimp) apply(induct meth_defs) by (auto split: meth_def.splits meth_sig.splits if_split_asm)
lemma find_meth_def_in_list_mem[rule_format, simp]:
"find_meth_def_in_list_f meth_defs meth = Some meth_def ⟶ meth_def ∈ set meth_defs"
apply(induct meth_defs) apply(auto split: meth_def.splits meth_sig.splits) done
lemma find_meth_def_in_path_ex_cld[rule_format]:
"find_meth_def_in_path_f ctxclds meth = Some (ctx, meth_def)
⟶ (∃cld meth_defs. (ctx, cld) ∈ set ctxclds ∧ class_methods_f cld = meth_defs ∧ meth_def ∈ set meth_defs)"
apply(induct ctxclds) apply(simp) apply(clarsimp)
apply(clarsimp split: option.splits) apply(rule_tac x = cld in exI) apply(force)
apply(force)
done
lemma map_ctx_cld_dcl_two[simp]:
"ctxclds = map (λ(ctx, cld, dcl). (ctx, cld)) (map (λ(ctx, cld). (ctx, cld, classname_f cld)) ctxclds)"
by (induct ctxclds, auto)
lemma clds_in_path_exist:
"find_path_f P ctx' fqn = Some path ⟹ (∀(ctx, cld) ∈ set path. cld ∈ set P)"
apply(clarify)
apply(drule all_in_path_found) apply(simp) apply(clarsimp)
apply(drule find_to_mem) apply(simp add: member_def)
done
lemma wf_meth_defs_in_wf_class[rule_format]:
"meth_def ∈ set (class_methods_f cld) ∧ wf_class P cld
⟶ wf_meth P (ty_def ctx_def (class_name_f cld)) meth_def"
apply(clarsimp)
apply(erule wf_classE) apply(clarsimp simp: class_methods_f_def)
apply(erule wf_class_cE) apply(clarsimp simp: class_name_f_def)
apply(drule(1)bspec, simp)
done
lemma map_ctxclds: "ctxclds = map ((λ(ctx_XXX, cld_XXX, dcl_XXX). (ctx_XXX, cld_XXX)) ∘ (λ(ctx, cld). (ctx, cld, class_name_f cld))) ctxclds"
by (induct ctxclds, auto)
lemma wf_method_from_find'[rule_format]:
"wf_program P ∧ find_path_ty_f P (ty_def ctxa dcl) = Some ctxclds ∧ find_meth_def_in_path_f ctxclds meth = Some (ctx, meth_def)
⟶ (∃dcla. is_sty_one P (ty_def ctxa dcl) (ty_def ctx dcla) = Some True ∧ wf_meth P (ty_def ctx_def dcla) meth_def)"
apply(clarsimp) apply(drule find_meth_def_in_path_ex_cld) apply(clarsimp)
apply(rule_tac x = "class_name_f cld" in exI)
apply(rule)
apply(rule_tac ctx_cld_dcl_list = "map (λ(ctx, cld). (ctx, cld, class_name_f cld)) ctxclds" in sty_dclI[simplified])
apply(simp add: map_ctxclds)
apply(clarsimp)
apply(force)
apply(drule clds_in_path_exist)
apply(simp)
apply(erule wf_programE)
apply(drule_tac x = "(ctx, cld)" in bspec, simp)
apply(drule_tac x = cld in bspec, simp)
apply(simp add: wf_meth_defs_in_wf_class)
done
lemma wf_method_from_find:
"⟦wf_program P; find_meth_def P ty_x_d meth (Some (ctx, meth_def))⟧ ⟹
∃dcl. sty_one P ty_x_d (ty_def ctx dcl) ∧ wf_meth P (ty_def ctx_def dcl) meth_def"
apply(erule find_meth_def.cases, clarsimp+)
apply(induct ty_x_d) apply(simp) apply(rename_tac ctx' dcl' ctxclds)
apply(cut_tac P = P and ctxa = ctx' and dcl = dcl' and ctxclds = ctxclds and
meth = meth and ctx = ctx and meth_def = meth_def in wf_method_from_find') apply(simp)
apply(simp)
done
lemma find_type_lift_opts[rule_format]:
"(∀x∈set cl_var_ty_list. (λ(cl_k, var_k, ty_k). find_type_f P ctx cl_k = Some ty_k) x) ⟶
lift_opts (map (case_vd (λclk vark. find_type_f P ctx clk)) (map (λ(cl_k, var_k, ty_k). vd_def cl_k var_k) cl_var_ty_list)) =
Some (map (λ(cl, var, ty). ty) cl_var_ty_list)"
by (induct cl_var_ty_list, auto)
lemma find_md_in_pre_path[rule_format]:
"find_meth_def_in_path_f path m = Some ctxmd ⟶ (∀path'. find_meth_def_in_path_f (path @ path') m = Some ctxmd)"
by (induct path, auto split: option.splits)
lemma lift_opts_map:
"∀x∈set cl_var_ty_list. (λ(cl_k, var_k, ty_k). find_type_f P ctx cl_k = Some ty_k) x ⟹
lift_opts (map (case_vd (λclk vark. find_type_f P ctx clk)) (map (λ(cl_k, var_k, ty_k). vd_def cl_k var_k) cl_var_ty_list)) = Some (map (λ(cl, var, ty). ty) cl_var_ty_list)"
by (induct cl_var_ty_list, auto)
lemma m_in_list[rule_format]:
"(∀x∈set meth_def_meth_list. case_prod (λmeth_def. (=) (method_name_f meth_def)) x) ∧
find_meth_def_in_list_f (map fst meth_def_meth_list) m = Some md ⟶
m ∈ snd ` set meth_def_meth_list"
by (induct meth_def_meth_list, auto simp add: method_name_f_def split: meth_def.splits meth_sig.splits)
lemma m_image_eq[rule_format]:
"meth_def_def (meth_sig_def cl m list2) meth_body ∈ set meth_defs ⟶
m ∈ case_meth_def (λmeth_sig meth_body. case meth_sig of meth_sig_def cl meth vds ⇒ meth) ` set meth_defs"
by (induct meth_defs, auto)
lemma fmdip_to_mip[rule_format]:
"find_meth_def_in_path_f path m = Some ctxmd ⟶ m ∈ set (methods_in_path_f (map snd path))"
apply(induct path) apply(simp) apply(clarsimp simp add: class_methods_f_def split: option.splits cld.splits)
apply(rename_tac aa bb)
apply(case_tac aa) apply(rename_tac meth_sig meth_body) apply(case_tac meth_sig) apply(clarsimp) apply(frule find_md_m_match') apply(clarsimp)
apply(frule find_meth_def_in_list_mem) apply(frule m_image_eq) apply(assumption)
done
lemma lift_opts_for_all[rule_format]:
"lift_opts (map (case_vd (λclk vark. find_type_f P ctx clk)) (map (λ(cl, var, ty). vd_def cl var) cl_var_ty_list)) = None ∧
(∀x∈set cl_var_ty_list. (λ(cl, var, ty). find_type_f P ctx_def cl = Some ty) x) ⟶ False"
apply(induct cl_var_ty_list) apply(simp) apply(clarsimp) apply(case_tac ctx) apply(simp) done
lemma mty_preservation'''':
"⟦find_cld_f P ctx (fqn_def dcl') = Some (ctx, cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds');
find_cld_f P ctx (fqn_def dcl'') = Some (ctx, cld_def dcl'' cl'' fds'' mds'');
find_path_rec_f P ctx cl'' [(ctx, cld_def dcl'' cl'' fds'' mds'')] = Some path;
find_meth_def_in_path_f path m = Some (ctx'', meth_def_def (meth_sig_def cl_r m' vds) mb);
find_type_f P ctx'' cl_r = Some ty_r; lift_opts (map (case_vd (λclk vark. find_type_f P ctx'' clk)) vds) = Some tys;
lift_opts (map (case_vd (λclk vark. find_type_f P ctx' clk)) vds') = Some tys'; find_type_f P ctx' cl_r' = Some ty_r';
find_meth_def_in_path_f ((ctx, cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds') # path) m = Some (ctx', meth_def_def (meth_sig_def cl_r' m'' vds') mb');
wf_program P⟧
⟹ tys' = tys ∧ ty_r' = ty_r"
using [[hypsubst_thin = true]]
apply(clarsimp simp add: class_methods_f_def split: option.splits)
apply(drule wf_cld_from_lu) apply(simp) apply(erule wf_classE) apply(erule wf_class_cE) apply(clarsimp)
apply(subgoal_tac "m ∈ snd ` set meth_def_meth_list")
apply(clarsimp) apply(rename_tac md_m m) apply(drule_tac x = "(md_m, m)" in bspec, simp)+ apply(clarsimp split: option.splits)
apply(case_tac ctx') apply(clarsimp)
apply(case_tac md_m) apply(rename_tac meth_sig meth_body) apply(case_tac meth_sig) apply(rename_tac ms mb_m cl_r_m m vds_m) apply(clarsimp simp add: method_name_f_def)
apply(erule_tac Q = "tys' = tys ⟶ ty_r' ≠ ty_r" in contrapos_pp) apply(clarsimp)
apply(clarsimp simp add: methods_f_def find_path_f_def superclass_name_f_def split: option.splits if_split_asm)
apply(frule fmdip_to_mip) apply(clarsimp) apply(rename_tac m mty mty') apply(drule_tac x = "(m, mty, mty')" in bspec, simp)+
apply(clarsimp) apply(frule_tac f = snd in imageI) apply(simp) apply(thin_tac "m ∈ snd ` set meth_def_meth_list") apply(clarsimp)
apply(clarsimp simp add: mtype_f_def split: option.splits meth_def.splits meth_sig.splits)
apply(clarsimp simp add: find_meth_def_f_def find_path_f_def superclass_name_f_def split: option.splits if_split_asm)
apply(frule path_append) apply(rename_tac ad) apply(frule_tac path = ad in path_append) apply(clarsimp)
apply(frule_tac prefix = "[(ctx_def, cld_def dcl'' cl'' fds'' mds'')]" and suffix = path'' and
prefix' = "[(ctx_def, cld_def dcl' (cl_fqn (fqn_def dcl'')) (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) (map fst meth_def_meth_list)),
(ctx_def, cld_def dcl'' cl'' fds'' mds'')]" in fpr_same_suffix[rule_format]) apply(simp)
apply(clarsimp simp add: class_methods_f_def)
apply(rule m_in_list) apply(simp)
done
lemma mty_preservation'''[rule_format]:
"∀suffix dcl. find_path_rec_f P ctx cl prefix = Some (prefix @ suffix) ⟶ wf_program P ∧ cl = cl_fqn (fqn_def dcl) ⟶
(∀(ctx', cld') ∈ set suffix.
(∀prefix' suffix'. find_path_rec_f P ctx' (cl_fqn (fqn_def (class_name_f cld'))) prefix' = Some (prefix' @ suffix') ∧
mtype_f P (ty_def ctx' (class_name_f cld')) m = Some mty ⟶ mtype_f P (ty_def ctx dcl) m = Some mty))"
supply [[simproc del: defined_all]]
apply(induct_tac P ctx cl prefix rule: find_path_rec_f.induct)
apply(simp)
apply(clarsimp split: option.splits)
apply(frule path_append) apply(clarify)
apply(clarsimp)
apply(erule disjE)
apply(clarify)
apply(clarsimp simp add: class_name_f_def split: cld.splits)
apply(frule find_cld_name_eq) apply(frule_tac ctx = a in find_cld_name_eq)
apply(clarsimp simp add: class_name_f_def split: cld.splits)
apply(case_tac b) apply(rename_tac dcl' cl' fds' mds')
apply(clarsimp simp add: superclass_name_f_def) apply(case_tac cl') apply(simp) apply(rename_tac fqn) apply(case_tac fqn) apply(rename_tac dcl'') apply(clarsimp)
apply(clarsimp split: option.splits)
apply(subgoal_tac "∀aa b ab bb. (a = ab ∧ cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds' = bb ∧ aa = ab ∧ b = bb)
⟶ (∀suffix. find_path_rec_f P ab (case bb of cld_def dcl cl fds mds ⇒ cl) (path @ [(ab, bb)]) = Some (path @ (ab, bb) # suffix) ⟶
(∀dcl. (case bb of cld_def dcl cl fds mds ⇒ cl) = cl_fqn (fqn_def dcl) ⟶
(∀x∈set suffix.
(λ(ctx', cld').
(∃prefix' suffix'.
case_option None (case_prod (λctx' cld. find_path_rec_f P ctx' (superclass_name_f cld) (prefix' @ [(ctx', cld)]))) (find_cld_f P ctx' (fqn_def (class_name_f cld'))) =
Some (prefix' @ suffix')) ∧
mtype_f P (ty_def ctx' (class_name_f cld')) m = Some mty ⟶
mtype_f P (ty_def ab dcl) m = Some mty)
x)))")
defer
apply(force)
apply(thin_tac "⋀aa b x y.
⟦a = aa ∧ cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds' = b; x = aa ∧ y = b⟧
⟹ ∀suffix.
find_path_rec_f P aa (case b of cld_def dcl cl fds mds ⇒ cl) (path @ [(aa, b)]) =
Some (path @ (aa, b) # suffix) ⟶
(∀dcl. (case b of cld_def dcl cl fds mds ⇒ cl) = cl_fqn (fqn_def dcl) ⟶
(∀x∈set suffix.
case x of
(ctx', cld') ⇒
(∃prefix' suffix'.
case_option None
(λ(ctx', cld).
find_path_rec_f P ctx' (superclass_name_f cld)
(prefix' @ [(ctx', cld)]))
(find_cld_f P ctx' (fqn_def (class_name_f cld'))) =
Some (prefix' @ suffix')) ∧
mtype_f P (ty_def ctx' (class_name_f cld')) m = Some mty ⟶
mtype_f P (ty_def aa dcl) m = Some mty))")
apply(clarsimp)
apply(drule_tac x = "(aa, ba)" in bspec, simp)
apply(clarsimp)
apply(subgoal_tac "(∃prefix' suffix'. find_path_rec_f P ab (case bb of cld_def dcl cl fds mds ⇒ cl) (prefix' @ [(ab, bb)]) = Some (prefix' @ suffix'))")
apply(erule impE) apply(simp add: superclass_name_f_def) apply(thin_tac "∃prefix suffix'. P prefix suffix'" for P)
apply(thin_tac "mtype_f P (ty_def aa (class_name_f ba)) m = Some mty")
apply(frule find_cld_name_eq) apply(clarsimp split: option.splits if_split_asm)
apply(clarsimp simp add: mtype_f_def split: option.splits meth_def.splits meth_sig.splits)
apply(rule)
apply(clarsimp simp add: find_meth_def_f_def) apply(subgoal_tac "∃path'. find_path_f P a (cl_fqn (fqn_def dcl')) = Some path'")
apply(case_tac b) apply(clarsimp simp add: find_path_f_def superclass_name_f_def split: if_split_asm option.splits)
apply(rename_tac meth_body cl list_char1 list_vd ty list_ty list_char2 cla list_fd list_md list_p1 path')
apply(frule_tac path = path' in path_append) apply(rename_tac ag ah) apply(frule_tac path = ag in path_append) apply(clarify)
apply(frule_tac suffix = path''a and suffix' = path''b and prefix' = "[(ac, cld_def list_char2 cla list_fd list_md)]" in fpr_same_suffix[rule_format], force)
apply(simp) apply(clarify) apply(clarsimp simp add: class_methods_f_def split: option.splits)
apply(clarsimp simp add: find_path_f_def superclass_name_f_def split: option.splits if_split_asm)
apply(frule_tac path' = "(path @ [(a, cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds'), (ac, b)])" in path_append) apply(clarsimp)
apply(frule_tac suffix = path''a and prefix' = "[(a, cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds'), (ac, b)]" in fpr_same_suffix') back apply(simp) apply(simp)
apply(clarsimp) apply(rule)
apply(clarsimp) apply(frule_tac ty_x_d = "(ty_def a dcl')" in wf_method_from_find[simplified]) apply(simp) apply(clarsimp)
apply(erule wf_methE) apply(rename_tac ag ah ai aj ak al am an ao ap aq ar as at au av) apply(case_tac ag) apply(clarsimp)
apply(clarsimp) apply(rule)
apply(clarsimp) apply(frule_tac ty_x_d = "(ty_def a dcl')" in wf_method_from_find[simplified]) apply(simp) apply(clarsimp)
apply(erule wf_methE) apply(clarsimp) apply(cut_tac lift_opts_for_all) apply(assumption) apply(rule) apply(simp) apply(assumption)
apply(clarsimp)
apply(thin_tac "find_path_rec_f P ab (case bb of cld_def dcl cl fds mds ⇒ cl) (prefix' @ [(ab, bb)]) = Some (prefix' @ suffix')")
apply(thin_tac "find_cld_f P aa (fqn_def (class_name_f ba)) = Some (ab, bb)") apply(thin_tac "(aa, ba) ∈ set path''")
apply(case_tac b) apply(frule_tac dcl = dcl'' in find_cld_name_eq) apply(clarsimp simp add: superclass_name_f_def)
apply(rename_tac ctx ctx'' mb cl_r m' vds ty_r tys ctx' cl_r' m'' vds' ty_r' tys' mb' dcl'' cl'' fds'' mds'')
apply(clarsimp simp add: find_meth_def_f_def find_path_f_def superclass_name_f_def split: option.splits if_split_asm)
apply(thin_tac "find_path_rec_f P ctx cl'' (path @ [(ctx, cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds'), (ctx, cld_def dcl'' cl'' fds'' mds'')]) =
Some (path @ (ctx, cld_def dcl' (cl_fqn (fqn_def dcl'')) fds' mds') # path'')") apply(clarsimp) apply(rename_tac path'' path')
apply(frule_tac path = path' in path_append) apply(frule_tac path = path'' in path_append) apply(clarify)
apply(frule_tac suffix = path''a and suffix' = path''b and prefix' = "[(ctx, cld_def dcl'' cl'' fds'' mds'')]" in fpr_same_suffix[rule_format], force)
apply(clarsimp simp del: find_meth_def_in_path_f.simps) apply(rename_tac path'')
apply(frule_tac ctx' = ctx' and m'' = m'' and cl'' = cl'' and fds'' = fds'' and ctx'' = ctx'' and
path = "(ctx, cld_def dcl'' cl'' fds'' mds'') # path''" in mty_preservation'''', simp+)
apply(rule_tac x = prefix' in exI) apply(clarsimp simp add: superclass_name_f_def)
done
lemma mty_preservation'':
"⟦wf_program P; find_path_f P ctx (cl_fqn (fqn_def dcl)) = Some path; (ctx', cld') ∈ set path⟧ ⟹
∀prefix' suffix'.
find_path_rec_f P ctx' (cl_fqn (fqn_def (class_name_f cld'))) prefix' = Some (prefix' @ suffix') ∧
mtype_f P (ty_def ctx' (class_name_f cld')) m = Some mty ⟶ mtype_f P (ty_def ctx dcl) m = Some mty"
apply(cut_tac x = "(ctx', cld')" in mty_preservation'''[of _ _ _ "[]", simplified])
apply(unfold find_path_f_def) apply(assumption) apply(simp+) done
lemma mty_preservation':
"⟦wf_program P; find_path_f P ctx (cl_fqn (fqn_def dcl)) = Some path; (ctx', cld') ∈ set path;
find_path_f P ctx' (cl_fqn (fqn_def (class_name_f cld'))) = Some path'; mtype_f P (ty_def ctx' (class_name_f cld')) m = Some mty⟧
⟹ mtype_f P (ty_def ctx dcl) m = Some mty"
apply(cut_tac path = path and suffix' = path' in mty_preservation''[rule_format, of _ _ _ _ _ _ "[]"])
apply(assumption+) apply(rule) apply(simp add: find_path_f_def) apply(assumption+) done
lemma lift_opts_for_all_true[rule_format]:
"∀y_ty_list.
(∀x∈set cl_var_ty_list. (λ(cl_k, var_k, ty_k). find_type_f P ctx cl_k = Some ty_k) x) ∧
lift_opts (map (case_vd (λclk vark. find_type_f P ctx clk)) (map (λ(cl_k, var_k, ty_k). vd_def cl_k var_k) cl_var_ty_list)) = Some (map snd y_ty_list) ⟶
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list"
by (induct cl_var_ty_list, auto split: option.splits)
lemma mty_preservation:
"⟦wf_program P;
find_meth_def_f P ty_x_d meth = Some (ctx, meth_def_def (meth_sig_def cl_r meth (map (λ(cl_k, var_k, ty_k). vd_def cl_k var_k) cl_var_ty_list)) meth_body);
find_type_f P ctx cl_r = Some ty_r_d; ∀x∈set cl_var_ty_list. (λ(cl_k, var_k, ty_k). find_type_f P ctx cl_k = Some ty_k) x;
mtype_f P ty_x_s meth = Some (mty_def (map snd y_ty_list) ty_r_s); is_sty_one P ty_x_d ty_x_s = Some True⟧
⟹ ty_r_d = ty_r_s ∧ map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list"
apply(case_tac "ty_x_d = ty_x_s")
apply(clarsimp) apply(clarsimp simp add: mtype_f_def find_type_lift_opts[simplified] split: option.splits)
apply(simp add: is_sty_one_def split: option.splits)
apply(case_tac ty_x_s) apply(clarsimp simp add: mtype_f_def find_meth_def_f_def)
apply(clarsimp) apply(rename_tac path_d ctx_s cld_s)
apply(case_tac ty_x_d) apply(clarsimp) apply(clarsimp) apply(rename_tac ctx_d dcl_d)
apply(clarsimp simp add: find_meth_def_f_def split: option.splits)
apply(subgoal_tac "∃path_s. find_path_f P ctx_s (cl_fqn (fqn_def (class_name_f cld_s))) = Some path_s")
apply(clarify) apply(frule_tac path = path_d and path' = path_s in mty_preservation') apply(simp+)
apply(clarsimp simp add: mtype_f_def split: option.splits meth_def.splits meth_sig.splits)
apply(clarsimp simp add: find_meth_def_f_def)
apply(rule_tac P = P and ctx = ctx in lift_opts_for_all_true) apply(simp)
apply(clarsimp simp add: mtype_f_def find_meth_def_f_def split: option.splits)
done
lemma map_not_mem:
"⟦(y_k, ty_k, var_k, var'_k, v_k) ∈ set y_ty_var_var'_v_list; x' ∉ (λ(y, ty, var, var', v). x_var var') ` set y_ty_var_var'_v_list⟧
⟹ x_var var'_k ≠ x'"
by (force)
lemma map_fst:
"map fst (map (λ(y, ty, var, var', v). (x_var var', ty)) y_ty_var_var'_v_list) = map (λ(y, ty, var, var', v). x_var var') y_ty_var_var'_v_list"
by (force)
lemma supertype_top:
"sty_one P ty ty' ⟹ ty = ty_top ⟶ ty' = ty_top"
by (induct rule: sty_one.induct, auto)
lemma top_not_subtype[rule_format]:
"sty_one P ty_top (ty_def ctx dcl) ⟶ False"
by (rule, drule supertype_top, simp)
lemma f_in_found_fds:
"ftype_in_fds_f P ctx fds f = ty_opt_bot_opt (Some ty_f) ⟶ f ∈ case_fd (λcl f. f) ` set fds"
by (induct fds, auto split: fd.splits)
lemma ftype_fields[rule_format]:
"ftype_in_path_f P path_s f = Some ty_f ⟶ f ∈ set (fields_in_path_f path_s)"
apply(induct path_s) apply(simp) apply(clarsimp split: option.splits)
apply(case_tac b) apply(clarsimp) apply(rename_tac ctx path_s dcl cl fds mds)
apply(clarsimp simp add: class_fields_f_def split: ty_opt_bot.splits option.splits) apply(simp add: f_in_found_fds)
done
lemma no_field_hiding''':
"∀suffix. find_path_rec_f P ctx cl prefix = Some (prefix @ suffix) ⟶ wf_program P ⟶
(∀(ctx, cld) ∈ set suffix.
(∀prefix' suffix'. find_path_rec_f P ctx (cl_fqn (fqn_def (class_name_f cld))) prefix' = Some (prefix' @ suffix') ∧
f ∈ set (fields_in_path_f suffix') ⟶ f ∈ set (fields_in_path_f suffix)))"
supply [[simproc del: defined_all]]
apply(induct_tac P ctx cl prefix rule: find_path_rec_f.induct)
apply(simp)
apply(clarsimp split: option.splits)
apply(subgoal_tac "∀aa ba aaa bb.
(a = aaa ∧ b = bb ∧ aa = aaa ∧ ba = bb)
⟶ (∀suffix. find_path_rec_f P aaa (superclass_name_f bb) (path @ [(aaa, bb)]) = Some (path @ (aaa, bb) # suffix) ⟶
(∀x∈set suffix.
(λ(ctx, cld). (∃prefix' suffix'.
case_option None (case_prod (λctx' cld. find_path_rec_f P ctx' (superclass_name_f cld) (prefix' @ [(ctx', cld)]))) (find_cld_f P ctx (fqn_def (class_name_f cld))) =
Some (prefix' @ suffix') ∧
f ∈ set (fields_in_path_f suffix')) ⟶
f ∈ set (fields_in_path_f suffix))
x))")
defer
apply(thin_tac _)+
apply(force)
apply(thin_tac "⋀aa ba x y.
⟦a = aa ∧ b = ba; x = aa ∧ y = ba⟧
⟹ ∀suffix.
find_path_rec_f P aa (superclass_name_f ba) (path @ [(aa, ba)]) =
Some (path @ (aa, ba) # suffix) ⟶
(∀x∈set suffix.
case x of
(ctx, cld) ⇒
(∃prefix' suffix'.
case_option None
(λ(ctx', cld).
find_path_rec_f P ctx' (superclass_name_f cld) (prefix' @ [(ctx', cld)]))
(find_cld_f P ctx (fqn_def (class_name_f cld))) =
Some (prefix' @ suffix') ∧
f ∈ set (fields_in_path_f suffix')) ⟶
f ∈ set (fields_in_path_f suffix))")
apply(clarsimp)
apply(frule path_append) apply(clarify)
apply(erule_tac x = "tl suffix" in allE)
apply(clarsimp)
apply(erule disjE)
apply(clarify)
apply(case_tac fqn)
apply(clarsimp simp del: fmdip_cons simp add: class_name_f_def split: cld.splits)
apply(frule find_cld_name_eq) apply(frule_tac ctx = a in find_cld_name_eq)
apply(clarsimp simp del: fmdip_cons simp add: class_name_f_def split: cld.splits)
apply (rename_tac list1 cl list2 list3)
apply(frule_tac path = "prefix' @ suffix'" in path_append) apply(clarsimp simp del: fmdip_cons)
apply(frule_tac prefix = "path @ [(ab, cld_def list1 cl list2 list3)]" and suffix = path'' and
prefix' = "prefix' @ [(ab, cld_def list1 cl list2 list3)]" and suffix' = path''a in fpr_same_suffix[rule_format])
apply(clarsimp) apply(simp)
apply(drule_tac x = "(aa, ba)" in bspec, simp)
apply(force)
done
lemma no_field_hiding'':
"⟦find_path_f P ctx' cl = Some suffix; wf_program P; (ctx, cld) ∈ set suffix⟧
⟹ ∀prefix' suffix'.
find_path_rec_f P ctx (cl_fqn (fqn_def (class_name_f cld))) prefix' = Some (prefix' @ suffix') ∧ f ∈ set (fields_in_path_f suffix') ⟶
f ∈ set (fields_in_path_f suffix)"
apply(cut_tac x = "(ctx, cld)" in no_field_hiding'''[of _ _ _ "[]", rule_format]) apply(simp add: find_path_f_def)+ done
lemma no_field_hiding':
"⟦find_path_f P ctx' cl = Some path; wf_program P; (ctx, cld) ∈ set path;
find_path_f P ctx (cl_fqn (fqn_def (class_name_f cld))) = Some path'; f ∈ set (fields_in_path_f path')⟧
⟹ f ∈ set (fields_in_path_f path)"
apply(cut_tac no_field_hiding''[rule_format, of _ _ _ _ _ _ "[]"]) apply(assumption+) apply(unfold find_path_f_def) apply(rule) apply(simp+) done
lemma no_field_hiding:
"⟦wf_program P; is_sty_one P ty_x_d ty_x_s = Some True; ftype_f P ty_x_s f = Some ty_f; fields_f P ty_x_d = Some fields_oid⟧
⟹ f ∈ set fields_oid"
apply(case_tac ty_x_s) apply(simp add: ftype_f_def)
apply(simp add: is_sty_one_def split: option.splits)
apply(case_tac ty_x_d) apply(simp) apply(clarsimp) apply(rename_tac ctx_s dcl_s path_d ctx_d dcl_d)
apply(simp add: ftype_f_def split: option.splits)
apply(clarsimp simp add: fields_f_def) apply(drule ftype_fields)
apply(frule no_field_hiding') apply(simp add: ftype_fields class_name_f_def)+
done
lemma ftype_pre_path[rule_format]:
"ftype_in_path_f P path_s f = Some ty_f ⟶ ftype_in_path_f P (path_s @ path'') f = Some ty_f"
by (induct path_s, auto split: option.splits ty_opt_bot.splits)
lemma fields_non_intersection[rule_format]:
" (λ(cl, f, ty). f) ` set cl_f_ty_list ∩ set (fields_in_path_f path'') = {}
∧ f ∈ set (fields_in_path_f path'')
⟶ ftype_in_fds_f P ctx_def (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) f = ty_opt_bot_opt None"
by (induct cl_f_ty_list, auto)
lemma f_notin_list[rule_format]:
"f ∉ set (map (λ(cl, f, ty). f) cl_f_ty_list) ⟶ ftype_in_fds_f P ctx_def (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) f = ty_opt_bot_opt None"
by (induct cl_f_ty_list, auto)
declare find_path_rec_f.simps[simp del]
lemma ftype_preservation''''':
"⟦find_path_rec_f P ctx cl (prefix @ [cld']) = Some (prefix @ cld' # path'');
find_type_f P ctx_def cl = Some ty; fields_f P ty = Some fs;
ftype_in_path_f P path'' f = Some ty_f;
(set (map (λ(cl, f, ty). f) cl_f_ty_list)) ∩ (set fs) = {}⟧
⟹ ftype_in_fds_f P ctx (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) f = ty_opt_bot_opt None"
apply(clarsimp simp add: fields_f_def split: option.splits) apply(rename_tac path)
apply(case_tac cl) apply(simp add: find_path_rec_f.simps) apply(clarsimp split: fqn.splits option.splits)
apply(rename_tac dcl ctx'' cld'') apply(case_tac ctx'') apply(case_tac ctx) apply(clarsimp simp add: find_path_f_def)
apply(frule_tac prefix = "prefix @ [cld']" and suffix = path'' and prefix' = "[]" in fpr_same_suffix[rule_format]) apply(simp)
apply(clarsimp) apply(drule ftype_fields) apply(cut_tac fields_non_intersection) apply(force) apply(force)
done
declare find_path_rec_f.simps[simp]
lemma ftype_preservation'''':
"∀suffix. find_path_rec_f P ctx cl prefix = Some (prefix @ suffix) ⟶ wf_program P ⟶
(∀(ctx, cld) ∈ set suffix.
(∀prefix' suffix'. find_path_rec_f P ctx (cl_fqn (fqn_def (class_name_f cld))) prefix' = Some (prefix' @ suffix') ∧
ftype_in_path_f P suffix' f = Some ty ⟶ ftype_in_path_f P suffix f = Some ty))"
supply [[simproc del: defined_all]]
apply(induct_tac P ctx cl prefix rule: find_path_rec_f.induct)
apply(simp)
apply(clarsimp split: option.splits)
apply(subgoal_tac "∀aa ba aaa bb.
(a = aaa ∧ b = bb ∧ aa = aaa ∧ ba = bb)
⟶ (∀suffix. find_path_rec_f P aaa (superclass_name_f bb) (path @ [(aaa, bb)]) = Some (path @ (aaa, bb) # suffix) ⟶
(∀x∈set suffix.
(λ(ctx, cld). (∃prefix' suffix'.
case_option None (case_prod (λctx' cld. find_path_rec_f P ctx' (superclass_name_f cld) (prefix' @ [(ctx', cld)]))) (find_cld_f P ctx (fqn_def (class_name_f cld))) =
Some (prefix' @ suffix') ∧
ftype_in_path_f P suffix' f = Some ty) ⟶
ftype_in_path_f P suffix f = Some ty)
x))")
defer
apply(thin_tac _)+
apply(force)
apply(clarsimp)
apply(frule path_append) apply(clarify)
apply(erule_tac x = "tl suffix" in allE)
apply(clarsimp)
apply(erule disjE)
apply(clarify)
apply(case_tac fqn)
apply(clarsimp simp add: class_name_f_def split: cld.splits)
apply(frule find_cld_name_eq) apply(frule_tac ctx = a in find_cld_name_eq)
apply(clarsimp simp add: class_name_f_def split: cld.splits)
apply(rename_tac list1 cl list2 list3)
apply(frule_tac path = "prefix' @ suffix'" in path_append) apply(clarsimp)
apply(frule_tac prefix = "path @ [(ab, cld_def list1 cl list2 list3)]" and suffix = path'' and
prefix' = "prefix' @ [(ab, cld_def list1 cl list2 list3)]" and suffix' = path''a in fpr_same_suffix[rule_format])
apply(clarsimp) apply(clarsimp)
apply(drule_tac x = "(aa, ba)" in bspec, simp)
apply(clarsimp)
apply(subgoal_tac
"(∃prefix' suffix'.
find_path_rec_f P ab (superclass_name_f bb) (prefix' @ [(ab, bb)]) = Some (prefix' @ suffix') ∧ ftype_in_path_f P suffix' f = Some ty)")
apply(clarsimp)
apply(subgoal_tac "ftype_in_fds_f P a (class_fields_f b) f = ty_opt_bot_opt None") apply(simp)
apply(frule_tac cld' = b in wf_cld_from_lu) apply(simp) apply(erule wf_classE) apply(erule wf_class_cE)
apply(clarsimp simp add: superclass_name_f_def class_fields_f_def)
apply(rule ftype_preservation''''') apply(simp+)
apply(force)
done
lemma ftype_preservation''':
"⟦find_path_f P ctx' cl = Some suffix; wf_program P; (ctx, cld) ∈ set suffix⟧
⟹ ∀prefix' suffix'.
find_path_rec_f P ctx (cl_fqn (fqn_def (class_name_f cld))) prefix' = Some (prefix' @ suffix') ∧ ftype_in_path_f P suffix' f = Some ty ⟶
ftype_in_path_f P suffix f = Some ty"
apply(cut_tac x = "(ctx, cld)" in ftype_preservation''''[of _ _ _ "[]", rule_format]) apply(simp add: find_path_f_def)+ done
lemma ftype_preservation'':
"⟦find_path_f P ctx' cl = Some path; wf_program P; (ctx, cld) ∈ set path;
find_path_f P ctx (cl_fqn (fqn_def (class_name_f cld))) = Some path'; ftype_in_path_f P path' f = Some ty⟧
⟹ ftype_in_path_f P path f = Some ty"
apply(cut_tac ftype_preservation'''[rule_format, of _ _ _ _ _ _ "[]"]) apply(assumption+) apply(unfold find_path_f_def) apply(rule) apply(simp+) done
lemma ftype_preservation'[simplified]:
"⟦wf_program P; sty_one P ty_x_d ty_x_s; ftype P ty_x_s f ty_f⟧
⟹ ftype P ty_x_d f ty_f"
apply(case_tac ty_x_s) apply(simp add: ftype_f_def)
apply(simp add: is_sty_one_def split: option.splits)
apply(case_tac ty_x_d) apply(simp) apply(clarsimp) apply(rename_tac ctx_s dcl_s path_d ctx_d dcl_d)
apply(simp add: ftype_f_def split: option.splits)
apply(rename_tac path_s cl_s fds_s mds_s)
apply(rule ftype_preservation'') apply(simp add: class_name_f_def)+
done
lemma ftype_preservation[simplified]:
"⟦wf_program P;
∀x∈dom Γ. wf_object P H (L x) (Γ x); Γ x = Some ty_x_s; ftype P ty_x_s f ty_f_s;
L x = Some (v_oid oid_x); H oid_x = Some (ty_x_d, fs_oid); ftype P ty_x_d f ty_f_d⟧
⟹ ty_f_s = ty_f_d"
apply(drule_tac x = x in bspec, simp add: domI)
apply(erule wf_objectE)
apply(simp)
apply(clarsimp)
apply(erule sty_option.cases)
apply(clarsimp)
apply(simp add: ftype_preservation')
done
lemma map_f:
"∀cl_f_ty_list. map (λ(cl, f). fd_def cl f) cl_f_list = map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list ⟶
map (λ(cl, f). f) cl_f_list = map (λ(cl, f, ty). f) cl_f_ty_list"
by (induct cl_f_list, auto)
lemma fields_to_owner[rule_format]:
"f ∈ set (fields_in_path_f path) ⟶ (∃cld ∈ set (map snd path). ∃cl_f. fd_def cl_f f ∈ set (class_fields_f cld))"
apply(induct path) apply(simp) apply(clarsimp) apply(rename_tac cld path fd)
apply(clarsimp simp add: class_fields_f_def split: option.splits cld.splits fd.splits)
apply(force)
done
lemma ftype_in_fds_none[rule_format]:
"f ∉ (λ(cl, f, ty). f) ` set cl_f_ty_list ⟶ ftype_in_fds_f P ctx (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) f = ty_opt_bot_opt None"
by (induct cl_f_ty_list, auto)
lemma ftype_in_fds_some[rule_format]:
"(cl_f, f, ty_f) ∈ set cl_f_ty_list ∧ distinct (map (λ(cl, f, ty). f) cl_f_ty_list) ∧ find_type_f P ctx cl_f = Some ty_f
⟶ ftype_in_fds_f P ctx (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) f = ty_opt_bot_opt (Some ty_f)"
apply(induct cl_f_ty_list) apply(simp) apply(clarsimp) apply(safe) apply(force) apply(simp)
apply(frule ftype_in_fds_none) apply(force)
done
lemma no_ty_bot[THEN mp]:
"(∀x∈set cl_f_ty_list. (λ(cl, f, ty). find_type_f P ctx_def cl = Some ty) x)
⟶ ftype_in_fds_f P ctx' (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) f ≠ ty_opt_bot_bot"
apply(induct cl_f_ty_list) apply(simp) apply(clarsimp split: if_split_asm option.splits)
apply(case_tac ctx', simp)
done
lemma field_has_type'[rule_format]:
"(cl_f, f, ty_f) ∈ set cl_f_ty_list ∧
(∀(ctx, cld) ∈ set path. wf_class P cld) ∧
(ctx, cld_def dcl cl (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) mds) ∈ set path ∧
distinct (map (λ(cl, f, ty). f) cl_f_ty_list) ∧
find_type_f P ctx cl_f = Some ty_f
⟶ (∃ty'. ftype_in_path_f P path f = Some ty')"
apply(induct path) apply(simp)
apply(simp) apply(rule)
apply(elim conjE) apply(erule disjE) apply(clarsimp)
apply(subgoal_tac
"ftype_in_fds_f P ctx (class_fields_f (cld_def dcl cl (map (λ(cl, f, ty). fd_def cl f) cl_f_ty_list) mds)) f = ty_opt_bot_opt (Some ty_f)") apply(simp)
apply(simp add: class_fields_f_def) apply(rule ftype_in_fds_some) apply(force)
apply(case_tac a) apply(rename_tac ctx' cld') apply(simp) apply(case_tac "ftype_in_fds_f P ctx' (class_fields_f cld') f")
apply(rename_tac ty_opt) apply(case_tac ty_opt)
apply(clarsimp)
apply(clarsimp)
apply(clarsimp)
apply(erule wf_classE) apply(erule wf_class_cE) apply(clarsimp simp add: class_fields_f_def)
apply(frule no_ty_bot) apply(force)
done
lemma mem_class_wf:
"⟦wf_program P; cld ∈ set P⟧ ⟹ wf_class P cld"
apply(erule wf_programE) apply(drule_tac x = cld in bspec, simp) apply(clarsimp) done
lemma field_has_type:
"⟦wf_program P; fields P ty_oid (Some f_list); f ∈ set f_list⟧ ⟹ ∃ty. ftype P ty_oid f ty"
apply(simp) apply(clarsimp simp add: fields_f_def split: option.splits) apply(rename_tac path)
apply(case_tac ty_oid) apply(simp) apply(clarsimp) apply(rename_tac dcl)
apply(frule fields_to_owner) apply(clarsimp) apply(rename_tac ctx' cld cl_f)
apply(frule clds_in_path_exist) apply(drule_tac x = "(ctx', cld)" in bspec, simp) apply(clarsimp)
apply(frule mem_class_wf, simp)
apply(erule wf_classE) apply(erule wf_class_cE) apply(clarsimp simp add: class_fields_f_def)
apply(rename_tac cl_f ty_f) apply(drule_tac x = "(cl_f, f, ty_f)" in bspec, simp) apply(clarsimp)
apply(simp add: ftype_f_def)
apply(rule_tac cl_f = cl_f and ty_f = ty_f and cl_f_ty_list = cl_f_ty_list and ctx = ctx' and
dcl = dclb and cl = cla and mds = "(map fst meth_def_meth_list)" in field_has_type')
apply(simp) apply(case_tac ctx') apply(simp)
apply(clarify) apply(drule_tac cl = "cl_fqn (fqn_def dcl)" and ctxcld = "(a, b)" in all_in_path_found) apply(simp)
apply(clarsimp) apply(rule wf_cld_from_lu) apply(simp) apply(force)
done
lemma exists_three_in_five:
"var_k ∈ set (map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list) ⟶
(∃y cl var' v. (y, cl, var_k, var', v) ∈ set y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma map_xx[rule_format]:
"(y, cl, var_k, var', v) ∈ set y_cl_var_var'_v_list ⟶
(x_var var_k, x_var var') ∈ set (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma map_of_vd[rule_format]:
"∀cl_var_ty_list.
map (λ(y, cl, var, var', v). vd_def cl var) y_cl_var_var'_v_list = map (λ(cl, var, ty). vd_def cl var) cl_var_ty_list
⟶ map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list"
by (induct y_cl_var_var'_v_list, auto)
lemma mem_vd:
"vd_def cl_k var_k ∈ set (map (λ(y, cl, var, var', v). vd_def cl var) y_cl_var_var'_v_list) ⟶
var_k ∈ set (map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list)"
by (induct y_cl_var_var'_v_list, auto)
lemma exists_var':
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list);
map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
map_of (map (λ(cl, var, ty). (x_var var, ty)) cl_var_ty_list) var_k = Some ty_k⟧
⟹ ∃var'_k. map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) var_k = Some (x_var var'_k)"
apply(drule map_of_SomeD) apply(clarsimp, hypsubst_thin) apply(rename_tac cl_k var_k)
apply(subgoal_tac "var_k ∈ set (map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list)")
apply(simp (no_asm_use)) apply(clarify) apply(rename_tac y_k cl_k' var_k var'_k v_k)
apply(rule_tac x = var'_k in exI)
apply(rule map_of_is_SomeI)
apply(drule distinct_var, assumption+)
apply(rule map_xx, assumption)
by force
lemma map_y:
"⟦((y_k, cl_k, var_k, var'_k, v_k), y'_k, ty_k) ∈ set (zip y_cl_var_var'_v_list y_ty_list);
map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list⟧
⟹ (y_k, ty_k) ∈ set y_ty_list"
apply(clarsimp simp add: set_zip)
apply(drule_tac f = "λ(y, cl, var, var', v). y" in arg_cong)
apply(drule_tac f1 = "λ(y, cl, var, var', v). y" in nth_map[THEN sym])
apply(frule_tac f = "λ(y, ty). y" in arg_cong)
apply(case_tac "y_ty_list ! i")
apply(force simp add: in_set_conv_nth)
done
lemma set_zip_var'_v:
"⟦((y_k, cl_k, var_k, var'_k, v_k), y'_k, ty_k) ∈ set (zip y_cl_var_var'_v_list y_ty_list)⟧
⟹ (x_var var'_k, v_k) ∈ set (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list)"
apply(subgoal_tac "(y_k, cl_k, var_k, var'_k, v_k) ∈ set y_cl_var_var'_v_list")
by (force simp add: set_zip)+
lemma map_of_map_zip_none:
"⟦map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list;
map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)) x_G = None⟧
⟹ map_of (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list) x_G = None"
apply(drule map_length_y)
apply(clarsimp simp add: map_of_eq_None_iff)
apply(erule contrapos_np)
apply(simp only: set_map[THEN sym] fst_zip_eq)
by force
lemma map_of_map_zip_some:
"⟦distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list;
map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)) x_G = Some ty_k⟧
⟹ ∃v_k. map_of (map (λ(y, cl, var, var', y). (x_var var', y)) y_cl_var_var'_v_list) x_G = Some v_k"
apply(drule map_of_SomeD)
apply(clarsimp) apply(rename_tac y cl var var' v y')
apply(subgoal_tac "(y, cl, var, var', v) ∈ set y_cl_var_var'_v_list")
apply(rule_tac x = v in exI)
apply(rule map_of_is_SomeI)
apply(simp only: map_fst_two' distinct_x_var')
apply(force)
by (force simp add: set_zip)
lemma x'_not_in_list:
"⟦(y_k, cl_k, var_k, var'_k, v_k) ∈ set y_cl_var_var'_v_list;
x' ∉ (λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list⟧
⟹ x_var var'_k ≠ x'"
by (erule contrapos_nn, force)
lemma nth_in_set:
"⟦i < length y_ty_list; map fst y_ty_list ! i = y_k⟧ ⟹ y_k ∈ set (map fst y_ty_list)"
apply(subgoal_tac "∃i<length (map fst y_ty_list). map fst y_ty_list ! i = y_k")
apply(simp only: in_set_conv_nth[THEN sym])
apply(rule_tac x = i in exI) apply(clarsimp)
done
lemma map_one_in_two:
"y_k ∈ set (map fst y_ty_list) ⟶ (∃ty. (y_k, ty) ∈ set y_ty_list)"
by (induct y_ty_list, auto)
lemma exists_i:
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list);
(y_k, cl_ka, var_k, var'_k, v_k) ∈ set y_cl_var_var'_v_list;
(cl_k, var_k, ty_k) ∈ set cl_var_ty_list;
map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list⟧ ⟹
∃i < length cl_var_ty_list. cl_var_ty_list ! i = (cl_k, var_k, ty_k) ∧ y_cl_var_var'_v_list ! i = (y_k, cl_ka, var_k, var'_k, v_k)"
apply(simp only: in_set_conv_nth)
apply(erule_tac P = "λi. i < length cl_var_ty_list ∧ cl_var_ty_list ! i = (cl_k, var_k, ty_k)" in exE) apply(erule conjE)
apply(rule_tac x = x in exI)
apply(simp)
apply(drule_tac f = "λ(cl, var, ty). var" in arg_cong)
apply(frule_tac f1 = "λ(cl, var, ty). var" in nth_map[THEN sym])
apply(drule_tac t = "map (λ(cl, var, ty). var) cl_var_ty_list ! x" in sym)
apply(drule_tac s = "(λ(cl, var, ty). var) (cl_var_ty_list ! x)" in trans)
apply(simp)
apply(thin_tac "(λ(cl, var, ty). var) (cl_var_ty_list ! x) = (λ(cl, var, ty). var) (cl_k, var_k, ty_k)")
apply(drule sym)
apply(simp)
apply(erule exE) apply(rename_tac j) apply(erule conjE)
apply(simp only: distinct_conv_nth)
apply(erule_tac x = x in allE)
apply(drule_tac s = "map (λ(cl, var, ty). var) cl_var_ty_list" in sym)
apply(drule map_length_var)
apply(simp)
apply(erule_tac x = j in allE)
apply(simp)
done
lemma y_ty_match:
"⟦i < length cl_var_ty_list; cl_var_ty_list ! i = (cl_k, var_k, ty_k);
y_cl_var_var'_v_list ! i = (y_k, cl_ka, var_k, var'_k, v_k);
map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list⟧ ⟹
y_ty_list ! i = (y_k, ty_k)"
apply(drule_tac f = "λ(cl, var, ty). ty" in arg_cong)
apply(frule_tac f1 = "λ(cl, var, ty). ty" in nth_map[THEN sym])
apply(drule_tac t = "map (λ(cl, var, ty). ty) cl_var_ty_list ! i" in sym)
apply(frule map_length_y) apply(frule map_length_ty)
apply(drule_tac t = "length y_ty_list" in sym) apply(simp)
apply(drule_tac f = "λ(y, cl, var, var', v). y" in arg_cong)
apply(frule_tac f1 = "λ(y, cl, var, var', v). y" in nth_map[THEN sym])
apply(drule_tac t = "map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list ! i" in sym)
apply(case_tac "y_ty_list ! i") apply(simp)
done
lemma map_of_ty_k:
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list);
distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
(y_k, cl_ka, var_k, var'_k, v_k) ∈ set y_cl_var_var'_v_list;
(cl_k, var_k, ty_k) ∈ set cl_var_ty_list;
map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list;
map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list⟧
⟹ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)) (x_var var'_k) = Some ty_k"
apply(frule map_length_y)
apply(rule map_of_is_SomeI)
apply(simp only: fst_zip_eq)
apply(simp only: distinct_x_var')
apply(clarsimp)
apply(frule map_length_var)
apply(frule exists_i, simp+) apply(erule exE)
apply(drule_tac t = "length y_ty_list" in sym) apply(clarsimp)
apply(frule y_ty_match, assumption+)
apply(subgoal_tac "zip y_cl_var_var'_v_list y_ty_list ! i = (y_cl_var_var'_v_list ! i, y_ty_list ! i)")
apply(drule_tac f = "λ((y, cl, var, var', v), y', y). (x_var var', y)" in arg_cong)
apply(subgoal_tac "i < length (zip y_cl_var_var'_v_list y_ty_list)")
apply(frule_tac f1 = "λ((y, cl, var, var', v), y', y). (x_var var', y)" in nth_map[THEN sym])
apply(drule_tac t = "map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list) ! i" in sym)
apply(drule_tac s = "(λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list ! i)" in trans)
apply(simp)
apply(subgoal_tac "∃j<length (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)). map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list) ! j = (x_var var'_k, ty_k)")
apply(simp only: in_set_conv_nth[THEN sym])
apply(simp)
apply(rule_tac x = i in exI) apply(simp)
apply(force)
apply(rule nth_zip) apply(simp) apply(simp)
done
lemma map_of_ty_k':
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list); distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
x' ∉ (λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list; map fst y_cl_var_var'_v_list = map fst y_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list; map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
map_of (map (λ(cl, var, y). (x_var var, y)) cl_var_ty_list) (x_var var) = Some ty_var⟧
⟹ (if x_var (case_option var (case_x (λvar'. var') var) (map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) (x_var var))) = x' then Some ty_x_m
else (Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))
(x_var (case_option var (case_x (λvar'. var') var)
(map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) (x_var var))))) =
Some ty_var"
apply(frule exists_var') apply(simp add: weaken_list_var) apply(simp) apply(clarsimp split del: if_split) apply(clarsimp)
apply(drule map_of_SomeD)+ apply(clarsimp split del: if_split) apply(frule x'_not_in_list, simp+)
apply(frule map_of_ty_k) apply(simp add: weaken_list_y weaken_list_var)+
done
lemma var_not_var'_x':
"⟦Γ (x_var var) = Some ty_var; L (x_var var) = Some v_var;
∀x∈set y_cl_var_var'_v_list. L (x_var ((λ(y, cl, var, var', v). var') x)) = None; L x' = None⟧
⟹ (Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)) ++ Map.empty(x' ↦ ty_x_d)) (x_var var) = Some ty_var"
apply(subgoal_tac "x_var var ≠ x'")
apply(simp add: map_add_def)
apply(subgoal_tac "map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)) (x_var var) = None")
apply(simp)
apply(clarsimp simp add: map_of_eq_None_iff set_zip)
apply(rename_tac y_k cl_k var_k v_k y'_k ty_k i)
apply(drule_tac x = "(y_k, cl_k, var_k, var, v_k)" in bspec, simp)
apply(force)
by force
lemma same_el:
"⟦distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
i < length y_cl_var_var'_v_list;
(y_i, cl_i, var_i, var'_i, v_i) = y_cl_var_var'_v_list ! i;
(y_j, cl_j, var_j, var'_i, v_j) ∈ set y_cl_var_var'_v_list⟧
⟹ (y_i, cl_i, var_i, var'_i, v_i) = (y_j, cl_j, var_j, var'_i, v_j)"
apply(simp only: in_set_conv_nth) apply(clarsimp) apply(rename_tac j)
apply(simp only: distinct_conv_nth)
apply(erule_tac x = i in allE) apply(simp)
apply(erule_tac x = j in allE) apply(simp)
apply(drule sym) apply(simp)
done
lemma same_y:
"⟦map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list;
i < length y_cl_var_var'_v_list;
(y'_k, ty_k) = y_ty_list ! i; y_cl_var_var'_v_list ! i = (y_k, cl_k, var_k, var'_k, v_k)⟧
⟹ y'_k = y_k"
apply(drule_tac f = "λ(y, cl, var, var', v). y" in arg_cong)
apply(frule_tac f1 = "λ(y, cl, var, var', v). y" in nth_map[THEN sym])
apply(drule_tac f = fst in arg_cong) apply(simp)
apply(frule map_length_y) apply(simp)
done
lemma map_map_zip_y':
"map fst y_y'_list = map fst y_ty_list ⟹
map snd y_y'_list = map fst (map (λ((y, y'), yy, ty). (y', ty)) (zip y_y'_list y_ty_list))"
apply(rule nth_equalityI)
apply(induct y_y'_list) apply(simp) apply(clarsimp) apply(frule map_length_y') apply(simp)
apply(clarsimp)
apply(case_tac "y_y'_list ! i")
apply(case_tac "y_ty_list ! i")
apply(clarsimp)
apply(subgoal_tac "i < length (map (λ((y, y'), yy, ty). (y', ty)) (zip y_y'_list y_ty_list))")
apply(frule_tac f = fst and xs = "map (λ((y, y'), yy, ty). (y', ty)) (zip y_y'_list y_ty_list)" in nth_map)
apply(simp)
apply(subgoal_tac "length (map (λ((y, y'), yy, ty). (y', ty)) list) = length list" for list)
apply(simp) apply(frule map_length_y') apply(simp)
apply(simp only: map_length_list)
done
lemma map_map_zip_ty:
"map fst y_y'_list = map fst y_ty_list ⟹
map snd (map (λ((y, y'), yy, ty). (y', ty)) (zip y_y'_list y_ty_list)) = map snd y_ty_list"
apply(frule map_length_y')
apply(rule nth_equalityI)
apply(induct y_ty_list) apply(simp) apply(simp)
apply(clarsimp)
apply(case_tac "y_y'_list ! i")
apply(case_tac "y_ty_list ! i")
apply(simp)
done
lemma map_y_yy:
"⟦i < length y_y'_list; i < length y_ty_list;
map fst y_y'_list = map fst y_ty_list;
y_y'_list ! i = (y, y'); y_ty_list ! i = (yy, ty)⟧ ⟹
y = yy"
apply(drule_tac f = fst in arg_cong)
apply(frule_tac f1 = fst in nth_map[THEN sym])
by simp
lemma var_k_of_ty_k:
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list); distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
x' ∉ (λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list;
map fst y_cl_var_var'_v_list = map fst y_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list;
map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
(if x = x_this then Some ty_x_m else map_of (map (λ(cl, var, y). (x_var var, y)) cl_var_ty_list) x) = Some ty_x⟧
⟹ (if (case if x = x_this then Some x' else map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) x of None ⇒ x | Some x' ⇒ x') = x'
then Some ty_x_m
else (Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))
(case if x = x_this then Some x' else map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) x of None ⇒ x | Some x' ⇒ x')) =
Some ty_x"
apply(clarsimp) apply(rule) apply(rule) apply(simp) apply(clarsimp)
apply(frule exists_var') apply(simp add: weaken_list_var) apply(simp) apply(clarsimp split del: if_split)
apply(drule map_of_SomeD)+ apply(clarsimp split del: if_split) apply(frule x'_not_in_list, simp+)
apply(frule map_of_ty_k) apply(simp add: weaken_list_y weaken_list_var)+
done
lemma x_var_not_this: "(if x_var var = x_this then Some x' else Q) = Q" by simp
lemma subtype_through_tr:
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list); distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
x' ∉ (λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list;
map fst y_cl_var_var'_v_list = map fst y_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list;
map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
is_sty_one P ty_x ty_var = Some True; (if x = x_this then Some ty_x_m else map_of (map (λ(cl, var, y). (x_var var, y)) cl_var_ty_list) x) = Some ty_x;
map_of (map (λ(cl, var, y). (x_var var, y)) cl_var_ty_list) (x_var var) = Some ty_var⟧
⟹ sty_option P (if (case if x = x_this then Some x' else map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) x of None ⇒ x | Some x' ⇒ x') =
x'
then Some ty_x_m
else (Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))
(case if x = x_this then Some x' else map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) x of None ⇒ x | Some x' ⇒ x'))
(if x_var (case_option var (case_x (λvar'. var') var) (map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) (x_var var))) = x' then Some ty_x_m
else (Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))
(x_var (case_option var (case_x (λvar'. var') var)
(if x_var var = x_this then Some x' else map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) (x_var var)))))"
apply(rule_tac ty = ty_x and ty' = ty_var in sty_optionI)
apply(simp add: var_k_of_ty_k)
apply(simp only: x_var_not_this) apply(rule map_of_ty_k') apply(simp+)
done
lemma subtypes_through_tr:
"⟦distinct (map (λ(cl, var, ty). var) cl_var_ty_list); distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list);
x' ∉ (λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list; map fst y_cl_var_var'_v_list = map fst y_ty_list;
map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list; map (λ(y, cl, var, u). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list;
∀x∈set y_y'_list. case_prod (λy. (=) (case if y = x_this then Some x' else map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list) y of
None ⇒ y | Some x' ⇒ x')) x;
∀x∈set y_ty_lista. (λ(y, ty). sty_option P (if y = x_this then Some ty_x_m else map_of (map (λ(cl, var, y). (x_var var, y)) cl_var_ty_list) y) (Some ty)) x;
map fst y_y'_list = map fst y_ty_lista; (y, y') = y_y'_list ! i; (yy, ty) = y_ty_lista ! i; i < length y_y'_list; i < length y_ty_lista⟧ ⟹
sty_option P (if y' = x' then Some ty_x_m else (Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list))) y') (Some ty)"
apply(drule_tac x = "(y, y')" in bspec, simp) apply(drule_tac x = "(yy, ty)" in bspec, simp) apply(clarsimp split del: if_split)
apply(frule_tac y_ty_list = y_ty_lista in map_y_yy, assumption+) apply(erule sty_option.cases) apply(clarsimp split del: if_split)
apply(rule_tac ty = tya in sty_optionI, (simp add: var_k_of_ty_k)+)
done
lemma map_override_get:
"(Γ ++ (λu. if u = x' then Some ty_x_d else None)) x' = Some ty_x_d"
apply(simp add: map_add_def)
done
lemma s_induct':
"⟦⋀ss. ∀s∈set ss. P s ⟹ P (s_block ss); ⋀list x. P (s_ass list x); ⋀list1 x list2. P (s_read list1 x list2); ⋀x1 list x2. P (s_write x1 list x2);
⋀x1 x2 s1 s2. ⟦P s1; P s2⟧ ⟹ P (s_if x1 x2 s1 s2); ⋀list1 x list2 list3. P (s_call list1 x list2 list3); ⋀list ctx cl. P (s_new list ctx cl)⟧
⟹ P s"
by (metis s.induct)
lemma wf_tr_stmt_in_G':
"∀s'. distinct (map (λ(cl, var, ty). var) cl_var_ty_list)
∧ distinct (map (λ(y, cl, var, var', v). var') y_cl_var_var'_v_list)
∧ x' ∉ (λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list
∧ map (λ(y, cl, var, var', v). y) y_cl_var_var'_v_list = map fst y_ty_list
∧ map (λ(cl, var, ty). ty) cl_var_ty_list = map snd y_ty_list
∧ map (λ(y, cl, var, var', v). var) y_cl_var_var'_v_list = map (λ(cl, var, ty). var) cl_var_ty_list
∧ is_sty_one P ty_x_d ty_x_m = Some True
∧ wf_stmt P ((map_of (map (λ(cl, var, ty). (x_var var, ty)) cl_var_ty_list))(x_this ↦ ty_x_m)) s'
∧ tr_s ((map_of (map (λ(y, cl, var, var', v). (x_var var, x_var var')) y_cl_var_var'_v_list))(x_this ↦ x')) s' s''
⟶ wf_stmt P ((Γ ++ map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)))(x' ↦ ty_x_m)) s''"
apply(rule s_induct')
apply(clarsimp)
apply(erule tr_s.cases, simp_all) apply(clarsimp)
apply(erule wf_stmtE, simp_all) apply(clarsimp)
apply(rule wf_blockI) apply(clarsimp) apply(rename_tac s'_s''_list s' s'')
apply(drule_tac x = "(s', s'')" in bspec, simp)+ apply(clarsimp)
apply(clarsimp) apply(rename_tac var x s')
apply(erule tr_s.cases, simp+) apply(erule wf_stmtE, simp_all)
apply(erule sty_option.cases) apply(rule wf_var_assignI) apply(clarsimp split del: if_split)
apply(rule_tac ty_x = ty in subtype_through_tr, simp+)
apply(clarsimp) apply(rename_tac var x f s')
apply(erule tr_s.cases, simp+) apply(erule wf_stmtE, simp_all)
apply(erule sty_option.cases) apply(clarsimp split del: if_split) apply(rename_tac f ty_x var x ty_f ty_var)
apply(rule wf_field_readI) apply(simp add: var_k_of_ty_k) apply(simp)
apply(rule_tac ty' = ty_var in sty_optionI) apply(simp) apply(rule map_of_ty_k', simp+)
apply(clarsimp) apply(rename_tac x f y s')
apply(erule tr_s.cases, simp+) apply(erule wf_stmtE, simp_all)
apply(erule sty_option.cases) apply(clarsimp split del: if_split) apply(rename_tac f ty_x x y ty_y ty_f)
apply(rule wf_field_writeI) apply(simp add: var_k_of_ty_k) apply(simp)
apply(rule sty_optionI, (simp add: var_k_of_ty_k)+)
apply(clarsimp) apply(rename_tac x y s1 s2 s')
apply(erule tr_s.cases, simp+) apply(erule wf_stmtE, simp_all) apply(rule wf_ifI)
apply(erule disjE)
apply(rule disjI1) apply(erule sty_option.cases) apply(clarsimp split del: if_split)
apply(rule sty_optionI, (simp add: var_k_of_ty_k split del: if_split)+)
apply(rule disjI2) apply(erule sty_option.cases) apply(clarsimp split del: if_split)
apply(rule sty_optionI, (simp add: var_k_of_ty_k)+)
apply(clarsimp)
apply(clarsimp)
apply(clarsimp) apply(rename_tac var x meth ys s')
apply(erule tr_s.cases, simp+) apply(erule wf_stmtE, simp_all) apply(clarsimp split del: if_split)
apply(rule_tac y_ty_list = "map (λ((y, y'), (yy, ty)). (y', ty)) (zip y_y'_list y_ty_lista)" in wf_mcallI[simplified])
apply(force simp add: map_map_zip_y'[simplified])
apply(simp add: var_k_of_ty_k)
apply(force simp add: map_map_zip_ty[simplified])
apply(clarsimp simp add: set_zip split del: if_split) apply(simp add: subtypes_through_tr)
apply(erule sty_option.cases) apply(clarsimp split del: if_split) apply(rule sty_optionI, (simp add: map_of_ty_k')+)
apply(clarsimp) apply(rename_tac var ctx cl s')
apply(erule tr_s.cases, simp+) apply(erule wf_stmtE, simp_all) apply(clarsimp)
apply(rule wf_newI) apply(simp)
apply(erule sty_option.cases) apply(clarsimp split del: if_split) apply(rule sty_optionI, (simp add: map_of_ty_k')+)
done
lemma wf_object_heap:
"⟦wf_object P H v_opt (Some ty'); is_sty_one Pa ty_y_s ty_f = Some True; H oid_x = Some (ty_x_d, fs_oid)⟧
⟹ wf_object P (H(oid_x ↦ (ty_x_d, fs_oid(f ↦ v)))) v_opt (Some ty')"
apply(erule wf_objectE) apply(clarsimp)
apply(rule wf_nullI, simp)
apply(erule sty_option.cases) apply(clarsimp split: option.splits)
apply(rule wf_objectI) apply(force intro: sty_optionI)
done
lemma not_dom_is_none:
"((λ(y, cl, var, var', v). x_var var') ` set y_cl_var_var'_v_list ∩ Map.dom L = {})
⟹ (∀x∈set y_cl_var_var'_v_list. (λ(y, cl, var, var', v). L (x_var var') = None) x)"
by force
lemma type_to_val:
"⟦wf_varstate P Γ H L; sty_option P (Γ x) (Γ y)⟧ ⟹ ∃v w. L x = Some v ∧ L y = Some w"
apply(erule sty_option.cases) apply(clarsimp) apply(erule wf_varstateE)
apply(frule_tac x = x in bspec, simp add: domI) apply(drule_tac x = y in bspec, simp add: domI)
apply(elim wf_objectE) by (simp+)
lemma find_path_fields[THEN mp]:
"find_path_ty_f P ty = Some path ⟶ (∃fs. fields_in_path_f path = fs)"
by (force)
lemma replicate_eq_length:
"replicate x c = replicate y c ⟹ x = y"
apply(subgoal_tac "length (replicate x c) = length (replicate y c)") apply(thin_tac _)
apply(subgoal_tac "length (replicate x c) = x")
apply(subgoal_tac "length (replicate y c) = y")
by simp_all
lemma string_infinite:
"infinite (UNIV :: string set)"
apply(simp add: infinite_iff_countable_subset)
apply(rule_tac x = "λn. replicate n c" in exI) apply(rule linorder_injI)
apply(clarify) apply(frule replicate_eq_length) apply(simp)
done
lemma x_infinite:
"infinite (UNIV :: x set)"
apply(simp add: infinite_iff_countable_subset)
apply(rule_tac x = "λn. if n = 0 then x_this else x_var (replicate n c)" in exI)
apply(rule linorder_injI) apply(clarsimp)
done
lemma fresh_oid:
"wf_heap P H ⟹ (∃oid. oid ∉ dom H)"
apply(erule wf_heapE)
apply(cut_tac infinite_UNIV_nat) apply(frule_tac A = "dom H" in ex_new_if_finite)
apply(assumption) apply(simp)
done
lemma fresh_x:
"finite A ⟹ ∃x::x. x ∉ A"
apply(cut_tac x_infinite) apply(frule_tac A = A in ex_new_if_finite)
apply(assumption) apply(simp)
done
lemma fresh_var_not_in_list:
"finite (A::x set) ⟹ ∃var::var. x_var var ∉ A ∧ var ∉ set list"
apply(cut_tac x_infinite) apply(subgoal_tac "finite (insert x_this A)")
apply(frule_tac F = "insert x_this A" and G = "x_var ` set list" in finite_UnI) apply(simp)
apply(frule_tac A = "insert x_this A ∪ x_var ` set list" in ex_new_if_finite)
apply(assumption) apply(erule exE) apply(clarsimp) apply(case_tac a) apply(force+)
done
lemma fresh_vars[rule_format]:
"finite (A::x set) ⟶ (∃list::var list. length list = i ∧ x_var` set list ∩ A = {} ∧ distinct list)"
apply(induct i) apply(simp)
apply(clarsimp) apply(frule fresh_var_not_in_list) apply(erule exE)
apply(rule_tac x = "var#list" in exI) apply(simp)
done
lemma fresh_x_not_in_vars':
"finite A ⟹ ∃x'. x' ∉ A ∧ x' ∉ (x_var ` set vars')"
apply(subgoal_tac "finite (x_var ` set vars')") apply(frule_tac G = "x_var ` set vars'" in finite_UnI) apply(assumption)
apply(cut_tac x_infinite) apply(frule_tac A = "A ∪ x_var ` set vars'" in ex_new_if_finite)
apply(simp) apply(simp) apply(simp)
done
lemma lift_opts_ft_length[rule_format]:
"∀tys. lift_opts (map (case_vd (λclk vark. find_type_f P ctx_o clk)) vds) = Some tys ⟶ length tys = length vds"
by (induct vds, auto split: vd.splits option.splits)
lemma fpr_mem_has_path'[rule_format]:
"∀suffix. find_path_rec_f P ctx cl prefix = Some (prefix @ suffix) ⟶
(∀(ctx', cld') ∈ set suffix. ∀prefix'.
(∃suffix'. find_path_rec_f P ctx' (cl_fqn (fqn_def (class_name_f cld'))) prefix' = Some suffix'))"
supply [[simproc del: defined_all]]
apply(induct_tac P ctx cl prefix rule: find_path_rec_f.induct)
apply(simp)
apply(clarsimp split: option.splits)
apply(subgoal_tac "∀aa ba aaa bb.
(a = aaa ∧ b = bb ∧ aa = aaa ∧ ba = bb)
⟶ (∀suffix. find_path_rec_f P aaa (superclass_name_f bb) (path @ [(aaa, bb)]) = Some (path @ (aaa, bb) # suffix) ⟶
(∀x∈set suffix.
(λ(ctx', cld').
∀prefix'. ∃suffix'. case_option None (case_prod (λctx' cld. find_path_rec_f P ctx' (superclass_name_f cld) (prefix' @ [(ctx', cld)]))) (find_cld_f P ctx' (fqn_def (class_name_f cld'))) =
Some suffix')
x))")
defer
apply(thin_tac _)+
apply(force)
apply(thin_tac "⋀aa ba x y.
⟦a = aa ∧ b = ba; x = aa ∧ y = ba⟧
⟹ ∀suffix.
find_path_rec_f P aa (superclass_name_f ba) (path @ [(aa, ba)]) =
Some (path @ (aa, ba) # suffix) ⟶
(∀x∈set suffix.
case x of
(ctx', cld') ⇒
∀prefix'.
∃suffix'.
case_option None
(λ(ctx', cld).
find_path_rec_f P ctx' (superclass_name_f cld) (prefix' @ [(ctx', cld)]))
(find_cld_f P ctx' (fqn_def (class_name_f cld'))) =
Some suffix')")
apply(clarsimp)
apply(frule path_append) apply(clarify)
apply(erule_tac x = "tl suffix" in allE)
apply(clarsimp)
apply(erule disjE)
apply(clarify)
apply(clarsimp simp add: class_name_f_def split: cld.splits)
apply(rename_tac list1 cl list2 list3)
apply(case_tac fqn) apply(clarsimp) apply(frule find_cld_name_eq)
apply(clarsimp simp add: class_name_f_def split: cld.splits)
apply(frule_tac suffix = path'' and prefix' = " prefix' @ [(a, cld_def list1 cl list2 list3)]" in fpr_same_suffix') apply(simp) apply(simp)
apply(drule_tac x = "(aa, ba)" in bspec, simp) apply(clarsimp split: option.splits)
done
lemma fpr_mem_has_path:
"⟦find_path_f P ctx cl = Some suffix; (ctx', cld') ∈ set suffix⟧ ⟹
∃suffix'. find_path_rec_f P ctx' (cl_fqn (fqn_def (class_name_f cld'))) [] = Some suffix'"
apply(cut_tac x = "(ctx', cld')" in fpr_mem_has_path'[of _ _ _ "[]"]) apply(simp add: find_path_f_def)+ done
lemma mtype_to_find_md:
"⟦wf_program P; mtype_f P ty_x_s m = Some (mty_def tys ty_r); is_sty_one P ty_x_d ty_x_s = Some True⟧ ⟹
∃ctx cl_r vds ss' y. find_meth_def_f P ty_x_d m = Some (ctx, meth_def_def (meth_sig_def cl_r m vds) (meth_body_def ss' y))
∧ length tys = length vds"
apply(clarsimp simp add: is_sty_one_def split: option.splits ty.splits)
apply(clarsimp simp add: mtype_f_def find_meth_def_f_def)
apply(case_tac ty_x_d) apply(simp) apply(clarsimp) apply(rename_tac path_d ctx_s dcl_s ctx_d dcl_d)
apply(rename_tac cl_s fds_s mds_s)
apply(frule fpr_mem_has_path) apply(simp) apply(clarsimp simp del: find_path_rec_f.simps)
apply(frule_tac path = path_d and m = m and mty = "mty_def tys ty_r" and path' = suffix' in mty_preservation')
apply(simp add: class_name_f_def find_path_f_def)+
apply(clarsimp simp add: mtype_f_def split: option.splits if_split_asm meth_def.splits meth_sig.splits)
apply(rename_tac meth_body a b c d e f g)
apply(case_tac meth_body) apply(simp) apply(clarsimp simp add: lift_opts_ft_length)
apply(clarsimp simp add: find_meth_def_f_def split: option.splits)
apply(frule find_md_m_match[rule_format]) apply(assumption)
done
lemma exist_lifted_values:
"⟦∀x∈dom Γ. wf_object P H (L x) (Γ x); ∀x∈set y_ty_list. (λ(y, ty). sty_option P (Γ y) (Some ty)) x⟧
⟹ ∃vs. lift_opts (map (λ(y, ty). L y) y_ty_list) = Some vs"
apply(induct y_ty_list) apply(simp) apply(clarsimp)
apply(erule sty_option.cases) apply(clarsimp) apply(drule_tac x = a in bspec, simp add: domI)
apply(erule wf_objectE) apply(simp) apply(simp)
done
lemma [iff]:
"length (tr_ss_f ((map_of (zip (map (case_vd (λcl. x_var)) vds) (map x_var vars')))(x_this ↦ x')) ss') = length ss'"
by (induct ss', auto)
lemma collect_suc_eq_lt[simp]:
"{f i |i::nat. i < Suc n} = {f i |i. i = 0} ∪ {f (Suc i) |i. i < n}"
apply(induct n) apply(simp)
apply(clarsimp)
apply(simp add: less_Suc_eq)
apply(simp add: image_Collect[THEN sym])
apply(simp add: Collect_disj_eq)
apply(blast)
done
lemma [iff]:
"∀y_ty_list vars vars' vs. length y_ty_list = length vds ∧ length vars = length vds ∧ length vars' = length vds ∧ length vs = length vds ⟶
map (λ(y, cl, var, var', v). vd_def cl var) (zip (map fst y_ty_list) (zip (map (case_vd (λcl var. cl)) vds) (zip (map (case_vd (λcl var. var)) vds) (zip vars' vs)))) = vds"
apply(induct vds) apply(simp) apply(clarsimp simp add: set_zip length_Suc_conv split: vd.splits)
done
lemma vars'_eq[rule_format]:
"∀y_ty_list vds vars vs. length y_ty_list = length vars' ∧ length vds = length vars' ∧ length vars = length vars' ∧ length vs = length vars' ⟶
(λ(y, cl, var, var', v). x_var var') ` set (zip (map fst y_ty_list) (zip (map (case_vd (λcl var. cl)) vds) (zip vars (zip vars' vs)))) = x_var ` set vars'"
apply(induct vars') apply(simp) apply(clarsimp simp add: set_zip length_Suc_conv)
done
lemma [iff]:
"∀y_ty_list vds vars vs. length y_ty_list = length vars' ∧ length vds = length vars' ∧ length vars = length vars' ∧ length vs = length vars' ⟶
map (λ(y, cl, var, var', v). var') (zip (map fst y_ty_list) (zip (map (case_vd (λcl var. cl)) vds) (zip vars (zip vars' vs)))) = vars'"
apply(induct vars') apply(simp) apply(clarsimp simp add: set_zip length_Suc_conv)
done
lemma [iff]:
"∀y_ty_list vds vars vs. length y_ty_list = length vars' ∧ length vds = length vars' ∧ length vars = length vars' ∧ length vs = length vars' ⟶
map (λ(y, cl, var, var', v). (x_var var, x_var var'))
(zip (map fst y_ty_list) (zip (map (case_vd (λcl var. cl)) vds) (zip (map (case_vd (λcl var. var)) vds) (zip vars' vs)))) =
zip (map (case_vd (λcl. x_var)) vds) (map x_var vars')"
apply(induct vars') apply(simp) apply(clarsimp simp add: set_zip length_Suc_conv split: vd.splits)
done
lemma [iff]:
"∀vds vars vars' vs. length vds = length y_ty_list ∧ length vars = length y_ty_list ∧ length vars' = length y_ty_list ∧ length vs = length y_ty_list ⟶
map (λ(y, cl, var, var', v). y) (zip (map fst y_ty_list) (zip (map (case_vd (λcl var. cl)) vds) (zip vars (zip vars' vs)))) = map fst y_ty_list"
apply(induct y_ty_list) apply(simp) apply(clarsimp simp add: set_zip length_Suc_conv)
done
lemma lift_opts_mapping:
"∀vds vars vars' vs. length vds = length y_ty_list ∧ length vars = length y_ty_list ∧ length vars' = length y_ty_list ∧ length vs = length y_ty_list ⟶
lift_opts (map (λ(y, ty). L y) y_ty_list) = Some vs ⟶
(∀x∈set (zip (map fst y_ty_list) (zip (map (case_vd (λcl var. cl)) vds) (zip (map (case_vd (λcl var. var)) vds) (zip vars' vs)))). (λ(y, cl, var, var', v). L y = Some v) x)"
apply(induct y_ty_list) apply(simp) apply(clarsimp simp add: set_zip length_Suc_conv split: vd.splits option.splits)
apply(rename_tac y1 y_ty_list v2 vs cl1 var1 var'1 v1 vds vars var'2 vars' i cl2 var2)
apply(erule_tac x = vds in allE) apply(erule_tac x = vars in allE) apply(erule_tac x = vars' in allE)
apply(simp) apply(case_tac i) apply(simp) apply(rename_tac j) apply(clarsimp)
apply(erule_tac x = "map fst y_ty_list ! j" in allE) apply(clarsimp)
apply(case_tac "zip (map (case_vd (λcl var. cl)) vds) (zip (map (case_vd (λcl var. var)) vds) (zip vars' vs)) ! j") apply(rename_tac cl1 var1 var'1 v1)
apply(erule_tac x = cl1 in allE) apply(erule_tac x = var1 in allE) apply(erule_tac x = var'1 in allE) apply(erule_tac x = v1 in allE)
apply(clarsimp) apply(erule_tac x = j in allE) apply(simp)
done
lemma length_y_ty_list_vs[rule_format]:
"∀vs. lift_opts (map (λ(y, ty). L y) y_ty_list) = Some vs ⟶ length y_ty_list = length vs"
by (induct y_ty_list, auto split: option.splits)
lemma translation_eq:
"∀x∈set (zip (tr_ss_f ((map_of (zip (map (case_vd (λcl. x_var)) vds) (map x_var vars')))(x_this ↦ x')) ss') ss').
(λ(s'', s'). tr_s ((map_of (zip (map (case_vd (λcl. x_var)) vds) (map x_var vars')))(x_this ↦ x')) s' s'') x"
apply(induct ss') apply(simp add: tr_rel_f_eq)+ done
theorem progress:
"⟦wf_config Γ (config_normal P L H S); S ≠ []⟧ ⟹ ∃config'. r_stmt (config_normal P L H S) config'"
supply [[simproc del: defined_all]]
apply(case_tac S)
apply(simp)
apply(clarsimp) apply(rename_tac s ss)
apply(case_tac s)
apply(erule_tac[1-7] wf_configE) apply(simp_all)
apply(force intro: r_blockI[simplified])
apply(clarsimp, erule wf_stmtE, simp_all, clarsimp)
apply(frule type_to_val, simp) apply(clarify) apply(frule r_var_assignI) apply(force)
apply(clarsimp, erule wf_stmtE, simp_all, clarsimp)
apply(erule wf_varstateE)
apply(drule_tac x = x in bspec, simp add: domI)
apply(erule wf_objectE) apply(clarsimp) apply(frule r_field_read_npeI) apply(force)
apply(clarsimp) apply(erule_tac ?a3.0 = "Some ty" in sty_option.cases) apply(clarsimp split: option.splits)
apply(erule wf_heapE) apply(drule_tac x = oid in bspec, simp add: domI) apply(clarsimp)
apply(rename_tac x oid ty_x_s ty_x_d fields_oid fs)
apply(frule no_field_hiding, simp+) apply(drule_tac x = f in bspec, simp) apply(clarsimp)
apply(erule wf_objectE) apply(clarsimp, frule_tac H = H in r_field_readI, simp, force)+
apply(clarsimp, erule wf_stmtE, simp_all, clarsimp)
apply(erule wf_varstateE) apply(frule_tac x = x in bspec, simp add: domI)
apply(erule wf_objectE) apply(clarsimp) apply(frule r_field_write_npeI) apply(force)
apply(clarsimp) apply(erule sty_option.cases) apply(clarsimp) apply(rename_tac ty_y ty_f)
apply(drule_tac x = y in bspec, simp add: domI) apply(clarsimp)
apply(erule sty_option.cases) apply(clarsimp split: option.splits)
apply(erule wf_objectE) apply(clarsimp)
apply(frule_tac H = H and y = y in r_field_writeI, simp, force)+
apply(clarsimp, erule wf_stmtE, simp_all, clarsimp) apply(erule disjE)
apply(frule type_to_val, simp, clarify) apply(case_tac "v = w")
apply(frule_tac y = y in r_if_trueI, force+)
apply(frule_tac y = y in r_if_falseI, force+)
apply(frule type_to_val, simp, clarify) apply(case_tac "v = w")
apply(frule_tac y = y and v = w in r_if_trueI, force+)
apply(frule_tac y = y and v = w in r_if_falseI, force+)
apply(clarsimp, erule wf_stmtE, simp_all, clarsimp) apply(rename_tac cl ctx ty var)
apply(erule sty_option.cases) apply(clarsimp) apply(rename_tac ty_cl ty_var)
apply(simp add: is_sty_one_def split: option.splits) apply(rename_tac path)
apply(frule find_path_fields) apply(erule exE)
apply(frule fresh_oid) apply(erule exE)
apply(frule_tac H = H and L = L and var = var and s_list = ss and f_list = fs in r_newI[simplified])
apply(clarsimp simp add: fields_f_def split: option.splits) apply(assumption) apply(simp) apply(force)
apply(clarsimp, erule wf_stmtE, simp_all, clarsimp)
apply(rename_tac ss y_ty_list x ty_x_s m ty_r_s var)
apply(erule wf_varstateE) apply(frule_tac x = x in bspec, simp add: domI) apply(clarsimp)
apply(erule wf_objectE) apply(clarsimp) apply(frule r_mcall_npeI) apply(force)
apply(elim sty_option.cases) apply(clarsimp split: option.splits)
apply(rename_tac ty_r_s ty_var_s ty_x_s ty_x_d fs_x)
apply(frule mtype_to_find_md, simp+) apply(clarsimp)
apply(frule_tac A = "dom L" and i = "length vds" in fresh_vars) apply(clarsimp) apply(rename_tac vars')
apply(frule exist_lifted_values) apply(simp) apply(clarify)
apply(frule_tac vars' = vars' in fresh_x_not_in_vars') apply(erule exE) apply(erule conjE)
apply(subgoal_tac "∃vars. vars = map (λvd. case vd of vd_def cl var ⇒ var) vds")
apply(erule exE) apply(subgoal_tac "length vars = length vds")
apply(frule length_y_ty_list_vs)
apply(subgoal_tac "∃T. T = (map_of (zip (map (λvd. case vd of vd_def cl var ⇒ x_var var) vds) (map x_var vars')))(x_this ↦ x')")
apply(erule exE)
apply(frule_tac H = H and P = P and meth = m and ctx = ctx and cl = cl_r and y = y and ty = ty_x_d and y_cl_var_var'_v_list =
"zip (map fst y_ty_list) (zip (map (λvd. case vd of vd_def cl var ⇒ cl) vds) (zip vars (zip vars' vs)))"
and s''_s'_list = "zip (tr_ss_f T ss') ss'" and var = var and s_list = ss and x' = x' and T = T
in r_mcallI[simplified])
apply(force) apply(simp) apply(simp) apply(simp add: vars'_eq) apply(simp) apply(assumption) apply(simp add: vars'_eq)
apply(cut_tac L = L and y_ty_list = y_ty_list in lift_opts_mapping) apply(erule_tac x = vds in allE)
apply(erule_tac x = vars in allE) apply(erule_tac x = vars' in allE) apply(erule_tac x = vs in allE)
apply(simp) apply(simp) apply(simp) apply(simp add: translation_eq) apply(simp) apply(force)
by force+
theorem wf_preservation:
"⋀Γ config.
⟦wf_config Γ config; r_stmt config config'⟧
⟹ ∃Γ'. Γ ⊆⇩m Γ' ∧ wf_config Γ' config'"
supply [[simproc del: defined_all]]
apply(erule r_stmt.cases)
apply(rule_tac[1-10] x = Γ in exI)
apply(erule_tac[1-11] wf_configE)
apply(simp_all)
apply(clarsimp) apply(erule wf_stmtE) apply(simp_all)
apply(force intro: wf_config_normalI)
apply(clarsimp) apply(erule wf_stmtE) apply(simp_all)
apply(rule wf_config_normalI, assumption+)
apply(erule sty_option.cases)
apply(rule wf_subvarstateI, assumption+, simp)
apply(erule wf_varstateE)
apply(drule_tac x = x in bspec, simp add: domI)
apply(erule wf_objectE)
apply(simp add: wf_nullI)
apply(clarsimp)
apply(rule wf_objectI)
apply(erule sty_option.cases, simp)
apply(rule sty_optionI, simp+)
apply(rule_tac ty' = ty'a in sty_transitiveI, assumption+)
apply(force intro: wf_intros)
apply(clarsimp split: option.splits) apply(erule wf_stmtE) apply(simp_all)
apply(rule wf_config_normalI, assumption+)
apply(clarsimp)
apply(rename_tac L oid H v s_list ty_oid fs_oid Γ x ty_x P f ty_f var)
apply(erule sty_option.cases)
apply(rule wf_subvarstateI, assumption, simp)
apply(clarsimp)
apply(case_tac v)
apply(clarify)
apply(rule wf_nullI, simp)
apply(clarify)
apply(rename_tac ty_f ty_var P oid_v)
apply(erule wf_heapE)
apply(drule_tac x = oid in bspec, simp add: domI)
apply(clarsimp)
apply(rename_tac H P fs_oid)
apply(erule wf_varstateE)
apply(frule_tac x = x in bspec, simp add: domI)
apply(clarsimp)
apply(erule wf_objectE)
apply(simp)
apply(erule sty_option.cases)
apply(clarsimp split: option.splits)
apply(rename_tac L Γ H oid_x ty_x_d ty_x_s P)
apply(frule_tac ty_x_s = ty_x_s in no_field_hiding, simp+)
apply(drule_tac x = f in bspec, simp)
apply(clarsimp)
apply(frule ftype_preservation[simplified], assumption+)
apply(clarsimp)
apply(rename_tac ty_f)
apply(erule wf_objectE)
apply(simp)
apply(clarsimp)
apply(erule sty_option.cases)
apply(clarsimp split: option.splits)
apply(rename_tac H oid_v ty_f P ty_v fs_v)
apply(rule wf_objectI)
apply(rule sty_optionI, simp+)
apply(rule sty_transitiveI, assumption+)
apply(force intro: wf_intros)
apply(clarsimp, hypsubst_thin) apply(erule wf_stmtE) apply(simp_all)
apply(clarsimp split: option.splits) apply(rule)
apply(erule wf_varstateE) apply(clarsimp) apply(rename_tac Γ P H)
apply(drule_tac x = xa in bspec, simp add: domI)
apply(erule wf_objectE) apply(simp) apply(clarsimp)
apply(elim sty_option.cases) apply(simp)
apply(erule sty_option.cases)
apply(clarsimp)
apply(rule wf_config_normalI)
apply(assumption)
apply(rename_tac L oid_x v H ss Γ x ty_x_s f y ty_y_s ty_f P ty_x_d fs_oid)
apply(erule wf_heapE)
apply(rule wf_heapI) apply(simp)
apply(rule ballI) apply(clarsimp simp add: map_add_def) apply(rule)
apply(clarsimp) apply(drule_tac x = oid_x in bspec, simp add: domI) apply(clarsimp)
apply(drule_tac x = fa in bspec, simp) apply(clarsimp)
apply(rule)
apply(clarsimp) apply(case_tac v) apply(clarsimp simp add: wf_nullI) apply(clarsimp)
apply(rename_tac H P fields_x_d ty_f_d oid_v)
apply(erule wf_varstateE) apply(clarsimp)
apply(frule ftype_preservation, assumption+) apply(clarsimp)
apply(drule_tac x = y in bspec, simp add: domI) apply(clarsimp)
apply(erule_tac ?a4.0 = "Some ty_y_s" in wf_objectE) apply(simp) apply(clarsimp)
apply(erule sty_option.cases) apply(clarsimp split: option.splits)
apply(rule wf_objectI) apply(force intro: sty_optionI sty_transitiveI)
apply(clarsimp) apply(case_tac "fs_oid fa") apply(clarsimp) apply(force elim: wf_objectE)
apply(case_tac a) apply(force intro: wf_nullI)
apply(clarsimp) apply(rename_tac H P fields_x_d f ty_f_d oid_v)
apply(erule wf_varstateE) apply(clarsimp)
apply(drule_tac x = y in bspec, simp add: domI) apply(clarsimp)
apply(erule wf_objectE) apply(simp) apply(clarsimp)
apply(rule wf_objectI) apply(erule sty_option.cases) apply(clarsimp split: option.splits)
apply(safe) apply(clarsimp) apply(force intro: sty_optionI) apply(force intro: sty_optionI)
apply(drule_tac x = oid in bspec) apply(clarsimp)
apply(clarsimp) apply(drule_tac x = fa in bspec, simp)
apply(clarsimp simp add: wf_object_heap)
apply(rename_tac L oid_x v H ss Γ x ty_x_s f y ty_y_s ty_f P ty_x_d fs_x)
apply(erule wf_varstateE)
apply(rule wf_varstateI) apply(simp)
apply(clarsimp)
apply(rename_tac L Γ P H x' y')
apply(drule_tac x = x' in bspec, simp add: domI)
apply(clarsimp)
apply(erule wf_objectE)
apply(clarsimp)
apply(rule wf_nullI, simp)
apply(clarsimp)
apply(erule sty_option.cases)
apply(clarsimp split: option.splits)
apply(rename_tac H oid_x' ty_x'_s P ty_x'_d fs_x')
apply(rule wf_objectI)
apply(rule sty_optionI)
apply(clarsimp)
apply(rule conjI)
apply(clarsimp)
apply(simp)
apply(clarsimp)
apply(simp)
apply(simp)
apply(erule wf_stmtE) apply(simp_all)
apply(force intro: wf_config_normalI)
apply(erule wf_stmtE) apply(simp_all)
apply(force intro: wf_config_normalI)
apply(erule contrapos_np)
apply(erule wf_stmtE, simp_all, clarsimp)
apply(erule sty_option.cases, clarsimp)
apply(rule wf_config_normalI)
apply(assumption)
apply(rename_tac H L ss ctx cl Γ var ty' ty_var P)
apply(erule wf_heapE)
apply(rule wf_heapI) apply(simp)
apply(safe) apply(simp add: map_upd_Some_unfold) apply(split if_split_asm)
apply(clarsimp) apply(frule field_has_type, simp+)
apply(erule exE) apply(rule_tac x = ty in exI) apply(simp) apply(force intro: wf_nullI)
apply(drule_tac x = oida in bspec, simp add: domI) apply(clarsimp split: option.splits)
apply(drule_tac x = f in bspec, simp) apply(safe) apply(rule_tac x = ty'a in exI) apply(simp)
apply(erule wf_objectE) apply(clarsimp) apply(force intro: wf_nullI)
apply(erule sty_option.cases) apply(clarsimp split: option.splits)
apply(rule wf_objectI) apply(clarsimp) apply(rule conjI) apply(force)
apply(force intro: sty_optionI)
apply(rename_tac oid_new H L ss ctx cl Γ var ty_new ty_var P)
apply(erule wf_varstateE) apply(clarsimp)
apply(rule wf_varstateI) apply(simp) apply(rule ballI) apply(drule_tac x = x in bspec, simp)
apply(clarsimp) apply(rule conjI)
apply(clarsimp) apply(rule wf_objectI) apply(clarsimp) apply(force intro: sty_optionI)
apply(rule) apply(erule wf_objectE) apply(clarsimp) apply(force intro: wf_nullI)
apply(erule sty_option.cases) apply(clarsimp split: option.splits)
apply(rule wf_objectI) apply(clarsimp) apply(rule) apply(rule) apply(force)
apply(rule) apply(force intro: sty_optionI)
apply(force intro: wf_all_exI)
apply(case_tac "H oid", simp) apply(clarsimp)
apply(erule wf_stmtE, simp_all, clarsimp)
apply(frule wf_method_from_find[simplified]) apply(simp) apply(safe)
apply(erule_tac Q = "∀Γ'. Γ ⊆⇩m Γ' ⟶
~ (wf_config Γ' (config_normal Pa ((L ++ map_of (map (λ(y_XXX, cl_XXX, var_XXX, var_', y). (x_var var_', y)) y_cl_var_var'_v_list))(x' ↦ v_oid oid)) H
(map fst s''_s'_list @
s_ass vara
(case if y = x_this then Some x'
else map_of (map (λ(y_XXX, cl_XXX, var_XXX, var_', v_XXX). (x_var var_XXX, x_var var_')) y_cl_var_var'_v_list) y of
None ⇒ y | Some x' ⇒ x') #
s_list)))" in contrapos_pp) apply(simp only: not_all)
apply(rule_tac x = "Γ ++
map_of (map (λ((y, cl, var, var', v), (y', ty)). (x_var var', ty)) (zip y_cl_var_var'_v_list y_ty_list)) ++
Map.empty (x' ↦ ty_def ctx dcl)" in exI)
apply(clarsimp split del: if_split) apply(rule)
apply(clarsimp simp add: map_le_def split del: if_split) apply(rule sym)
apply(rule_tac L = L and Pa = Pa and H = H in map_of_map_and_x) apply(assumption+) apply(simp add: not_dom_is_none) apply(erule wf_varstateE) apply(clarsimp)
apply(rename_tac ss ty_x_d fs_x y_ty_list Γ x ty_x_s P meth ty_r var dcl)
apply(erule sty_option.cases) apply(clarsimp split del: if_split) apply(rename_tac ty_r ty_var P)
apply(erule wf_varstateE, clarify) apply(rename_tac L Γ P H)
apply(frule_tac x = x in bspec, simp add: domI)
apply(frule_tac x = "x_var var" in bspec, simp add: domI)
apply(clarsimp split del: if_split)
apply(erule wf_objectE, simp, clarsimp split del: if_split) apply(rename_tac P H oid)
apply(erule sty_option.cases, clarsimp split del: if_split) apply(rename_tac ty_x_d ty_x_s P)
apply(subgoal_tac "x_var var ∈ dom Γ")
apply(clarify) apply(rename_tac v_var)
apply(drule not_dom_is_none)
apply(rule wf_config_normalI)
apply(assumption)
apply(assumption)
apply(rule wf_varstateI) apply(simp only: finite_super_varstate) apply(clarsimp) apply(rule)
apply(rule wf_objectI) apply(simp) apply(rule sty_optionI, simp+)
apply(clarsimp, hypsubst_thin) apply(rule) apply(rule) apply(rule wf_objectI) apply(clarsimp) apply(rule sty_optionI, simp+)
apply(rule) apply(erule disjE)
apply(clarsimp) apply(drule map_of_SomeD) apply(clarsimp) apply(rename_tac y_k cl_k var_k var'_k v_k y'_k ty_k)
apply(frule_tac x = "(y_k, cl_k, var_k, var'_k, v_k)" in bspec) apply(force simp add: set_zip) apply(clarsimp)
apply(subgoal_tac "map_of (map (λ(y, cl, var, var', v). (x_var var', v)) y_cl_var_var'_v_list) (x_var var'_k) = Some v_k")
apply(clarsimp) apply(drule map_y) apply(simp) apply(drule_tac x = "(y_k, ty_k)" in bspec, assumption) apply(clarsimp)
apply(erule sty_option.cases) apply(clarsimp) apply(rename_tac ty_y_k ty_k P) apply(drule_tac x = y_k in bspec, simp add: domI)
apply(clarsimp) apply(case_tac v_k) apply(clarify, rule wf_nullI, simp) apply(clarsimp) apply(rename_tac oid_y_k)
apply(erule_tac ?a4.0 = "Some ty_y_k" in wf_objectE) apply(simp) apply(erule sty_option.cases)
apply(clarsimp split: option.splits) apply(rule wf_objectI) apply(clarsimp) apply(rule sty_optionI, simp+)
apply(rule_tac ty' = ty' in sty_transitiveI, assumption+)
apply(rule map_of_is_SomeI) apply(simp add: map_fst_var'[simplified]) apply(rule set_zip_var'_v, simp)
apply(clarify) apply(rename_tac x_G ty_x_G) apply(frule_tac x = x_G in bspec, simp add: domI)
apply(case_tac "map_of (map (λ((y, cl, var, var', v), y', y). (x_var var', y)) (zip y_cl_var_var'_v_list y_ty_list)) x_G")
apply(frule map_of_map_zip_none, simp+) apply(simp add: map_add_def)
apply(frule map_of_map_zip_some, simp+) apply(clarsimp)
apply(drule map_of_SomeD) apply(drule map_of_SomeD) apply(clarsimp simp add: set_zip)
apply(frule same_el, simp+) apply(drule_tac s = "(aa, ab, ac, ai, b)" in sym)
apply(clarsimp) apply(rename_tac y_k cl_k var_k v_k y'_k ty_k var'_k i)
apply(frule_tac y_k = y_k and cl_k = cl_k and var_k = var_k and var'_k = var'_k and v_k = v_k in same_y, simp+) apply(clarsimp)
apply(drule_tac x = "(y_k, ty_k)" in bspec, simp) apply(clarsimp) apply(rename_tac y_k ty_k)
apply(erule sty_option.cases) apply(clarsimp) apply(drule_tac x = y_k in bspec, simp add: domI) apply(clarsimp)
apply(drule_tac x = "(y_k, cl_k, var_k, var'_k, v_k)" in bspec) apply(drule_tac t = "(y_k, cl_k, var_k, var'_k, v_k)" in sym) apply(simp)
apply(clarsimp) apply(erule_tac ?a4.0 = "Some ty" in wf_objectE) apply(clarsimp) apply(rule wf_nullI, simp)
apply(erule sty_option.cases) apply(clarsimp split: option.splits) apply(rule wf_objectI) apply(clarsimp)
apply(rule sty_optionI, simp+) apply(rule_tac ty' = ty'a in sty_transitiveI, assumption+)
apply(clarsimp split del: if_split) apply(rule)
apply(rule wf_var_assignI) apply(frule wf_method_from_find) apply(simp) apply(erule exE) apply(erule wf_methE)
apply(case_tac "ya = x_this")
apply(clarsimp split del: if_split)
apply(rule_tac ty' = ty_var in sty_optionI) apply(simp) apply(simp) apply(case_tac ctx, clarify)
apply(frule_tac ty_r_d = ty in mty_preservation, assumption+) apply(clarify)
apply(erule sty_option.cases) apply(clarsimp) apply(rule_tac ty' = ty' in sty_transitiveI, assumption+)
apply(erule sty_option.cases) apply(clarsimp split del: if_split)
apply(frule_tac var_k = ya and ty_k = tya in exists_var') apply(drule map_of_vd) apply(assumption+) apply(erule exE) apply(clarsimp)
apply(drule_tac y = "x_var var'_k" in map_of_SomeD) apply(clarsimp split del: if_split) apply(rename_tac y_k cl_k var_k var'_k v_k)
apply(frule x'_not_in_list, assumption+) apply(clarsimp) apply(drule map_of_SomeD)
apply(clarsimp split del: if_split) apply(rename_tac cl_k' var_k ty_k) apply(case_tac ctx, clarify) apply(frule mty_preservation, assumption+)
apply(clarsimp split del: if_split) apply(drule map_of_vd) apply(frule map_of_ty_k, assumption+)
apply(rule_tac ty = ty_k and ty' = ty_var in sty_optionI) apply(simp add: map_add_def) apply(simp) apply(simp)
apply(rule_tac ty' = ty_r in sty_transitiveI) apply(assumption+)
apply(clarsimp) apply(erule disjE) apply(erule wf_methE) apply(clarsimp)
apply(frule map_of_vd[rule_format]) apply(case_tac ctx, clarify) apply(frule mty_preservation, simp+) apply(clarsimp)
apply(rename_tac P dcl cl y meth s'' s')
apply(drule_tac x = "(s'', s')" in bspec, simp)+ apply(clarsimp)
apply(cut_tac cl_var_ty_list = cl_var_ty_list and y_cl_var_var'_v_list = y_cl_var_var'_v_list and y_ty_list = y_ty_list and
P = P and ty_x_d = ty_x_d and ty_x_m = "ty_def ctx_def dcl" and x' = x' and s'' = s'' and Γ = Γ in wf_tr_stmt_in_G')
apply(clarsimp)
apply(cut_tac L = L and x' = x' and y_cl_var_var'_v_list = y_cl_var_var'_v_list and Γ = Γ and P = P and H = H and
y_ty_list = y_ty_list and ty = "ty_def ctx dcl" and ss = ss in wf_stmt_in_G')
apply(clarsimp)
apply(erule wf_objectE) apply(force) apply(force)
done
end