# HG changeset patch # User paulson # Date 1713713490 -3600 # Node ID 6d56e85f674e77ccd8527d32b89376e9bd435db4 # Parent fec5a23017b55f7c7f85f021c361088c63830f5d More proof tidying for Nominal diff -r fec5a23017b5 -r 6d56e85f674e src/HOL/Nominal/Examples/Pattern.thy --- a/src/HOL/Nominal/Examples/Pattern.thy Sat Apr 20 23:02:47 2024 +0100 +++ b/src/HOL/Nominal/Examples/Pattern.thy Sun Apr 21 16:31:30 2024 +0100 @@ -62,21 +62,23 @@ by (simp add: supp_def Collect_disj_eq del: disj_not1) instance pat :: pt_name -proof (standard, goal_cases) - case (1 x) - show ?case by (induct x) simp_all -next - case (2 _ _ x) - show ?case by (induct x) (simp_all add: pt_name2) -next - case (3 _ _ x) - then show ?case by (induct x) (simp_all add: pt_name3) +proof + fix x :: pat + show "([]::(name \ _) list) \ x = x" + by (induct x) simp_all + fix pi1 pi2 :: "(name \ name) list" + show "(pi1 @ pi2) \ x = pi1 \ pi2 \ x" + by (induct x) (simp_all add: pt_name2) + assume "pi1 \ pi2" + then show "pi1 \ x = pi2 \ x" + by (induct x) (simp_all add: pt_name3) qed instance pat :: fs_name -proof (standard, goal_cases) - case (1 x) - show ?case by (induct x) (simp_all add: fin_supp) +proof + fix x :: pat + show "finite (supp x::name set)" + by (induct x) (simp_all add: fin_supp) qed (* the following function cannot be defined using nominal_primrec, *) @@ -255,21 +257,15 @@ lemma weakening: assumes "\\<^sub>1 \ t : T" and "valid \\<^sub>2" and "\\<^sub>1 \ \\<^sub>2" shows "\\<^sub>2 \ t : T" using assms - apply (nominal_induct \\<^sub>1 t T avoiding: \\<^sub>2 rule: typing.strong_induct) - apply auto - apply (drule_tac x="(x, T) # \\<^sub>2" in meta_spec) - apply (auto intro: valid_typing) - apply (drule_tac x="\\<^sub>2" in meta_spec) - apply (drule_tac x="\ @ \\<^sub>2" in meta_spec) - apply (auto intro: valid_typing) - apply (rule typing.Let) - apply assumption+ - apply (drule meta_mp) - apply (rule valid_app_mono) - apply (rule valid_typing) - apply assumption - apply (auto simp add: pat_freshs) - done +proof (nominal_induct \\<^sub>1 t T avoiding: \\<^sub>2 rule: typing.strong_induct) + case (Abs x T \ t U) + then show ?case + by (simp add: typing.Abs valid.Cons) +next + case (Let p t \ T \ u U) + then show ?case + by (smt (verit, ccfv_threshold) Un_iff pat_freshs set_append typing.simps valid_app_mono valid_typing) +qed auto inductive match :: "pat \ trm \ (name \ trm) list \ bool" ("\ _ \ _ \ _" [50, 50, 50] 50) @@ -301,27 +297,20 @@ | "x \ \ \ \\\x:T. t\ = (\x:T. \\t\)" | "\\Base t\\<^sub>b = Base (\\t\)" | "x \ \ \ \\Bind T x t\\<^sub>b = Bind T x (\\t\\<^sub>b)" - apply finite_guess+ - apply (simp add: abs_fresh | fresh_guess)+ - done + by (finite_guess | simp add: abs_fresh | fresh_guess)+ lemma lookup_fresh: "x = y \ x \ set (map fst \) \ \(y, t)\set \. x \ t \ x \ lookup \ y" - apply (induct \) - apply (simp_all add: split_paired_all fresh_atm) - apply (case_tac "x = y") - apply (auto simp add: fresh_atm) - done + by (induct \) (use fresh_atm in force)+ lemma psubst_fresh: assumes "x \ set (map fst \)" and "\(y, t)\set \. x \ t" shows "x \ \\t\" and "x \ \\t'\\<^sub>b" using assms - apply (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts) - apply simp - apply (rule lookup_fresh) - apply (rule impI) - apply (simp_all add: abs_fresh) - done +proof (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts) + case (Var name) + then show ?case + by (metis lookup_fresh simps(1)) +qed (auto simp: abs_fresh) lemma psubst_eqvt[eqvt]: fixes pi :: "name prm" @@ -350,23 +339,21 @@ lemma psubst_forget: "(supp (map fst \)::name set) \* t \ \\t\ = t" "(supp (map fst \)::name set) \* t' \ \\t'\\<^sub>b = t'" - apply (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts) - apply (auto simp add: fresh_star_def lookup_forget abs_fresh) - apply (drule_tac x=\ in meta_spec) - apply (drule meta_mp) - apply (rule ballI) - apply (drule_tac x=x in bspec) - apply assumption - apply (drule supp_fst) - apply (auto simp add: fresh_def) - apply (drule_tac x=\ in meta_spec) - apply (drule meta_mp) - apply (rule ballI) - apply (drule_tac x=x in bspec) - apply assumption - apply (drule supp_fst) - apply (auto simp add: fresh_def) - done +proof (nominal_induct t and t' avoiding: \ rule: trm_btrm.strong_inducts) + case (Var name) + then show ?case + by (simp add: fresh_star_set lookup_forget) +next + case (Abs ty name trm) + then show ?case + apply (simp add: fresh_def) + by (metis abs_fresh(1) fresh_star_set supp_fst trm.fresh(3)) +next + case (Bind ty name btrm) + then show ?case + apply (simp add: fresh_def) + by (metis abs_fresh(1) btrm.fresh(2) fresh_star_set supp_fst) +qed (auto simp: fresh_star_set) lemma psubst_nil: "[]\t\ = t" "[]\t'\\<^sub>b = t'" by (induct t and t' rule: trm_btrm.inducts) (simp_all add: fresh_list_nil) @@ -557,17 +544,15 @@ Abs: "{x}" | Beta: "{x}" | Let: "(supp p)::name set" - apply (simp_all add: fresh_star_def abs_fresh fin_supp) - apply (rule psubst_fresh) - apply simp - apply simp - apply (rule ballI) - apply (rule psubst_fresh) - apply (rule match_vars) - apply assumption+ - apply (rule match_fresh_mono) - apply auto - done +proof (simp_all add: fresh_star_def abs_fresh fin_supp) + show "x \ t[x\u]" if "x \ u" for x t u + by (simp add: \x \ u\ psubst_fresh(1)) +next + show "\x\supp p. (x::name) \ \\u\" + if "\x\supp p. (x::name) \ t" and "\ p \ t \ \" + for p t \ u + by (meson that match_fresh_mono match_vars psubst_fresh(1)) +qed lemma typing_case_Abs: assumes ty: "\ \ (\x:T. t) : S" @@ -636,13 +621,16 @@ proof fix x assume "x \ pi \ B" then show "x \ A \ B" using pi - apply (induct pi arbitrary: x B rule: rev_induct) - apply simp - apply (simp add: split_paired_all supp_eqvt) - apply (drule perm_mem_left) - apply (simp add: calc_atm split: if_split_asm) - apply (auto dest: perm_mem_right) - done + proof (induct pi arbitrary: x B rule: rev_induct) + case Nil + then show ?case + by simp + next + case (snoc y xs) + then show ?case + apply simp + by (metis SigmaE perm_mem_left perm_pi_simp(2) pt_name2 swap_simps(3)) + qed qed lemma abs_pat_alpha': diff -r fec5a23017b5 -r 6d56e85f674e src/HOL/Nominal/Examples/W.thy --- a/src/HOL/Nominal/Examples/W.thy Sat Apr 20 23:02:47 2024 +0100 +++ b/src/HOL/Nominal/Examples/W.thy Sun Apr 21 16:31:30 2024 +0100 @@ -13,17 +13,15 @@ lemma difference_eqvt_tvar[eqvt]: fixes pi::"tvar prm" - and Xs Ys::"tvar list" + and Xs Ys::"tvar list" shows "pi\(Xs - Ys) = (pi\Xs) - (pi\Ys)" -by (induct Xs) (simp_all add: eqvts) + by (induct Xs) (simp_all add: eqvts) -lemma difference_fresh: +lemma difference_fresh [simp]: fixes X::"tvar" - and Xs Ys::"tvar list" - assumes a: "X\set Ys" - shows "X\(Xs - Ys)" -using a -by (induct Xs) (auto simp add: fresh_list_nil fresh_list_cons fresh_atm) + and Xs Ys::"tvar list" + shows "X\(Xs - Ys) \ X\Xs \ X\set Ys" + by (induct Xs) (auto simp add: fresh_list_nil fresh_list_cons fresh_atm) lemma difference_supset: fixes xs::"'a list" @@ -114,10 +112,8 @@ where "ftv_tyS (Ty T) = ((ftv (T::ty))::tvar list)" | "ftv_tyS (\[X].S) = (ftv_tyS S) - [X]" -apply(finite_guess add: ftv_ty_eqvt fs_tvar1)+ -apply(rule TrueI)+ -apply(rule difference_fresh) -apply(simp) +apply(finite_guess add: ftv_ty_eqvt fs_tvar1 | rule TrueI)+ + apply (metis difference_fresh list.set_intros(1)) apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+ done @@ -127,18 +123,21 @@ fixes pi::"tvar prm" and S::"tyS" shows "pi\(ftv S) = ftv (pi\S)" -apply(nominal_induct S rule: tyS.strong_induct) -apply(simp add: eqvts) -apply(simp only: ftv_tyS.simps) -apply(simp only: eqvts) -apply(simp add: eqvts) -done +proof (nominal_induct S rule: tyS.strong_induct) + case (Ty ty) + then show ?case + by (simp add: ftv_ty_eqvt) +next + case (ALL tvar tyS) + then show ?case + by (metis difference_eqvt_tvar ftv_ty.simps(1) ftv_tyS.simps(2) ftv_ty_eqvt ty.perm(3) tyS.perm(4)) +qed lemma ftv_Ctxt_eqvt[eqvt]: fixes pi::"tvar prm" - and \::"Ctxt" + and \::"Ctxt" shows "pi\(ftv \) = ftv (pi\\)" -by (induct \) (auto simp add: eqvts) + by (induct \) (auto simp add: eqvts) text \Valid\ inductive @@ -157,7 +156,7 @@ lemma gen_eqvt[eqvt]: fixes pi::"tvar prm" shows "pi\(gen T Xs) = gen (pi\T) (pi\Xs)" -by (induct Xs) (simp_all add: eqvts) + by (induct Xs) (simp_all add: eqvts) @@ -169,7 +168,7 @@ lemma close_eqvt[eqvt]: fixes pi::"tvar prm" shows "pi\(close \ T) = close (pi\\) (pi\T)" -by (simp_all only: eqvts) + by (simp_all only: eqvts) text \Substitution\ @@ -183,8 +182,7 @@ where "smth[X::=T] \ ([(X,T)])" -fun - lookup :: "Subst \ tvar \ ty" +fun lookup :: "Subst \ tvar \ ty" where "lookup [] X = TVar X" | "lookup ((Y,T)#\) X = (if X=Y then T else lookup \ X)" @@ -192,15 +190,15 @@ lemma lookup_eqvt[eqvt]: fixes pi::"tvar prm" shows "pi\(lookup \ X) = lookup (pi\\) (pi\X)" -by (induct \) (auto simp add: eqvts) + by (induct \) (auto simp add: eqvts) lemma lookup_fresh: fixes X::"tvar" assumes a: "X\\" shows "lookup \ X = TVar X" -using a -by (induct \) - (auto simp add: fresh_list_cons fresh_prod fresh_atm) + using a + by (induct \) + (auto simp add: fresh_list_cons fresh_prod fresh_atm) overloading psubst_ty \ "psubst :: Subst \ ty \ ty" @@ -231,9 +229,7 @@ where "\<(Ty T)> = Ty (\)" | "X\\ \ \<(\[X].S)> = \[X].(\)" -apply(finite_guess add: psubst_ty_eqvt fs_tvar1)+ -apply(rule TrueI)+ -apply(simp add: abs_fresh) +apply(finite_guess add: psubst_ty_eqvt fs_tvar1 | simp add: abs_fresh)+ apply(fresh_guess add: psubst_ty_eqvt fs_tvar1)+ done @@ -330,26 +326,26 @@ assumes a: "X\\" shows "\ = (\)[X::=\]" using a -apply(nominal_induct T avoiding: \ X T' rule: ty.strong_induct) -apply(auto simp add: ty.inject lookup_fresh) -apply(rule sym) -apply(rule subst_forget_ty) -apply(rule fresh_lookup) -apply(simp_all add: fresh_atm) -done +proof (nominal_induct T avoiding: \ X T' rule: ty.strong_induct) + case (TVar tvar) + then show ?case + by (simp add: fresh_atm(1) fresh_lookup lookup_fresh subst_forget_ty) +qed auto lemma general_preserved: fixes \::"Subst" assumes a: "T \ S" shows "\ \ \" -using a -apply(nominal_induct T S avoiding: \ rule: inst.strong_induct) -apply(auto)[1] -apply(simp add: psubst_ty_lemma) -apply(rule_tac I_All) -apply(simp add: fresh_psubst_ty) -apply(simp) -done + using a +proof (nominal_induct T S avoiding: \ rule: inst.strong_induct) + case (I_Ty T) + then show ?case + by (simp add: inst.I_Ty) +next + case (I_All X T' T S) + then show ?case + by (simp add: fresh_psubst_ty inst.I_All psubst_ty_lemma) +qed text\typing judgements\ @@ -386,74 +382,72 @@ lemma ftv_Ctxt: fixes \::"Ctxt" shows "supp \ = set (ftv \)" -apply (induct \) -apply (simp_all add: supp_list_nil supp_list_cons) -apply (rename_tac a \') -apply (case_tac a) -apply (simp add: supp_prod supp_atm ftv_tyS) -done +proof (induct \) + case Nil + then show ?case + by (simp add: supp_list_nil) +next + case (Cons c \) + show ?case + proof (cases c) + case (Pair a b) + with Cons show ?thesis + by (simp add: ftv_tyS supp_atm(3) supp_list_cons supp_prod) + qed +qed -lemma ftv_tvars: +lemma ftv_tvars: fixes Tvs::"tvar list" shows "supp Tvs = set Tvs" -by (induct Tvs) - (simp_all add: supp_list_nil supp_list_cons supp_atm) + by (induct Tvs) (simp_all add: supp_list_nil supp_list_cons supp_atm) lemma difference_supp: fixes xs ys::"tvar list" shows "((supp (xs - ys))::tvar set) = supp xs - supp ys" -by (induct xs) - (auto simp add: supp_list_nil supp_list_cons ftv_tvars) + by (induct xs) (auto simp add: supp_list_nil supp_list_cons ftv_tvars) lemma set_supp_eq: fixes xs::"tvar list" shows "set xs = supp xs" -by (induct xs) - (simp_all add: supp_list_nil supp_list_cons supp_atm) + by (induct xs) (simp_all add: supp_list_nil supp_list_cons supp_atm) nominal_inductive2 typing avoids T_LET: "set (ftv T\<^sub>1 - ftv \)" -apply (simp add: fresh_star_def fresh_def ftv_Ctxt) -apply (simp add: fresh_star_def fresh_tvar_trm) -apply assumption -apply simp -done + apply (simp_all add: fresh_star_def fresh_def ftv_Ctxt fresh_tvar_trm) + by (meson fresh_def fresh_tvar_trm) + lemma perm_fresh_fresh_aux: "\(x,y)\set (pi::tvar prm). x \ z \ y \ z \ pi \ (z::'a::pt_tvar) = z" - apply (induct pi rule: rev_induct) - apply simp +proof (induct pi rule: rev_induct) + case Nil + then show ?case + by simp +next + case (snoc x xs) + then show ?case apply (simp add: split_paired_all pt_tvar2) - apply (frule_tac x="(a, b)" in bspec) - apply simp - apply (simp add: perm_fresh_fresh) - done + using perm_fresh_fresh(1) by fastforce +qed lemma freshs_mem: fixes S::"tvar set" assumes "x \ S" - and "S \* z" + and "S \* z" shows "x \ z" -using assms by (simp add: fresh_star_def) + using assms by (simp add: fresh_star_def) lemma fresh_gen_set: fixes X::"tvar" and Xs::"tvar list" - assumes asm: "X\set Xs" + assumes "X\set Xs" shows "X\gen T Xs" -using asm -apply(induct Xs) -apply(simp) -apply(rename_tac a Xs') -apply(case_tac "X=a") -apply(simp add: abs_fresh) -apply(simp add: abs_fresh) -done + using assms by (induct Xs) (auto simp: abs_fresh) lemma close_fresh: fixes \::"Ctxt" shows "\(X::tvar)\set ((ftv T) - (ftv \)). X\(close \ T)" -by (simp add: fresh_gen_set) + by (meson fresh_gen_set) lemma gen_supp: shows "(supp (gen T Xs)::tvar set) = supp T - supp Xs" @@ -466,9 +460,7 @@ lemma close_supp: shows "supp (close \ T) = set (ftv T) \ set (ftv \)" - apply (simp add: gen_supp difference_supp ftv_ty ftv_Ctxt) - apply (simp only: set_supp_eq minus_Int_eq) - done + using difference_supp ftv_ty gen_supp set_supp_eq by auto lemma better_T_LET: assumes x: "x\\" @@ -483,22 +475,12 @@ from pi1 have pi1': "(pi \ set (ftv T\<^sub>1 - ftv \)) \* \" by (simp add: fresh_star_prod) have Gamma_fresh: "\(x,y)\set pi. x \ \ \ y \ \" - apply (rule ballI) - apply (simp add: split_paired_all) - apply (drule subsetD [OF pi2]) - apply (erule SigmaE) - apply (drule freshs_mem [OF _ pi1']) - apply (simp add: ftv_Ctxt [symmetric] fresh_def) - done - have close_fresh': "\(x, y)\set pi. x \ close \ T\<^sub>1 \ y \ close \ T\<^sub>1" - apply (rule ballI) - apply (simp add: split_paired_all) - apply (drule subsetD [OF pi2]) - apply (erule SigmaE) - apply (drule bspec [OF close_fresh]) - apply (drule freshs_mem [OF _ pi1']) - apply (simp add: fresh_def close_supp ftv_Ctxt) - done + using freshs_mem [OF _ pi1'] subsetD [OF pi2] ftv_Ctxt fresh_def by fastforce + have "\x y. \x \ set (ftv T\<^sub>1 - ftv \); y \ pi \ set (ftv T\<^sub>1 - ftv \)\ + \ x \ close \ T\<^sub>1 \ y \ close \ T\<^sub>1" + by (metis DiffE filter_set fresh_def fresh_gen_set freshs_mem ftv_Ctxt ftv_ty gen_supp member_filter pi1') + then have close_fresh': "\(x, y)\set pi. x \ close \ T\<^sub>1 \ y \ close \ T\<^sub>1" + using pi2 by auto note x moreover from Gamma_fresh perm_boolI [OF t1, of pi] have "\ \ t\<^sub>1 : pi \ T\<^sub>1" @@ -518,96 +500,81 @@ fixes T::"ty" and \::"Subst" and X Y ::"tvar" - assumes a1: "X \ set (ftv T)" - and a2: "Y \ set (ftv (lookup \ X))" + assumes "X \ set (ftv T)" + and "Y \ set (ftv (lookup \ X))" shows "Y \ set (ftv (\))" -using a1 a2 -by (nominal_induct T rule: ty.strong_induct) (auto) + using assms + by (nominal_induct T rule: ty.strong_induct) (auto) lemma ftv_tyS_subst: fixes S::"tyS" and \::"Subst" and X Y::"tvar" - assumes a1: "X \ set (ftv S)" - and a2: "Y \ set (ftv (lookup \ X))" + assumes "X \ set (ftv S)" + and "Y \ set (ftv (lookup \ X))" shows "Y \ set (ftv (\))" -using a1 a2 + using assms by (nominal_induct S avoiding: \ Y rule: tyS.strong_induct) (auto simp add: ftv_ty_subst fresh_atm) lemma ftv_Ctxt_subst: fixes \::"Ctxt" and \::"Subst" - assumes a1: "X \ set (ftv \)" - and a2: "Y \ set (ftv (lookup \ X))" +assumes "X \ set (ftv \)" + and "Y \ set (ftv (lookup \ X))" shows "Y \ set (ftv (\<\>))" -using a1 a2 -by (induct \) - (auto simp add: ftv_tyS_subst) + using assms by (induct \) (auto simp add: ftv_tyS_subst) lemma gen_preserved1: - assumes asm: "Xs \* \" + assumes "Xs \* \" shows "\ = gen (\) Xs" -using asm -by (induct Xs) - (auto simp add: fresh_star_def) + using assms by (induct Xs) (auto simp add: fresh_star_def) lemma gen_preserved2: fixes T::"ty" and \::"Ctxt" - assumes asm: "((ftv T) - (ftv \)) \* \" + assumes "((ftv T) - (ftv \)) \* \" shows "((ftv (\)) - (ftv (\<\>))) = ((ftv T) - (ftv \))" -using asm -apply(nominal_induct T rule: ty.strong_induct) -apply(auto simp add: fresh_star_def) -apply(simp add: lookup_fresh) -apply(simp add: ftv_Ctxt[symmetric]) -apply(fold fresh_def) -apply(rule fresh_psubst_Ctxt) -apply(assumption) -apply(assumption) -apply(rule difference_supset) -apply(auto) -apply(simp add: ftv_Ctxt_subst) -done + using assms +proof(nominal_induct T rule: ty.strong_induct) + case (TVar tvar) + then show ?case + apply(auto simp add: fresh_star_def ftv_Ctxt_subst) + by (metis filter.simps fresh_def fresh_psubst_Ctxt ftv_Ctxt ftv_ty.simps(1) lookup_fresh) +next + case (Fun ty1 ty2) + then show ?case + by (simp add: fresh_star_list) +qed lemma close_preserved: fixes \::"Ctxt" - assumes asm: "((ftv T) - (ftv \)) \* \" + assumes "((ftv T) - (ftv \)) \* \" shows "\ T> = close (\<\>) (\)" -using asm -by (simp add: gen_preserved1 gen_preserved2) + using assms by (simp add: gen_preserved1 gen_preserved2) lemma var_fresh_for_ty: fixes x::"var" - and T::"ty" + and T::"ty" shows "x\T" -by (nominal_induct T rule: ty.strong_induct) - (simp_all add: fresh_atm) + by (nominal_induct T rule: ty.strong_induct) (simp_all add: fresh_atm) lemma var_fresh_for_tyS: - fixes x::"var" - and S::"tyS" + fixes x::"var" and S::"tyS" shows "x\S" -by (nominal_induct S rule: tyS.strong_induct) - (simp_all add: abs_fresh var_fresh_for_ty) + by (nominal_induct S rule: tyS.strong_induct) (simp_all add: abs_fresh var_fresh_for_ty) lemma psubst_fresh_Ctxt: - fixes x::"var" - and \::"Ctxt" - and \::"Subst" + fixes x::"var" and \::"Ctxt" and \::"Subst" shows "x\\<\> = x\\" -by (induct \) - (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS) + by (induct \) (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS) lemma psubst_valid: fixes \::Subst - and \::Ctxt - assumes a: "valid \" + and \::Ctxt + assumes "valid \" shows "valid (\<\>)" -using a -by (induct) - (auto simp add: psubst_fresh_Ctxt) + using assms by (induct) (auto simp add: psubst_fresh_Ctxt) lemma psubst_in: fixes \::"Ctxt" @@ -616,17 +583,14 @@ and S::"tyS" assumes a: "(x,S)\set \" shows "(x,\)\set (\<\>)" -using a -by (induct \) - (auto simp add: calc_atm) - + using a by (induct \) (auto simp add: calc_atm) lemma typing_preserved: fixes \::"Subst" - and pi::"tvar prm" - assumes a: "\ \ t : T" + and pi::"tvar prm" + assumes "\ \ t : T" shows "(\<\>) \ t : (\)" -using a + using assms proof (nominal_induct \ t T avoiding: \ rule: typing.strong_induct) case (T_VAR \ x S T) have a1: "valid \" by fact @@ -662,14 +626,7 @@ have a2: "\<\> \ t1 : \" by fact have a3: "\<((x, close \ T1)#\)> \ t2 : \" by fact from a2 a3 show "\<\> \ Let x be t1 in t2 : \" - apply - - apply(rule better_T_LET) - apply(rule a1) - apply(rule a2) - apply(simp add: close_preserved vc) - done + by (simp add: a1 better_T_LET close_preserved vc) qed - - end