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) |