# HG changeset patch # User Christian Urban # Date 1325554930 0 # Node ID 9a63d90d1752eda4b81a02a1cdca2e6a114c6828 # Parent 5b5ade6bc88912d693dba1654414dbd177c8fc8d proved that generalisation is closed under substitution diff -r 5b5ade6bc889 -r 9a63d90d1752 Nominal/Ex/TypeSchemes1.thy --- a/Nominal/Ex/TypeSchemes1.thy Mon Jan 02 16:13:16 2012 +0000 +++ b/Nominal/Ex/TypeSchemes1.thy Tue Jan 03 01:42:10 2012 +0000 @@ -121,6 +121,9 @@ apply blast done +termination (eqvt) + by (lexicographic_order) + text {* Some Tests about Alpha-Equality *} lemma @@ -186,6 +189,18 @@ qed fun + subst_subst :: "Subst \ Subst \ Subst" ("_<_>" [100,60] 120) +where + "\<[]> = []" +| "\ <((X,T)#\')> = (X,\)#(\<\'>)" + +lemma redundant1: + fixes \1::"Subst" + and \2::"Subst" + shows "\1 \ \2 = (\1<\2>)@\1" +by (induct \2) (auto) + +fun dom :: "Subst \ name fset" where "dom [] = {||}" @@ -197,173 +212,213 @@ apply(simp_all) done -nominal_primrec - ftv :: "ty \ name fset" +lemma dom_compose: + shows "dom (\1 \ \2) = dom \1 |\| dom \2" +apply(induct rule: dom.induct) +apply(simp) +apply(simp) +by (metis sup_commute union_insert_fset) + +lemma redundant3: + fixes \1::"Subst" + and \2::"Subst" + shows "dom (\2<\1>) = (dom \1)" +by (induct \1) (auto) + +lemma dom_pi: + shows "(p \ (dom \)) = dom (map (\(X, T). (p \ X, T)) \)" +apply(induct \) +apply(auto) +done + +lemma dom_fresh_lookup: + fixes \::"Subst" + assumes "\X \ fset (dom \). atom X \ name" + shows "lookup \ name = Var name" +using assms +apply(induct \) +apply(auto simp add: fresh_at_base) +done + +lemma dom_fresh_ty: + fixes \::"Subst" + and T::"ty" + assumes "\X \ fset (dom \). atom X \ T" + shows "\ = T" +using assms +apply(induct T rule: ty.induct) +apply(auto simp add: ty.fresh dom_fresh_lookup) +done + +lemma dom_fresh_subst: + fixes \ \'::"Subst" + assumes "\X \ fset (dom \). atom X \ \'" + shows "\<\'> = \'" +using assms +apply(induct \') +apply(auto simp add: fresh_Pair fresh_Cons dom_fresh_ty) +done + + +abbreviation + "sub_list" :: "'a list \ 'a list \ bool" ("_ \ _" [60,60] 60) where - "ftv (Var X) = {|X|}" -| "ftv (T1 \ T2) = (ftv T1) |\| (ftv T2)" - unfolding eqvt_def ftv_graph_def - apply (rule, perm_simp, rule) - apply(auto)[2] - apply(rule_tac y="x" in ty.exhaust) - apply(blast) - apply(blast) - apply(simp_all) + "xs\<^isub>1 \ xs\<^isub>2 \ \x. x \ set xs\<^isub>1 \ x \ set xs\<^isub>2" + + +definition + generalises3 :: "ty \ tys \ bool" ("_ \\\\ _") +where + " T \\\\ S \ (\\ Xs T'. S = All [Xs].T'\ T = \ \ dom \ = Xs)" + + +lemma lookup_fresh: + fixes X::"name" + assumes a: "atom X \ \" + shows "lookup \ X = Var X" + using a + apply (induct \) + apply (auto simp add: fresh_Cons fresh_Pair fresh_at_base) done -termination (eqvt) - by lexicographic_order - -lemma s1: - fixes T::"ty" - shows "(X \ Y) \ T = [(X, Var Y),(Y, Var X)]" -apply(induct T rule: ty.induct) -apply(simp_all) -done +lemma lookup_dom: + fixes X::"name" + assumes a: "X |\| dom \" + shows "lookup \ X = Var X" + using a + apply (induct \) + apply(auto) + done -lemma s2: - fixes T::"ty" - shows "[] = T" -apply(induct T rule: ty.induct) -apply(simp_all) -done - -lemma perm_struct_induct_name[case_names pure zero swap]: - assumes pure: "supp p \ atom ` (UNIV::name set)" - and zero: "P 0" - and swap: "\p a b::name. \P p; a \ b\ \ P ((a \ b) + p)" - shows "P p" -apply(rule_tac S="supp p \ atom ` (UNIV::name set)" in perm_struct_induct) -using pure -apply(auto)[1] -apply(rule zero) -apply(auto) -apply(simp add: flip_def[symmetric]) -apply(rule swap) +lemma w1: + "\(X, y). (p \ X, y)) \'> = map (\(X, y). (p \ X, y)) (\<\'>)" +apply(induct \') apply(auto) done -lemma s3: - fixes T::"ty" - assumes "supp p \ atom ` (UNIV::name set)" - shows "\\. p \ T = \" -apply(induct p rule: perm_struct_induct_name) -apply(rule assms) -apply(simp) -apply(rule_tac x="[]" in exI) -apply(simp add: s2) -apply(clarify) -apply(simp) -apply(rule_tac x="[(a, Var b),(b, Var a)] \ \" in exI) -apply(simp add: compose_ty[symmetric]) -apply(simp add: s1) +lemma w2: + assumes "name |\| dom \'" + shows "\' name> = lookup (\<\'>) name" +using assms +apply(induct \') +apply(auto) +by (metis notin_empty_fset) + +lemma w3: + assumes "name |\| dom \" + shows "lookup \ name = lookup (map (\(X, y). (p \ X, y)) \) (p \ name)" +using assms +apply(induct \) +apply(auto) +by (metis notin_empty_fset) + +lemma fresh_lookup: + fixes X Y::"name" + and \::"Subst" + assumes asms: "atom X \ Y" "atom X \ \" + shows "atom X \ (lookup \ Y)" + using assms + apply (induct \) + apply (auto simp add: fresh_Cons fresh_Pair fresh_at_base ty.fresh) done -lemma s4: - fixes x::"'a::fs" - assumes "supp x \ atom ` (UNIV::name set)" - shows "\q. p \ x = q \ x \ supp q \ atom ` (UNIV::name set)" -apply(induct p rule: perm_simple_struct_induct) -apply(rule_tac x="0" in exI) -apply(auto)[1] -apply(simp add: supp_zero_perm) -apply(auto)[1] -apply(case_tac "supp (a \ b) \ range atom") -apply(rule_tac x="(a \ b) + q" in exI) +lemma test: + fixes \ \'::"Subst" + and T::"ty" + assumes "(p \ atom ` fset (dom \')) \* \" "supp All [dom \'].T \* p" + shows "\<\'> = \(X, y). (p \ X, y)) \'><\

T>>" +using assms +apply(induct T rule: ty.induct) +defer +apply(auto simp add: tys.supp ty.supp fresh_star_def)[1] +apply(auto simp add: tys.supp ty.supp fresh_star_def supp_at_base)[1] +apply(case_tac "name |\| dom \'") +apply(subgoal_tac "atom (p \ name) \ \") +apply(subst (2) lookup_fresh) +apply(perm_simp) +apply(auto simp add: fresh_star_def)[1] apply(simp) -apply(rule subset_trans) -apply(rule supp_plus_perm) -apply(simp) -apply(rule_tac x="q" in exI) +apply(simp add: w1) +apply(simp add: w2) +apply(subst w3[symmetric]) +apply(simp add:redundant3) apply(simp) -apply(rule swap_fresh_fresh) -apply(simp add: fresh_permute_left) -apply(subst perm_supp_eq) -apply(simp add: supp_swap) -apply(simp add: supp_minus_perm) -apply(simp add: fresh_star_def fresh_def) -apply(simp add: supp_atom) +apply(perm_simp) +apply(rotate_tac 2) +apply(drule_tac p="p" in permute_boolI) +apply(perm_simp) +apply(auto simp add: fresh_star_def)[1] +apply(metis notin_fset) +apply(simp add: lookup_dom) +apply(perm_simp) +apply(subst dom_fresh_ty) apply(auto)[1] -apply (metis atom_eqvt image_iff rangeI subsetD swap_atom_simps(2)) -apply(simp add: supp_swap) -using assms -apply(simp add: fresh_def) -apply(auto)[1] -apply (metis atom_eqvt image_iff rangeI subsetD swap_atom_simps(2)) -apply(simp add: fresh_permute_left) -apply(subst perm_supp_eq) -apply(simp add: supp_swap) -apply(simp add: supp_minus_perm) -apply(simp add: fresh_star_def fresh_def) -apply(simp add: supp_atom) -apply(auto)[1] -apply (metis atom_eqvt image_iff rangeI subsetD swap_atom_simps(2)) -apply(simp add: supp_swap) -using assms -apply(simp add: fresh_def) -apply(auto)[1] -apply (metis atom_eqvt image_iff rangeI subsetD swap_atom_simps(2)) -done - -lemma s5: - fixes T::"ty" - shows "supp T \ atom ` (UNIV::name set)" -apply(induct T rule: ty.induct) -apply(auto simp add: ty.supp supp_at_base) +apply(rule fresh_lookup) +apply(simp add: redundant3) +apply(simp add: dom_pi[symmetric]) +apply(perm_simp) +apply(rotate_tac 2) +apply(drule_tac p="p" in permute_boolI) +apply(perm_simp) +apply(simp add: fresh_at_base) +apply (metis in_fset) +apply(simp add: redundant3) +apply(simp add: dom_pi[symmetric]) +apply(perm_simp) +apply metis +apply(subst supp_perm_eq) +apply(simp add: supp_at_base fresh_star_def) +apply (smt Diff_iff atom_eq_iff image_iff insertI1 notin_fset) +apply(simp) done -function - generalises :: "ty \ tys \ bool" ("_ \\ _") -where - "T \\ All [Xs].T' \ (\\. \ = T)" - apply auto[1] - apply (rule_tac y="b" in tys.exhaust) - apply auto[1] - apply(simp) - apply(clarify) - apply(rule iffI) - apply(clarify) - apply(drule sym) - apply(simp add: Abs_eq_iff2) - apply(simp add: alphas) - apply(clarify) - using s4[OF s5] - apply - - apply(drule_tac x="p" in meta_spec) - apply(drule_tac x="T'a" in meta_spec) - apply(clarify) - apply(simp) - using s3 - apply - - apply(drule_tac x="q" in meta_spec) - apply(drule_tac x="T'a" in meta_spec) - apply(drule meta_mp) - apply(simp) - apply(clarify) - apply(simp) - apply(rule_tac x="\ \ \'" in exI) - apply(simp add: compose_ty) - apply(auto) - apply(simp add: Abs_eq_iff2) - apply(simp add: alphas) - apply(clarify) - apply(drule_tac x="p" in meta_spec) - apply(drule_tac x="T'" in meta_spec) - apply(clarify) - apply(simp) - apply(drule_tac x="q" in meta_spec) - apply(drule_tac x="T'" in meta_spec) - apply(drule meta_mp) - apply(simp) - apply(clarify) - apply(simp) - apply(rule_tac x="\ \ \'" in exI) - apply(simp add: compose_ty) - done - - - - +lemma + shows "T \\\\ S \ \ \\\\ \" +unfolding generalises3_def +apply(erule exE)+ +apply(erule conjE)+ +apply(rule_tac t="S" and s="All [Xs].T'" in subst) +apply(simp) +using at_set_avoiding3 +apply - +apply(drule_tac x="fset (map_fset atom Xs)" in meta_spec) +apply(drule_tac x="\" in meta_spec) +apply(drule_tac x="All [Xs].T'" in meta_spec) +apply(drule meta_mp) +apply(simp) +apply(drule meta_mp) +apply(simp add: finite_supp) +apply(drule meta_mp) +apply(simp add: finite_supp) +apply(drule meta_mp) +apply(simp add: tys.fresh fresh_star_def) +apply(erule exE) +apply(erule conjE)+ +apply(rule_tac t="All[Xs].T'" and s="p \ (All [Xs].T')" in subst) +apply(rule supp_perm_eq) +apply(assumption) +apply(perm_simp) +apply(subst substs.simps) +apply(perm_simp) +apply(simp) +apply(rule_tac x="\(X, T). (p \ X, T)) \'>" in exI) +apply(rule_tac x="p \ Xs" in exI) +apply(rule_tac x="\

T'>" in exI) +apply(rule conjI) +apply(simp) +apply(rule conjI) +defer +apply(simp add: redundant3) +apply(simp add: dom_pi[symmetric]) +apply(rule_tac t="T" and s="\'" in subst) +apply(simp) +apply(rule test) +apply(perm_simp) +apply(rotate_tac 2) +apply(drule_tac p="p" in permute_boolI) +apply(perm_simp) +apply(auto simp add: fresh_star_def) +done end