src/HOL/Nominal/Examples/SOS.thy
changeset 80146 cf11a7f0a5f0
parent 66453 cc19f7ca2ed6
child 80914 d97fdabd9e2b
equal deleted inserted replaced
80143:378593bf5109 80146:cf11a7f0a5f0
    65   psubst :: "(name\<times>trm) list \<Rightarrow> trm \<Rightarrow> trm"  ("_<_>" [95,95] 105)
    65   psubst :: "(name\<times>trm) list \<Rightarrow> trm \<Rightarrow> trm"  ("_<_>" [95,95] 105)
    66 where
    66 where
    67   "\<theta><(Var x)> = (lookup \<theta> x)"
    67   "\<theta><(Var x)> = (lookup \<theta> x)"
    68 | "\<theta><(App e\<^sub>1 e\<^sub>2)> = App (\<theta><e\<^sub>1>) (\<theta><e\<^sub>2>)"
    68 | "\<theta><(App e\<^sub>1 e\<^sub>2)> = App (\<theta><e\<^sub>1>) (\<theta><e\<^sub>2>)"
    69 | "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)"
    69 | "x\<sharp>\<theta> \<Longrightarrow> \<theta><(Lam [x].e)> = Lam [x].(\<theta><e>)"
    70 apply(finite_guess)+
    70   by (finite_guess | simp add: abs_fresh | fresh_guess)+
    71 apply(rule TrueI)+
       
    72 apply(simp add: abs_fresh)+
       
    73 apply(fresh_guess)+
       
    74 done
       
    75 
    71 
    76 lemma psubst_eqvt[eqvt]:
    72 lemma psubst_eqvt[eqvt]:
    77   fixes pi::"name prm" 
    73   fixes pi::"name prm" 
    78   and   t::"trm"
    74   and   t::"trm"
    79   shows "pi\<bullet>(\<theta><t>) = (pi\<bullet>\<theta>)<(pi\<bullet>t)>"
    75   shows "pi\<bullet>(\<theta><t>) = (pi\<bullet>\<theta>)<(pi\<bullet>t)>"
   355 | "V (T\<^sub>1 \<rightarrow> T\<^sub>2) = {Lam [x].e | x e. \<forall> v \<in> (V T\<^sub>1). \<exists> v'. e[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2}"
   351 | "V (T\<^sub>1 \<rightarrow> T\<^sub>2) = {Lam [x].e | x e. \<forall> v \<in> (V T\<^sub>1). \<exists> v'. e[x::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2}"
   356   by (rule TrueI)+ 
   352   by (rule TrueI)+ 
   357 
   353 
   358 lemma V_eqvt:
   354 lemma V_eqvt:
   359   fixes pi::"name prm"
   355   fixes pi::"name prm"
   360   assumes a: "x\<in>V T"
   356   assumes "x \<in> V T"
   361   shows "(pi\<bullet>x)\<in>V T"
   357   shows "(pi\<bullet>x) \<in> V T"
   362 using a
   358 using assms
   363 apply(nominal_induct T arbitrary: pi x rule: ty.strong_induct)
   359 proof (nominal_induct T arbitrary: pi x rule: ty.strong_induct)
   364 apply(auto simp add: trm.inject)
   360   case (TVar nat)
   365 apply(simp add: eqvts)
   361   then show ?case
   366 apply(rule_tac x="pi\<bullet>xa" in exI)
   362     by (simp add: val.eqvt)
   367 apply(rule_tac x="pi\<bullet>e" in exI)
   363 next
   368 apply(simp)
   364   case (Arrow T\<^sub>1 T\<^sub>2 pi x)
   369 apply(auto)
   365   obtain a e where ae: "x = Lam [a]. e" "\<forall>v\<in>V T\<^sub>1. \<exists>v'. e[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   370 apply(drule_tac x="(rev pi)\<bullet>v" in bspec)
   366     using Arrow.prems by auto
   371 apply(force)
   367   have "\<exists>v'. (pi \<bullet> e)[(pi \<bullet> a)::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" if v: "v \<in> V T\<^sub>1" for v
   372 apply(auto)
   368   proof -
   373 apply(rule_tac x="pi\<bullet>v'" in exI)
   369     have "rev pi \<bullet> v \<in> V T\<^sub>1"
   374 apply(auto)
   370       by (simp add: Arrow.hyps(1) v)
   375 apply(drule_tac pi="pi" in big.eqvt)
   371     then obtain v' where "e[a::=(rev pi \<bullet> v)] \<Down> v'" "v' \<in> V T\<^sub>2"
   376 apply(perm_simp add: eqvts)
   372       using ae(2) by blast
   377 done
   373     then have "(pi \<bullet> e)[(pi \<bullet> a)::=v] \<Down> pi \<bullet> v'"
       
   374       by (metis (no_types, lifting) big.eqvt cons_eqvt nil_eqvt perm_pi_simp(1) perm_prod.simps psubst_eqvt)
       
   375     then show ?thesis
       
   376       using Arrow.hyps \<open>v' \<in> V T\<^sub>2\<close> by blast
       
   377   qed
       
   378   with ae show ?case by force
       
   379 qed
   378 
   380 
   379 lemma V_arrow_elim_weak:
   381 lemma V_arrow_elim_weak:
   380   assumes h:"u \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)"
   382   assumes h:"u \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)"
   381   obtains a t where "u = Lam [a].t" and "\<forall> v \<in> (V T\<^sub>1). \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   383   obtains a t where "u = Lam [a].t" and "\<forall> v \<in> (V T\<^sub>1). \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   382 using h by (auto)
   384 using h by (auto)
   383 
   385 
   384 lemma V_arrow_elim_strong:
   386 lemma V_arrow_elim_strong:
   385   fixes c::"'a::fs_name"
   387   fixes c::"'a::fs_name"
   386   assumes h: "u \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)"
   388   assumes h: "u \<in> V (T\<^sub>1 \<rightarrow> T\<^sub>2)"
   387   obtains a t where "a\<sharp>c" "u = Lam [a].t" "\<forall>v \<in> (V T\<^sub>1). \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   389   obtains a t where "a\<sharp>c" "u = Lam [a].t" "\<forall>v \<in> (V T\<^sub>1). \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   388 using h
   390 proof -
   389 apply -
   391   obtain a t where "u = Lam [a].t" 
   390 apply(erule V_arrow_elim_weak)
   392     and at: "\<And>v. v \<in> (V T\<^sub>1) \<Longrightarrow> \<exists> v'. t[a::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   391 apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(a,t,c)") (*A*)
   393     using V_arrow_elim_weak [OF assms] by metis
   392 apply(erule exE)
   394   obtain a'::name where a': "a'\<sharp>(a,t,c)"
   393 apply(drule_tac x="a'" in meta_spec)
   395     by (meson exists_fresh fs_name_class.axioms)
   394 apply(drule_tac x="[(a,a')]\<bullet>t" in meta_spec)
   396   then have "u = Lam [a'].([(a, a')] \<bullet> t)"
   395 apply(drule meta_mp)
   397     unfolding \<open>u = Lam [a].t\<close>
   396 apply(simp)
   398     by (smt (verit) alpha fresh_atm fresh_prod perm_swap trm.inject(2))
   397 apply(drule meta_mp)
   399   moreover
   398 apply(simp add: trm.inject alpha fresh_left fresh_prod calc_atm fresh_atm)
   400   have "\<exists> v'. ([(a, a')] \<bullet> t)[a'::=v] \<Down> v' \<and> v' \<in> V T\<^sub>2" if "v \<in> (V T\<^sub>1)" for v
   399 apply(perm_simp)
   401   proof -
   400 apply(force)
   402     obtain v' where v': "t[a::=([(a, a')] \<bullet> v)] \<Down> v' \<and> v' \<in> V T\<^sub>2"
   401 apply(drule meta_mp)
   403       using V_eqvt \<open>v \<in> V T\<^sub>1\<close> at by blast
   402 apply(rule ballI)
   404     then have "([(a, a')] \<bullet> t[a::=([(a, a')] \<bullet> v)]) \<Down> [(a, a')] \<bullet> v'"
   403 apply(drule_tac x="[(a,a')]\<bullet>v" in bspec)
   405       by (simp add: big.eqvt)
   404 apply(simp add: V_eqvt)
   406     then show ?thesis
   405 apply(auto)
   407       by (smt (verit) V_eqvt cons_eqvt nil_eqvt perm_prod.simps perm_swap(1) psubst_eqvt swap_simps(1) v')
   406 apply(rule_tac x="[(a,a')]\<bullet>v'" in exI)
   408   qed
   407 apply(auto)
   409   ultimately show thesis
   408 apply(drule_tac pi="[(a,a')]" in big.eqvt)
   410     by (metis fresh_prod that a')
   409 apply(perm_simp add: eqvts calc_atm)
   411 qed
   410 apply(simp add: V_eqvt)
       
   411 (*A*)
       
   412 apply(rule exists_fresh')
       
   413 apply(simp add: fin_supp)
       
   414 done
       
   415 
   412 
   416 lemma Vs_are_values:
   413 lemma Vs_are_values:
   417   assumes a: "e \<in> V T"
   414   assumes a: "e \<in> V T"
   418   shows "val e"
   415   shows "val e"
   419 using a by (nominal_induct T arbitrary: e rule: ty.strong_induct) (auto)
   416 using a by (nominal_induct T arbitrary: e rule: ty.strong_induct) (auto)