src/HOL/Nominal/Examples/Crary.thy
changeset 26966 071f40487734
parent 26677 ab629324081c
child 28042 1471f2974eb1
equal deleted inserted replaced
26965:003b5781b845 26966:071f40487734
    32 
    32 
    33 lemma perm_ty[simp]: 
    33 lemma perm_ty[simp]: 
    34   fixes T::"ty"
    34   fixes T::"ty"
    35   and   pi::"name prm"
    35   and   pi::"name prm"
    36   shows "pi\<bullet>T = T"
    36   shows "pi\<bullet>T = T"
    37   by (induct T rule: ty.weak_induct) (simp_all)
    37   by (induct T rule: ty.induct) (simp_all)
    38 
    38 
    39 lemma fresh_ty[simp]:
    39 lemma fresh_ty[simp]:
    40   fixes x::"name" 
    40   fixes x::"name" 
    41   and   T::"ty"
    41   and   T::"ty"
    42   shows "x\<sharp>T"
    42   shows "x\<sharp>T"
    43   by (simp add: fresh_def supp_def)
    43   by (simp add: fresh_def supp_def)
    44 
    44 
    45 lemma ty_cases:
    45 lemma ty_cases:
    46   fixes T::ty
    46   fixes T::ty
    47   shows "(\<exists> T\<^isub>1 T\<^isub>2. T=T\<^isub>1\<rightarrow>T\<^isub>2) \<or> T=TUnit \<or> T=TBase"
    47   shows "(\<exists> T\<^isub>1 T\<^isub>2. T=T\<^isub>1\<rightarrow>T\<^isub>2) \<or> T=TUnit \<or> T=TBase"
    48 by (induct T rule:ty.weak_induct) (auto)
    48 by (induct T rule:ty.induct) (auto)
    49 
    49 
    50 instance ty :: size ..
    50 instance ty :: size ..
    51 
    51 
    52 nominal_primrec
    52 nominal_primrec
    53   "size (TBase) = 1"
    53   "size (TBase) = 1"
    56 by (rule TrueI)+
    56 by (rule TrueI)+
    57 
    57 
    58 lemma ty_size_greater_zero[simp]:
    58 lemma ty_size_greater_zero[simp]:
    59   fixes T::"ty"
    59   fixes T::"ty"
    60   shows "size T > 0"
    60   shows "size T > 0"
    61 by (nominal_induct rule:ty.induct) (simp_all)
    61 by (nominal_induct rule: ty.strong_induct) (simp_all)
    62 
    62 
    63 section {* Substitutions *}
    63 section {* Substitutions *}
    64 
    64 
    65 fun
    65 fun
    66   lookup :: "Subst \<Rightarrow> name \<Rightarrow> trm"   
    66   lookup :: "Subst \<Rightarrow> name \<Rightarrow> trm"   
   117   by (simp_all add: fresh_list_cons fresh_list_nil)
   117   by (simp_all add: fresh_list_cons fresh_list_nil)
   118 
   118 
   119 lemma subst_eqvt[eqvt]:
   119 lemma subst_eqvt[eqvt]:
   120   fixes pi::"name prm" 
   120   fixes pi::"name prm" 
   121   shows "pi\<bullet>(t[x::=t']) = (pi\<bullet>t)[(pi\<bullet>x)::=(pi\<bullet>t')]"
   121   shows "pi\<bullet>(t[x::=t']) = (pi\<bullet>t)[(pi\<bullet>x)::=(pi\<bullet>t')]"
   122   by (nominal_induct t avoiding: x t' rule: trm.induct)
   122   by (nominal_induct t avoiding: x t' rule: trm.strong_induct)
   123      (perm_simp add: fresh_bij)+
   123      (perm_simp add: fresh_bij)+
   124 
   124 
   125 lemma subst_rename: 
   125 lemma subst_rename: 
   126   fixes c::"name"
   126   fixes c::"name"
   127   assumes a: "c\<sharp>t\<^isub>1"
   127   assumes a: "c\<sharp>t\<^isub>1"
   128   shows "t\<^isub>1[a::=t\<^isub>2] = ([(c,a)]\<bullet>t\<^isub>1)[c::=t\<^isub>2]"
   128   shows "t\<^isub>1[a::=t\<^isub>2] = ([(c,a)]\<bullet>t\<^isub>1)[c::=t\<^isub>2]"
   129 using a
   129 using a
   130 apply(nominal_induct t\<^isub>1 avoiding: a c t\<^isub>2 rule: trm.induct)
   130 apply(nominal_induct t\<^isub>1 avoiding: a c t\<^isub>2 rule: trm.strong_induct)
   131 apply(simp add: trm.inject calc_atm fresh_atm abs_fresh perm_nat_def)+
   131 apply(simp add: trm.inject calc_atm fresh_atm abs_fresh perm_nat_def)+
   132 done
   132 done
   133 
   133 
   134 lemma fresh_psubst: 
   134 lemma fresh_psubst: 
   135   fixes z::"name"
   135   fixes z::"name"
   136   assumes a: "z\<sharp>t" "z\<sharp>\<theta>"
   136   assumes a: "z\<sharp>t" "z\<sharp>\<theta>"
   137   shows "z\<sharp>(\<theta><t>)"
   137   shows "z\<sharp>(\<theta><t>)"
   138 using a
   138 using a
   139 by (nominal_induct t avoiding: z \<theta> t rule: trm.induct)
   139 by (nominal_induct t avoiding: z \<theta> t rule: trm.strong_induct)
   140    (auto simp add: abs_fresh lookup_fresh)
   140    (auto simp add: abs_fresh lookup_fresh)
   141 
   141 
   142 lemma fresh_subst'':
   142 lemma fresh_subst'':
   143   fixes z::"name"
   143   fixes z::"name"
   144   assumes "z\<sharp>t\<^isub>2"
   144   assumes "z\<sharp>t\<^isub>2"
   145   shows "z\<sharp>t\<^isub>1[z::=t\<^isub>2]"
   145   shows "z\<sharp>t\<^isub>1[z::=t\<^isub>2]"
   146 using assms 
   146 using assms 
   147 by (nominal_induct t\<^isub>1 avoiding: t\<^isub>2 z rule: trm.induct)
   147 by (nominal_induct t\<^isub>1 avoiding: t\<^isub>2 z rule: trm.strong_induct)
   148    (auto simp add: abs_fresh fresh_nat fresh_atm)
   148    (auto simp add: abs_fresh fresh_nat fresh_atm)
   149 
   149 
   150 lemma fresh_subst':
   150 lemma fresh_subst':
   151   fixes z::"name"
   151   fixes z::"name"
   152   assumes "z\<sharp>[y].t\<^isub>1" "z\<sharp>t\<^isub>2"
   152   assumes "z\<sharp>[y].t\<^isub>1" "z\<sharp>t\<^isub>2"
   153   shows "z\<sharp>t\<^isub>1[y::=t\<^isub>2]"
   153   shows "z\<sharp>t\<^isub>1[y::=t\<^isub>2]"
   154 using assms 
   154 using assms 
   155 by (nominal_induct t\<^isub>1 avoiding: y t\<^isub>2 z rule: trm.induct)
   155 by (nominal_induct t\<^isub>1 avoiding: y t\<^isub>2 z rule: trm.strong_induct)
   156    (auto simp add: abs_fresh fresh_nat fresh_atm)
   156    (auto simp add: abs_fresh fresh_nat fresh_atm)
   157 
   157 
   158 lemma fresh_subst:
   158 lemma fresh_subst:
   159   fixes z::"name"
   159   fixes z::"name"
   160   assumes a: "z\<sharp>t\<^isub>1" "z\<sharp>t\<^isub>2"
   160   assumes a: "z\<sharp>t\<^isub>1" "z\<sharp>t\<^isub>2"
   164 
   164 
   165 lemma fresh_psubst_simp:
   165 lemma fresh_psubst_simp:
   166   assumes "x\<sharp>t"
   166   assumes "x\<sharp>t"
   167   shows "((x,u)#\<theta>)<t> = \<theta><t>" 
   167   shows "((x,u)#\<theta>)<t> = \<theta><t>" 
   168 using assms
   168 using assms
   169 proof (nominal_induct t avoiding: x u \<theta> rule: trm.induct)
   169 proof (nominal_induct t avoiding: x u \<theta> rule: trm.strong_induct)
   170   case (Lam y t x u)
   170   case (Lam y t x u)
   171   have fs: "y\<sharp>\<theta>" "y\<sharp>x" "y\<sharp>u" by fact+
   171   have fs: "y\<sharp>\<theta>" "y\<sharp>x" "y\<sharp>u" by fact+
   172   moreover have "x\<sharp> Lam [y].t" by fact 
   172   moreover have "x\<sharp> Lam [y].t" by fact 
   173   ultimately have "x\<sharp>t" by (simp add: abs_fresh fresh_atm)
   173   ultimately have "x\<sharp>t" by (simp add: abs_fresh fresh_atm)
   174   moreover have ih:"\<And>n T. n\<sharp>t \<Longrightarrow> ((n,T)#\<theta>)<t> = \<theta><t>" by fact
   174   moreover have ih:"\<And>n T. n\<sharp>t \<Longrightarrow> ((n,T)#\<theta>)<t> = \<theta><t>" by fact
   182 lemma forget: 
   182 lemma forget: 
   183   fixes x::"name"
   183   fixes x::"name"
   184   assumes a: "x\<sharp>t" 
   184   assumes a: "x\<sharp>t" 
   185   shows "t[x::=t'] = t"
   185   shows "t[x::=t'] = t"
   186   using a
   186   using a
   187 by (nominal_induct t avoiding: x t' rule: trm.induct)
   187 by (nominal_induct t avoiding: x t' rule: trm.strong_induct)
   188    (auto simp add: fresh_atm abs_fresh)
   188    (auto simp add: fresh_atm abs_fresh)
   189 
   189 
   190 lemma subst_fun_eq:
   190 lemma subst_fun_eq:
   191   fixes u::trm
   191   fixes u::trm
   192   assumes h:"[x].t\<^isub>1 = [y].t\<^isub>2"
   192   assumes h:"[x].t\<^isub>1 = [y].t\<^isub>2"
   205   ultimately show ?thesis using alpha h by blast
   205   ultimately show ?thesis using alpha h by blast
   206 qed
   206 qed
   207 
   207 
   208 lemma psubst_empty[simp]:
   208 lemma psubst_empty[simp]:
   209   shows "[]<t> = t"
   209   shows "[]<t> = t"
   210 by (nominal_induct t rule: trm.induct) 
   210 by (nominal_induct t rule: trm.strong_induct) 
   211    (auto simp add: fresh_list_nil)
   211    (auto simp add: fresh_list_nil)
   212 
   212 
   213 lemma psubst_subst_psubst:
   213 lemma psubst_subst_psubst:
   214   assumes h:"c\<sharp>\<theta>"
   214   assumes h:"c\<sharp>\<theta>"
   215   shows "\<theta><t>[c::=s] = ((c,s)#\<theta>)<t>"
   215   shows "\<theta><t>[c::=s] = ((c,s)#\<theta>)<t>"
   216   using h
   216   using h
   217 by (nominal_induct t avoiding: \<theta> c s rule: trm.induct)
   217 by (nominal_induct t avoiding: \<theta> c s rule: trm.strong_induct)
   218    (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst)
   218    (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst)
   219 
   219 
   220 lemma subst_fresh_simp:
   220 lemma subst_fresh_simp:
   221   assumes a: "x\<sharp>\<theta>"
   221   assumes a: "x\<sharp>\<theta>"
   222   shows "\<theta><Var x> = Var x"
   222   shows "\<theta><Var x> = Var x"
   225 
   225 
   226 lemma psubst_subst_propagate: 
   226 lemma psubst_subst_propagate: 
   227   assumes "x\<sharp>\<theta>" 
   227   assumes "x\<sharp>\<theta>" 
   228   shows "\<theta><t[x::=u]> = \<theta><t>[x::=\<theta><u>]"
   228   shows "\<theta><t[x::=u]> = \<theta><t>[x::=\<theta><u>]"
   229 using assms
   229 using assms
   230 proof (nominal_induct t avoiding: x u \<theta> rule: trm.induct)
   230 proof (nominal_induct t avoiding: x u \<theta> rule: trm.strong_induct)
   231   case (Var n x u \<theta>)
   231   case (Var n x u \<theta>)
   232   { assume "x=n"
   232   { assume "x=n"
   233     moreover have "x\<sharp>\<theta>" by fact 
   233     moreover have "x\<sharp>\<theta>" by fact 
   234     ultimately have "\<theta><Var n[x::=u]> = \<theta><Var n>[x::=\<theta><u>]" using subst_fresh_simp by auto
   234     ultimately have "\<theta><Var n[x::=u]> = \<theta><Var n>[x::=\<theta><u>]" using subst_fresh_simp by auto
   235   }
   235   }
   652 qed (auto)
   652 qed (auto)
   653 
   653 
   654 lemma main_lemma:
   654 lemma main_lemma:
   655   shows "\<Gamma> \<turnstile> s is t : T \<Longrightarrow> valid \<Gamma> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T" 
   655   shows "\<Gamma> \<turnstile> s is t : T \<Longrightarrow> valid \<Gamma> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T" 
   656     and "\<Gamma> \<turnstile> p \<leftrightarrow> q : T \<Longrightarrow> \<Gamma> \<turnstile> p is q : T"
   656     and "\<Gamma> \<turnstile> p \<leftrightarrow> q : T \<Longrightarrow> \<Gamma> \<turnstile> p is q : T"
   657 proof (nominal_induct T arbitrary: \<Gamma> s t p q rule: ty.induct)
   657 proof (nominal_induct T arbitrary: \<Gamma> s t p q rule: ty.strong_induct)
   658   case (Arrow T\<^isub>1 T\<^isub>2)
   658   case (Arrow T\<^isub>1 T\<^isub>2)
   659   { 
   659   { 
   660     case (1 \<Gamma> s t)
   660     case (1 \<Gamma> s t)
   661     have ih1:"\<And>\<Gamma> s t. \<lbrakk>\<Gamma> \<turnstile> s is t : T\<^isub>2; valid \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T\<^isub>2" by fact
   661     have ih1:"\<And>\<Gamma> s t. \<lbrakk>\<Gamma> \<turnstile> s is t : T\<^isub>2; valid \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T\<^isub>2" by fact
   662     have ih2:"\<And>\<Gamma> s t. \<Gamma> \<turnstile> s \<leftrightarrow> t : T\<^isub>1 \<Longrightarrow> \<Gamma> \<turnstile> s is t : T\<^isub>1" by fact
   662     have ih2:"\<And>\<Gamma> s t. \<Gamma> \<turnstile> s \<leftrightarrow> t : T\<^isub>1 \<Longrightarrow> \<Gamma> \<turnstile> s is t : T\<^isub>1" by fact
   702 
   702 
   703 lemma logical_symmetry:
   703 lemma logical_symmetry:
   704   assumes a: "\<Gamma> \<turnstile> s is t : T"
   704   assumes a: "\<Gamma> \<turnstile> s is t : T"
   705   shows "\<Gamma> \<turnstile> t is s : T"
   705   shows "\<Gamma> \<turnstile> t is s : T"
   706 using a 
   706 using a 
   707 by (nominal_induct arbitrary: \<Gamma> s t rule: ty.induct) 
   707 by (nominal_induct arbitrary: \<Gamma> s t rule: ty.strong_induct) 
   708    (auto simp add: algorithmic_symmetry)
   708    (auto simp add: algorithmic_symmetry)
   709 
   709 
   710 lemma logical_transitivity:
   710 lemma logical_transitivity:
   711   assumes "\<Gamma> \<turnstile> s is t : T" "\<Gamma> \<turnstile> t is u : T" 
   711   assumes "\<Gamma> \<turnstile> s is t : T" "\<Gamma> \<turnstile> t is u : T" 
   712   shows "\<Gamma> \<turnstile> s is u : T"
   712   shows "\<Gamma> \<turnstile> s is u : T"
   713 using assms
   713 using assms
   714 proof (nominal_induct arbitrary: \<Gamma> s t u  rule:ty.induct)
   714 proof (nominal_induct arbitrary: \<Gamma> s t u  rule:ty.strong_induct)
   715   case TBase
   715   case TBase
   716   then show "\<Gamma> \<turnstile> s is u : TBase" by (auto elim:  algorithmic_transitivity)
   716   then show "\<Gamma> \<turnstile> s is u : TBase" by (auto elim:  algorithmic_transitivity)
   717 next 
   717 next 
   718   case (Arrow T\<^isub>1 T\<^isub>2 \<Gamma> s t u)
   718   case (Arrow T\<^isub>1 T\<^isub>2 \<Gamma> s t u)
   719   have h1:"\<Gamma> \<turnstile> s is t : T\<^isub>1 \<rightarrow> T\<^isub>2" by fact
   719   have h1:"\<Gamma> \<turnstile> s is t : T\<^isub>1 \<rightarrow> T\<^isub>2" by fact
   736   assumes a: "\<Gamma> \<turnstile> s is t : T" 
   736   assumes a: "\<Gamma> \<turnstile> s is t : T" 
   737   and     b: "s' \<leadsto> s" 
   737   and     b: "s' \<leadsto> s" 
   738   and     c: "t' \<leadsto> t"
   738   and     c: "t' \<leadsto> t"
   739   shows "\<Gamma> \<turnstile> s' is t' : T"
   739   shows "\<Gamma> \<turnstile> s' is t' : T"
   740 using a b c algorithmic_weak_head_closure 
   740 using a b c algorithmic_weak_head_closure 
   741 by (nominal_induct arbitrary: \<Gamma> s t s' t' rule: ty.induct) 
   741 by (nominal_induct arbitrary: \<Gamma> s t s' t' rule: ty.strong_induct) 
   742    (auto, blast)
   742    (auto, blast)
   743 
   743 
   744 lemma logical_weak_head_closure':
   744 lemma logical_weak_head_closure':
   745   assumes "\<Gamma> \<turnstile> s is t : T" and "s' \<leadsto> s" 
   745   assumes "\<Gamma> \<turnstile> s is t : T" and "s' \<leadsto> s" 
   746   shows "\<Gamma> \<turnstile> s' is t : T"
   746   shows "\<Gamma> \<turnstile> s' is t : T"
   747 using assms
   747 using assms
   748 proof (nominal_induct arbitrary: \<Gamma> s t s' rule: ty.induct)
   748 proof (nominal_induct arbitrary: \<Gamma> s t s' rule: ty.strong_induct)
   749   case (TBase  \<Gamma> s t s')
   749   case (TBase  \<Gamma> s t s')
   750   then show ?case by force
   750   then show ?case by force
   751 next
   751 next
   752   case (TUnit \<Gamma> s t s')
   752   case (TUnit \<Gamma> s t s')
   753   then show ?case by auto
   753   then show ?case by auto