src/HOL/Nominal/Examples/Lam_substs.thy
author urbanc
Tue, 29 Nov 2005 19:26:38 +0100
changeset 18284 cd217d16c90d
parent 18269 3f36e2165e51
child 18298 f7899cb24c79
permissions -rw-r--r--
changed the order of the induction variable and the context in lam_induct (test to see whether it simplifies the code for nominal_induct).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
     1
(* $Id$ *)
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
     2
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
     3
theory lam_substs
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
     4
imports "../nominal" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
     5
begin
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
     6
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
     7
text {* Contains all the reasoning infrastructure for the
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
     8
        lambda-calculus that the nominal datatype package
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
     9
        does not yet provide. *}
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    10
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    11
atom_decl name 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    12
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    13
nominal_datatype lam = Var "name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    14
                     | App "lam" "lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    15
                     | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    16
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    17
section {* Strong induction principles for lam *}
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    18
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    19
lemma lam_induct_aux:
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    20
  fixes P :: "'a \<Rightarrow> lam \<Rightarrow> bool"
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    21
  and   f :: "'a \<Rightarrow> 'a"
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    22
  assumes fs: "\<And>x. finite ((supp (f x))::name set)"
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    23
      and h1: "\<And>x a. P x (Var  a)"  
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    24
      and h2: "\<And>x t1 t2. (\<And>z. P z t1) \<Longrightarrow> (\<And>z. P z t2) \<Longrightarrow> P x (App t1 t2)" 
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    25
      and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<And>z. P z t) \<Longrightarrow> P x (Lam [a].t)"
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    26
  shows "\<And>(pi::name prm) x. P x (pi\<bullet>t)"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    27
proof (induct rule: lam.induct_weak)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    28
  case (Lam a t)
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    29
  have ih: "\<And>(pi::name prm) x. P x (pi\<bullet>t)" by fact
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    30
  show "\<And>(pi::name prm) x. P x (pi\<bullet>(Lam [a].t))"
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    31
  proof (simp add: abs_perm)
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    32
    fix x::"'a" and pi::"name prm"
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    33
    have "\<exists>c::name. c\<sharp>(f x,pi\<bullet>a,pi\<bullet>t)"
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    34
      by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 fs)
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    35
    then obtain c::"name" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    36
      where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>(f x)" and f3: "c\<sharp>(pi\<bullet>t)" 
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    37
      by (force simp add: fresh_prod fresh_atm)
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    38
    have "Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) = Lam [(pi\<bullet>a)].(pi\<bullet>t)" using f1 f3
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    39
      by (simp add: lam.inject alpha)
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    40
    moreover
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    41
    from ih have "\<And>x. P x (([(c,pi\<bullet>a)]@pi)\<bullet>t)" by force
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    42
    hence "\<And>x. P x ([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t))" by (simp add: pt_name2[symmetric])
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    43
    hence "P x (Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)))" using h3 f2
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    44
      by (auto simp add: fresh_def at_fin_set_supp[OF at_name_inst, OF fs])
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    45
    ultimately show "P x (Lam [(pi\<bullet>a)].(pi\<bullet>t))" by simp
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    46
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    47
qed (auto intro: h1 h2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    48
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    49
lemma lam_induct'[case_names Fin Var App Lam]: 
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    50
  fixes P :: "'a \<Rightarrow> lam \<Rightarrow> bool"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    51
  and   x :: "'a"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    52
  and   t :: "lam"
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    53
  and   f :: "'a \<Rightarrow> 'a"
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
    54
  assumes fs: "\<And>x. finite ((supp (f x))::name set)"
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    55
  and     h1: "\<And>x a. P x (Var  a)" 
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    56
  and     h2: "\<And>x t1 t2. (\<And>z. P z t1)\<Longrightarrow>(\<And>z. P z t2)\<Longrightarrow>P x (App t1 t2)" 
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    57
  and     h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<And>z. P z t)\<Longrightarrow> P x (Lam [a].t)"
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    58
  shows  "P x t"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    59
proof - 
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    60
  from fs h1 h2 h3 have "\<And>(pi::name prm) x. P x (pi\<bullet>t)" by (rule lam_induct_aux, auto)
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    61
  hence "P x (([]::name prm)\<bullet>t)" by blast
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    62
  thus "P x t" by simp
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    63
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    64
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    65
lemma lam_induct[case_names Var App Lam]: 
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    66
  fixes P :: "('a::fs_name) \<Rightarrow> lam \<Rightarrow> bool"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    67
  and   x :: "'a::fs_name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    68
  and   t :: "lam"
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    69
  assumes h1: "\<And>x a. P x (Var  a)" 
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    70
  and     h2: "\<And>x t1 t2. (\<And>z. P z t1)\<Longrightarrow>(\<And>z. P z t2)\<Longrightarrow>P x (App t1 t2)" 
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    71
  and     h3: "\<And>x a t. a\<sharp>x \<Longrightarrow> (\<And>z. P z t)\<Longrightarrow> P x (Lam [a].t)"
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    72
  shows  "P x t"
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    73
apply(rule lam_induct'[of "\<lambda>x. x" "P"])
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    74
apply(simp add: fs_name1)
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    75
apply(auto intro: h1 h2 h3)
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
    76
done
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    77
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    78
types 'a f1_ty  = "name\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    79
      'a f2_ty  = "'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    80
      'a f3_ty  = "name\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    81
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    82
lemma f3_freshness_conditions:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    83
  fixes f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    84
  and   y ::"name prm \<Rightarrow> 'a::pt_name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    85
  and   a ::"name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    86
  and   pi1::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    87
  and   pi2::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    88
  assumes a: "finite ((supp f3)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    89
  and     b: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    90
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    91
  shows "\<exists>(a''::name). a''\<sharp>(\<lambda>a'. f3 a' (y (pi1@[(a,pi2\<bullet>a')]))) \<and> 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    92
                       a''\<sharp>(\<lambda>a'. f3 a' (y (pi1@[(a,pi2\<bullet>a')]))) a''" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    93
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    94
  from c obtain a' where d0: "a'\<sharp>f3" and d1: "\<forall>(y::'a::pt_name). a'\<sharp>f3 a' y" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    95
  have "\<exists>(a''::name). a''\<sharp>(f3,a,a',pi1,pi2,y)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    96
    by (rule at_exists_fresh[OF at_name_inst],  simp add: supp_prod fs_name1 a b)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    97
  then obtain a'' where d2: "a''\<sharp>f3" and d3: "a''\<noteq>a'" and d3b: "a''\<sharp>(f3,a,pi1,pi2,y)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    98
    by (auto simp add: fresh_prod at_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
    99
  have d3c: "a''\<notin>((supp (f3,a,pi1,pi2,y))::name set)" using d3b by (simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   100
  have d4: "a''\<sharp>f3 a'' (y (pi1@[(a,pi2\<bullet>a'')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   101
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   102
    have d5: "[(a'',a')]\<bullet>f3 = f3" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   103
      by (rule pt_fresh_fresh[OF pt_name_inst, OF at_name_inst, OF d2, OF d0]) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   104
    from d1 have "\<forall>(y::'a::pt_name). ([(a'',a')]\<bullet>a')\<sharp>([(a'',a')]\<bullet>(f3 a' y))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   105
      by (simp add: pt_fresh_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   106
    hence "\<forall>(y::'a::pt_name). a''\<sharp>(f3 a'' ([(a'',a')]\<bullet>y))" using d3 d5 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   107
      by (simp add: at_calc[OF at_name_inst] pt_fun_app_eq[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   108
    hence "a''\<sharp>(f3 a'' ([(a'',a')]\<bullet>((rev [(a'',a')])\<bullet>(y (pi1@[(a,pi2\<bullet>a'')])))))" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   109
    thus ?thesis by (simp only: pt_pi_rev[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   110
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   111
  have d6: "a''\<sharp>(\<lambda>a'. f3 a' (y (pi1@[(a,pi2\<bullet>a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   112
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   113
    from a b have d7: "finite ((supp (f3,a,pi1,pi2,y))::name set)" by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   114
    have e: "((supp (f3,a,pi1,pi2,y))::name set) supports (\<lambda>a'. f3 a' (y (pi1@[(a,pi2\<bullet>a')])))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   115
      by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   116
    from e d7 d3c show ?thesis by (rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   117
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   118
  from d6 d4 show ?thesis by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   119
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   120
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   121
lemma f3_freshness_conditions_simple:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   122
  fixes f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   123
  and   y ::"name prm \<Rightarrow> 'a::pt_name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   124
  and   a ::"name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   125
  and   pi::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   126
  assumes a: "finite ((supp f3)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   127
  and     b: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   128
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   129
  shows "\<exists>(a''::name). a''\<sharp>(\<lambda>a'. f3 a' (y (pi@[(a,a')]))) \<and> a''\<sharp>(\<lambda>a'. f3 a' (y (pi@[(a,a')]))) a''" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   130
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   131
  from c obtain a' where d0: "a'\<sharp>f3" and d1: "\<forall>(y::'a::pt_name). a'\<sharp>f3 a' y" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   132
  have "\<exists>(a''::name). a''\<sharp>(f3,a,a',pi,y)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   133
    by (rule at_exists_fresh[OF at_name_inst],  simp add: supp_prod fs_name1 a b)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   134
  then obtain a'' where d2: "a''\<sharp>f3" and d3: "a''\<noteq>a'" and d3b: "a''\<sharp>(f3,a,pi,y)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   135
    by (auto simp add: fresh_prod at_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   136
  have d3c: "a''\<notin>((supp (f3,a,pi,y))::name set)" using d3b by (simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   137
  have d4: "a''\<sharp>f3 a'' (y (pi@[(a,a'')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   138
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   139
    have d5: "[(a'',a')]\<bullet>f3 = f3" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   140
      by (rule pt_fresh_fresh[OF pt_name_inst, OF at_name_inst, OF d2, OF d0]) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   141
    from d1 have "\<forall>(y::'a::pt_name). ([(a'',a')]\<bullet>a')\<sharp>([(a'',a')]\<bullet>(f3 a' y))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   142
      by (simp add: pt_fresh_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   143
    hence "\<forall>(y::'a::pt_name). a''\<sharp>(f3 a'' ([(a'',a')]\<bullet>y))" using d3 d5 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   144
      by (simp add: at_calc[OF at_name_inst] pt_fun_app_eq[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   145
    hence "a''\<sharp>(f3 a'' ([(a'',a')]\<bullet>((rev [(a'',a')])\<bullet>(y (pi@[(a,a'')])))))" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   146
    thus ?thesis by (simp only: pt_pi_rev[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   147
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   148
  have d6: "a''\<sharp>(\<lambda>a'. f3 a' (y (pi@[(a,a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   149
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   150
    from a b have d7: "finite ((supp (f3,a,pi,y))::name set)" by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   151
    have "((supp (f3,a,pi,y))::name set) supports (\<lambda>a'. f3 a' (y (pi@[(a,a')])))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   152
      by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   153
    with d7 d3c show ?thesis by (simp add: supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   154
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   155
  from d6 d4 show ?thesis by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   156
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   157
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   158
lemma f3_fresh_fun_supports:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   159
  fixes f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   160
  and   a ::"name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   161
  and   pi1::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   162
  and   y ::"name prm \<Rightarrow> 'a::pt_name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   163
  assumes a: "finite ((supp f3)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   164
  and     b: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   165
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   166
  shows "((supp (f3,a,y))::name set) supports (\<lambda>pi. fresh_fun (\<lambda>a'. f3 a' (y (pi@[(a,a')]))))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   167
proof (auto simp add: "op supports_def" perm_fun_def expand_fun_eq fresh_def[symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   168
  fix b::"name" and c::"name" and pi::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   169
  assume b1: "b\<sharp>(f3,a,y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   170
  and    b2: "c\<sharp>(f3,a,y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   171
  from b1 b2 have b3: "[(b,c)]\<bullet>f3=f3" and t4: "[(b,c)]\<bullet>a=a" and t5: "[(b,c)]\<bullet>y=y"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   172
    by (simp_all add: pt_fresh_fresh[OF pt_name_inst, OF at_name_inst] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   173
  let ?g = "\<lambda>a'. f3 a' (y (([(b,c)]\<bullet>pi)@[(a,a')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   174
  and ?h = "\<lambda>a'. f3 a' (y (pi@[(a,a')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   175
  have a0: "finite ((supp (f3,a,[(b,c)]\<bullet>pi,y))::name set)" using a b 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   176
    by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   177
  have a1: "((supp (f3,a,[(b,c)]\<bullet>pi,y))::name set) supports ?g" by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   178
  hence a2: "finite ((supp ?g)::name set)" using a0 by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   179
  have a3: "\<exists>(a''::name). a''\<sharp>?g \<and> a''\<sharp>(?g a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   180
    by (rule f3_freshness_conditions_simple[OF a, OF b, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   181
  have "((supp (f3,a,y))::name set) \<subseteq> (supp (f3,a,[(b,c)]\<bullet>pi,y))" by (force simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   182
  have a4: "[(b,c)]\<bullet>?g = ?h" using b1 b2
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   183
    by (simp add: fresh_prod, perm_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   184
  have "[(b,c)]\<bullet>(fresh_fun ?g) = fresh_fun ([(b,c)]\<bullet>?g)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   185
    by (simp add: fresh_fun_equiv[OF pt_name_inst, OF at_name_inst, OF a2, OF a3])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   186
  also have "\<dots> = fresh_fun ?h" using a4 by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   187
  finally show "[(b,c)]\<bullet>(fresh_fun ?g) = fresh_fun ?h" .
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   188
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   189
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   190
lemma f3_fresh_fun_supp_finite:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   191
  fixes f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   192
  and   a ::"name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   193
  and   pi1::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   194
  and   y ::"name prm \<Rightarrow> 'a::pt_name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   195
  assumes a: "finite ((supp f3)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   196
  and     b: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   197
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   198
  shows "finite ((supp (\<lambda>pi. fresh_fun (\<lambda>a'. f3 a' (y (pi@[(a,a')])))))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   199
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   200
  have "((supp (f3,a,y))::name set) supports (\<lambda>pi. fresh_fun (\<lambda>a'. f3 a' (y (pi@[(a,a')]))))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   201
    using a b c by (rule f3_fresh_fun_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   202
  moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   203
  have "finite ((supp (f3,a,y))::name set)" using a b by (simp add: supp_prod fs_name1) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   204
  ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   205
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   206
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   207
types 'a recT  = "'a f1_ty \<Rightarrow> 'a f2_ty \<Rightarrow> 'a f3_ty \<Rightarrow> (lam\<times>(name prm \<Rightarrow> ('a::pt_name))) set"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   208
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   209
consts
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   210
  rec :: "('a::pt_name) recT"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   211
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   212
inductive "rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   213
intros
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   214
r1: "(Var a,\<lambda>pi. f1 (pi\<bullet>a))\<in>rec f1 f2 f3" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   215
r2: "\<lbrakk>finite ((supp y1)::name set);(t1,y1)\<in>rec f1 f2 f3; 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   216
      finite ((supp y2)::name set);(t2,y2)\<in>rec f1 f2 f3\<rbrakk> 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   217
      \<Longrightarrow> (App t1 t2,\<lambda>pi. f2 (y1 pi) (y2 pi))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   218
r3: "\<lbrakk>finite ((supp y)::name set);(t,y)\<in>rec f1 f2 f3\<rbrakk> 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   219
      \<Longrightarrow> (Lam [a].t,\<lambda>pi. fresh_fun (\<lambda>a'. f3 a' (y (pi@[(a,a')]))))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   220
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   221
constdefs
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   222
  rfun' :: "'a f1_ty \<Rightarrow> 'a f2_ty \<Rightarrow> 'a f3_ty \<Rightarrow> lam \<Rightarrow> name prm \<Rightarrow> ('a::pt_name)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   223
  "rfun' f1 f2 f3 t \<equiv> (THE y. (t,y)\<in>rec f1 f2 f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   224
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   225
  rfun :: "'a f1_ty \<Rightarrow> 'a f2_ty \<Rightarrow> 'a f3_ty \<Rightarrow> lam \<Rightarrow> ('a::pt_name)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   226
  "rfun f1 f2 f3 t \<equiv> rfun' f1 f2 f3 t ([]::name prm)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   227
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   228
lemma rec_prm_eq[rule_format]:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   229
  fixes f1 ::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   230
  and   f2 ::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   231
  and   f3 ::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   232
  and   t  ::"lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   233
  and   y  ::"name prm \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   234
  shows "(t,y)\<in>rec f1 f2 f3 \<Longrightarrow> (\<forall>(pi1::name prm) (pi2::name prm). pi1 \<sim> pi2 \<longrightarrow> (y pi1 = y pi2))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   235
apply(erule rec.induct)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   236
apply(auto simp add: pt3[OF pt_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   237
apply(rule_tac f="fresh_fun" in arg_cong)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   238
apply(auto simp add: expand_fun_eq)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   239
apply(drule_tac x="pi1@[(a,x)]" in spec)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   240
apply(drule_tac x="pi2@[(a,x)]" in spec)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   241
apply(force simp add: prm_eq_def pt2[OF pt_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   242
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   243
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   244
(* silly helper lemma *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   245
lemma rec_trans: 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   246
  fixes f1 ::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   247
  and   f2 ::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   248
  and   f3 ::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   249
  and   t  ::"lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   250
  and   y  ::"name prm \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   251
  assumes a: "(t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   252
  and     b: "y=y'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   253
  shows   "(t,y')\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   254
using a b by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   255
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   256
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   257
lemma rec_prm_equiv:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   258
  fixes f1 ::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   259
  and   f2 ::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   260
  and   f3 ::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   261
  and   t  ::"lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   262
  and   y  ::"name prm \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   263
  and   pi ::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   264
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   265
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   266
  and     a: "(t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   267
  shows "(pi\<bullet>t,pi\<bullet>y)\<in>rec (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   268
using a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   269
proof (induct)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   270
  case (r1 c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   271
  let ?g ="pi\<bullet>(\<lambda>(pi'::name prm). f1 (pi'\<bullet>c))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   272
  and ?g'="\<lambda>(pi'::name prm). (pi\<bullet>f1) (pi'\<bullet>(pi\<bullet>c))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   273
  have "?g'=?g" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   274
  proof (auto simp only: expand_fun_eq perm_fun_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   275
    fix pi'::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   276
    let ?h = "((rev pi)\<bullet>(pi'\<bullet>(pi\<bullet>c)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   277
    and ?h'= "(((rev pi)\<bullet>pi')\<bullet>c)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   278
    have "?h' = ((rev pi)\<bullet>pi')\<bullet>((rev pi)\<bullet>(pi\<bullet>c))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   279
      by (simp add: pt_rev_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   280
    also have "\<dots> = ?h"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   281
      by (simp add: pt_perm_compose[OF pt_name_inst, OF at_name_inst,symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   282
    finally show "pi\<bullet>(f1 ?h) = pi\<bullet>(f1 ?h')" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   283
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   284
  thus ?case by (force intro: rec_trans rec.r1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   285
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   286
  case (r2 t1 t2 y1 y2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   287
  assume a1: "finite ((supp y1)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   288
  and    a2: "finite ((supp y2)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   289
  and    a3: "(pi\<bullet>t1,pi\<bullet>y1) \<in> rec (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   290
  and    a4: "(pi\<bullet>t2,pi\<bullet>y2) \<in> rec (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   291
  from a1 a2 have a1': "finite ((supp (pi\<bullet>y1))::name set)" and a2': "finite ((supp (pi\<bullet>y2))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   292
    by (simp_all add: pt_supp_finite_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   293
  let ?g ="pi\<bullet>(\<lambda>(pi'::name prm). f2 (y1 pi') (y2 pi'))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   294
  and ?g'="\<lambda>(pi'::name prm). (pi\<bullet>f2) ((pi\<bullet>y1) pi') ((pi\<bullet>y2) pi')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   295
  have "?g'=?g" by  (simp add: expand_fun_eq perm_fun_def pt_rev_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   296
  thus ?case using a1' a2' a3 a4 by (force intro: rec.r2 rec_trans)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   297
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   298
  case (r3 a t y)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   299
  assume a1: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   300
  and    a2: "(pi\<bullet>t,pi\<bullet>y) \<in> rec (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   301
  from a1 have a1': "finite ((supp (pi\<bullet>y))::name set)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   302
    by (simp add: pt_supp_finite_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   303
  let ?g ="pi\<bullet>(\<lambda>(pi'::name prm). fresh_fun (\<lambda>a'. f3 a' (y (pi'@[(a,a')]))))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   304
  and ?g'="(\<lambda>(pi'::name prm). fresh_fun (\<lambda>a'. (pi\<bullet>f3) a' ((pi\<bullet>y) (pi'@[((pi\<bullet>a),a')]))))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   305
  have "?g'=?g" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   306
  proof (auto simp add: expand_fun_eq perm_fun_def pt_rev_pi[OF pt_name_inst, OF at_name_inst] 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   307
                        perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   308
    fix pi'::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   309
    let ?h  = "\<lambda>a'. pi\<bullet>(f3 ((rev pi)\<bullet>a') (y (((rev pi)\<bullet>pi')@[(a,(rev pi)\<bullet>a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   310
    and ?h' = "\<lambda>a'. f3 a' (y (((rev pi)\<bullet>pi')@[(a,a')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   311
    have fs_f3: "finite ((supp f3)::name set)" using f by (simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   312
    have fs_h': "finite ((supp ?h')::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   313
    proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   314
      have "((supp (f3,a,(rev pi)\<bullet>pi',y))::name set) supports ?h'" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   315
	by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   316
      moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   317
      have "finite ((supp (f3,a,(rev pi)\<bullet>pi',y))::name set)" using a1 fs_f3 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   318
	by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   319
      ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   320
    qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   321
    have fcond: "\<exists>(a''::name). a''\<sharp>?h' \<and> a''\<sharp>(?h' a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   322
      by (rule f3_freshness_conditions_simple[OF fs_f3, OF a1, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   323
    have "fresh_fun ?h = fresh_fun (pi\<bullet>?h')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   324
      by (simp add: perm_fun_def pt_rev_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   325
    also have "\<dots> = pi\<bullet>(fresh_fun ?h')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   326
      by (simp add: fresh_fun_equiv[OF pt_name_inst, OF at_name_inst, OF fs_h', OF fcond])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   327
    finally show "fresh_fun ?h = pi\<bullet>(fresh_fun ?h')" .
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   328
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   329
  thus ?case using a1' a2 by (force intro: rec.r3 rec_trans)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   330
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   331
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   332
lemma rec_perm:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   333
  fixes f1 ::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   334
  and   f2 ::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   335
  and   f3 ::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   336
  and   pi1::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   337
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   338
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   339
  and     a: "(t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   340
  shows "(pi1\<bullet>t, \<lambda>pi2. y (pi2@pi1))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   341
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   342
  have lem: "\<forall>(y::name prm\<Rightarrow>('a::pt_name))(pi::name prm). 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   343
             finite ((supp y)::name set) \<longrightarrow> finite ((supp (\<lambda>pi'. y (pi'@pi)))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   344
  proof (intro strip)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   345
    fix y::"name prm\<Rightarrow>('a::pt_name)" and pi::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   346
    assume  "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   347
    hence "finite ((supp (y,pi))::name set)" by (simp add: supp_prod fs_name1)      
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   348
    moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   349
    have  "((supp (y,pi))::name set) supports (\<lambda>pi'. y (pi'@pi))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   350
      by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   351
    ultimately show "finite ((supp (\<lambda>pi'. y (pi'@pi)))::name set)" by (simp add: supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   352
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   353
from a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   354
show ?thesis
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   355
proof (induct)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   356
  case (r1 c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   357
  show ?case
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   358
    by (auto simp add: pt2[OF pt_name_inst], rule rec.r1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   359
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   360
  case (r2 t1 t2 y1 y2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   361
  thus ?case using lem by (auto intro!: rec.r2) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   362
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   363
  case (r3 c t y)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   364
  assume a0: "(t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   365
  and    a1: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   366
  and    a2: "(pi1\<bullet>t,\<lambda>pi2. y (pi2@pi1))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   367
  from f have f': "finite ((supp f3)::name set)" by (simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   368
  show ?case
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   369
  proof(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   370
    have a3: "finite ((supp (\<lambda>pi2. y (pi2@pi1)))::name set)" using lem a1 by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   371
    let ?g' = "\<lambda>(pi::name prm). fresh_fun (\<lambda>a'. f3 a' ((\<lambda>pi2. y (pi2@pi1)) (pi@[(pi1\<bullet>c,a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   372
    and ?g  = "\<lambda>(pi::name prm). fresh_fun (\<lambda>a'. f3 a' (y (pi@[(pi1\<bullet>c,a')]@pi1)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   373
    and ?h  = "\<lambda>(pi::name prm). fresh_fun (\<lambda>a'. f3 a' (y (pi@pi1@[(c,a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   374
    have eq1: "?g = ?g'" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   375
    have eq2: "?g'= ?h" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   376
    proof (auto simp only: expand_fun_eq)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   377
      fix pi::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   378
      let ?q  = "\<lambda>a'. f3 a' (y ((pi@[(pi1\<bullet>c,a')])@pi1))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   379
      and ?q' = "\<lambda>a'. f3 a' (y (((pi@pi1)@[(c,(rev pi1)\<bullet>a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   380
      and ?r  = "\<lambda>a'. f3 a' (y ((pi@pi1)@[(c,a')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   381
      and ?r' = "\<lambda>a'. f3 a' (y (pi@(pi1@[(c,a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   382
      have eq3a: "?r = ?r'" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   383
      have eq3: "?q = ?q'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   384
      proof (auto simp only: expand_fun_eq)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   385
	fix a'::"name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   386
	have "(y ((pi@[(pi1\<bullet>c,a')])@pi1)) =  (y (((pi@pi1)@[(c,(rev pi1)\<bullet>a')])))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   387
	  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   388
	    have "((pi@[(pi1\<bullet>c,a')])@pi1) \<sim> ((pi@pi1)@[(c,(rev pi1)\<bullet>a')])"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   389
	    by (force simp add: prm_eq_def at_append[OF at_name_inst] 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   390
                   at_calc[OF at_name_inst] at_bij[OF at_name_inst] 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   391
                   at_pi_rev[OF at_name_inst] at_rev_pi[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   392
	    with a0 show ?thesis by (rule rec_prm_eq)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   393
	  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   394
	thus "f3 a' (y ((pi@[(pi1\<bullet>c,a')])@pi1)) = f3 a' (y (((pi@pi1)@[(c,(rev pi1)\<bullet>a')])))" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   395
      qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   396
      have fs_a: "finite ((supp ?q')::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   397
      proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   398
	have "((supp (f3,c,(pi@pi1),(rev pi1),y))::name set) supports ?q'" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   399
	  by (supports_simp add: perm_append fresh_list_append fresh_list_rev)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   400
	moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   401
	have "finite ((supp (f3,c,(pi@pi1),(rev pi1),y))::name set)" using f' a1
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   402
	  by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   403
	ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   404
      qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   405
      have fs_b: "finite ((supp ?r)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   406
      proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   407
	have "((supp (f3,c,(pi@pi1),y))::name set) supports ?r" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   408
	  by (supports_simp add: perm_append fresh_list_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   409
	moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   410
	have "finite ((supp (f3,c,(pi@pi1),y))::name set)" using f' a1
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   411
	  by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   412
	ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   413
      qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   414
      have c1: "\<exists>(a''::name). a''\<sharp>?q' \<and> a''\<sharp>(?q' a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   415
	by (rule f3_freshness_conditions[OF f', OF a1, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   416
      have c2: "\<exists>(a''::name). a''\<sharp>?r \<and> a''\<sharp>(?r a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   417
	by (rule f3_freshness_conditions_simple[OF f', OF a1, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   418
      have c3: "\<exists>(d::name). d\<sharp>(?q',?r,(rev pi1))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   419
	by (rule at_exists_fresh[OF at_name_inst], 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   420
            simp only: finite_Un supp_prod fs_a fs_b fs_name1, simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   421
      then obtain d::"name" where d1: "d\<sharp>?q'" and d2: "d\<sharp>?r" and d3: "d\<sharp>(rev pi1)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   422
	by (auto simp only: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   423
      have eq4: "(rev pi1)\<bullet>d = d" using d3 by (simp add: at_prm_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   424
      have "fresh_fun ?q = fresh_fun ?q'" using eq3 by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   425
      also have "\<dots> = ?q' d" using fs_a c1 d1 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   426
	by (simp add: fresh_fun_app[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   427
      also have "\<dots> = ?r d" using fs_b c2 d2 eq4
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   428
	by (simp add: fresh_fun_app[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   429
      also have "\<dots> = fresh_fun ?r" using fs_b c2 d2 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   430
	by (simp add: fresh_fun_app[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   431
      finally show "fresh_fun ?q = fresh_fun ?r'" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   432
    qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   433
    from a3 a2 have "(Lam [(pi1\<bullet>c)].(pi1\<bullet>t), ?g')\<in>rec f1 f2 f3" by (rule rec.r3)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   434
    thus "(Lam [(pi1\<bullet>c)].(pi1\<bullet>t), ?h)\<in>rec f1 f2 f3" using eq2 by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   435
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   436
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   437
qed    
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   438
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   439
lemma rec_perm_rev:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   440
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   441
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   442
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   443
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   444
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   445
  and     a: "(pi\<bullet>t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   446
  shows "(t, \<lambda>pi2. y (pi2@(rev pi)))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   447
proof - 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   448
  from a have "((rev pi)\<bullet>(pi\<bullet>t),\<lambda>pi2. y (pi2@(rev pi)))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   449
    by (rule rec_perm[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   450
  thus ?thesis by (simp add: pt_rev_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   451
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   452
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   453
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   454
lemma rec_unique:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   455
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   456
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   457
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   458
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   459
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   460
  and     a: "(t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   461
  shows "\<forall>(y'::name prm\<Rightarrow>('a::pt_name))(pi::name prm).
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   462
         (t,y')\<in>rec f1 f2 f3 \<longrightarrow> y pi = y' pi"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   463
using a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   464
proof (induct)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   465
  case (r1 c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   466
  show ?case 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   467
   apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   468
   apply(ind_cases "(Var c, y') \<in> rec f1 f2 f3")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   469
   apply(simp_all add: lam.distinct lam.inject)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   470
   done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   471
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   472
  case (r2 t1 t2 y1 y2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   473
  thus ?case 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   474
    apply(clarify)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   475
    apply(ind_cases "(App t1 t2, y') \<in> rec f1 f2 f3") 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   476
    apply(simp_all (no_asm_use) only: lam.distinct lam.inject) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   477
    apply(clarify)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   478
    apply(drule_tac x="y1" in spec)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   479
    apply(drule_tac x="y2" in spec)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   480
    apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   481
    done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   482
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   483
  case (r3 c t y)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   484
  assume i1: "finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   485
  and    i2: "(t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   486
  and    i3: "\<forall>(y'::name prm\<Rightarrow>('a::pt_name))(pi::name prm).
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   487
              (t,y')\<in>rec f1 f2 f3 \<longrightarrow> y pi = y' pi"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   488
  from f have f': "finite ((supp f3)::name set)" by (simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   489
  show ?case 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   490
  proof (auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   491
    fix y'::"name prm\<Rightarrow>('a::pt_name)" and pi::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   492
    assume i4: "(Lam [c].t, y') \<in> rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   493
    from i4 show "fresh_fun (\<lambda>a'. f3 a' (y (pi@[(c,a')]))) = y' pi"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   494
    proof (cases, simp_all add: lam.distinct lam.inject, auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   495
      fix a::"name" and t'::"lam" and y''::"name prm\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   496
      assume i5: "[c].t = [a].t'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   497
      and    i6: "(t',y'')\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   498
      and    i6':"finite ((supp y'')::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   499
      let ?g = "\<lambda>a'. f3 a' (y  (pi@[(c,a')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   500
      and ?h = "\<lambda>a'. f3 a' (y'' (pi@[(a,a')]))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   501
      show "fresh_fun ?g = fresh_fun ?h" using i5
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   502
      proof (cases "a=c")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   503
	case True
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   504
	assume i7: "a=c"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   505
	with i5 have i8: "t=t'" by (simp add: alpha)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   506
	show "fresh_fun ?g = fresh_fun ?h" using i3 i6 i7 i8 by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   507
      next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   508
	case False
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   509
	assume i9: "a\<noteq>c"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   510
	with i5[symmetric] have i10: "t'=[(a,c)]\<bullet>t" and i11: "a\<sharp>t" by (simp_all add: alpha)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   511
	have r1: "finite ((supp ?g)::name set)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   512
	proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   513
	  have "((supp (f3,c,pi,y))::name set) supports ?g" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   514
	    by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   515
	  moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   516
	  have "finite ((supp (f3,c,pi,y))::name set)" using f' i1
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   517
	    by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   518
	  ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   519
	qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   520
	have r2: "finite ((supp ?h)::name set)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   521
	proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   522
	  have "((supp (f3,a,pi,y''))::name set) supports ?h" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   523
	    by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   524
	  moreover
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   525
	  have "finite ((supp (f3,a,pi,y''))::name set)" using f' i6'
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   526
	    by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   527
	  ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   528
	qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   529
	have c1: "\<exists>(a''::name). a''\<sharp>?g \<and> a''\<sharp>(?g a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   530
	  by (rule f3_freshness_conditions_simple[OF f', OF i1, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   531
	have c2: "\<exists>(a''::name). a''\<sharp>?h \<and> a''\<sharp>(?h a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   532
	  by (rule f3_freshness_conditions_simple[OF f', OF i6', OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   533
	have "\<exists>(d::name). d\<sharp>(?g,?h,t,a,c)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   534
	  by (rule at_exists_fresh[OF at_name_inst], 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   535
              simp only: finite_Un supp_prod r1 r2 fs_name1, simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   536
	then obtain d::"name" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   537
	  where f1: "d\<sharp>?g" and f2: "d\<sharp>?h" and f3: "d\<sharp>t" and f4: "d\<noteq>a" and f5: "d\<noteq>c" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   538
	  by (force simp add: fresh_prod at_fresh[OF at_name_inst] at_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   539
	have g1: "[(a,d)]\<bullet>t = t" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   540
	  by (rule pt_fresh_fresh[OF pt_name_inst, OF at_name_inst, OF i11, OF f3]) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   541
	from i6 have "(([(a,c)]@[(a,d)])\<bullet>t,y'')\<in>rec f1 f2 f3" using g1 i10 by (simp only: pt_name2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   542
	hence "(t, \<lambda>pi2. y'' (pi2@(rev ([(a,c)]@[(a,d)]))))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   543
	  by (simp only: rec_perm_rev[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   544
	hence g2: "(t, \<lambda>pi2. y'' (pi2@([(a,d)]@[(a,c)])))\<in>rec f1 f2 f3" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   545
	have "distinct [a,c,d]" using i9 f4 f5 by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   546
	hence g3: "(pi@[(c,d)]@[(a,d)]@[(a,c)]) \<sim> (pi@[(a,d)])"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   547
	  by (force simp add: prm_eq_def at_calc[OF at_name_inst] at_append[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   548
	have "fresh_fun ?g = ?g d" using r1 c1 f1
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   549
	  by (simp add: fresh_fun_app[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   550
	also have "\<dots> = f3 d ((\<lambda>pi2. y'' (pi2@([(a,d)]@[(a,c)]))) (pi@[(c,d)]))" using i3 g2 by simp 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   551
	also have "\<dots> = f3 d (y'' (pi@[(c,d)]@[(a,d)]@[(a,c)]))" by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   552
	also have "\<dots> = f3 d (y'' (pi@[(a,d)]))" using i6 g3 by (simp add: rec_prm_eq)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   553
	also have "\<dots> = fresh_fun ?h" using r2 c2 f2
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   554
	  by (simp add: fresh_fun_app[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   555
	finally show "fresh_fun ?g = fresh_fun ?h" .
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   556
      qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   557
    qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   558
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   559
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   560
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   561
lemma rec_total_aux:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   562
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   563
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   564
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   565
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   566
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   567
  shows "\<exists>(y::name prm\<Rightarrow>('a::pt_name)). ((t,y)\<in>rec f1 f2 f3) \<and> (finite ((supp y)::name set))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   568
proof (induct t rule: lam.induct_weak)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   569
  case (Var c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   570
  have a1: "(Var c,\<lambda>(pi::name prm). f1 (pi\<bullet>c))\<in>rec f1 f2 f3" by (rule rec.r1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   571
  have a2: "finite ((supp (\<lambda>(pi::name prm). f1 (pi\<bullet>c)))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   572
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   573
    have "((supp (f1,c))::name set) supports (\<lambda>(pi::name prm). f1 (pi\<bullet>c))" by (supports_simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   574
    moreover have "finite ((supp (f1,c))::name set)" using f by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   575
    ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   576
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   577
  from a1 a2 show ?case by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   578
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   579
  case (App t1 t2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   580
  assume "\<exists>y1. (t1,y1)\<in>rec f1 f2 f3 \<and> finite ((supp y1)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   581
  then obtain y1::"name prm \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   582
    where a11: "(t1,y1)\<in>rec f1 f2 f3" and a12: "finite ((supp y1)::name set)" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   583
  assume "\<exists>y2. (t2,y2)\<in>rec f1 f2 f3 \<and> finite ((supp y2)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   584
  then obtain y2::"name prm \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   585
    where a21: "(t2,y2)\<in>rec f1 f2 f3" and a22: "finite ((supp y2)::name set)" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   586
  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   587
  have a1: "(App t1 t2,\<lambda>(pi::name prm). f2 (y1 pi) (y2 pi))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   588
    using a12 a11 a22 a21 by (rule rec.r2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   589
  have a2: "finite ((supp (\<lambda>(pi::name prm). f2 (y1 pi) (y2 pi)))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   590
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   591
    have "((supp (f2,y1,y2))::name set) supports (\<lambda>(pi::name prm). f2 (y1 pi) (y2 pi))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   592
      by (supports_simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   593
    moreover have "finite ((supp (f2,y1,y2))::name set)" using f a21 a22 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   594
      by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   595
    ultimately show ?thesis by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   596
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   597
  from a1 a2 show ?case by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   598
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   599
  case (Lam a t)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   600
  assume "\<exists>y. (t,y)\<in>rec f1 f2 f3 \<and> finite ((supp y)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   601
  then obtain y::"name prm \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   602
    where a11: "(t,y)\<in>rec f1 f2 f3" and a12: "finite ((supp y)::name set)" by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   603
  from f have f': "finite ((supp f3)::name set)" by (simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   604
  have a1: "(Lam [a].t,\<lambda>(pi::name prm). fresh_fun (\<lambda>a'. f3 a' (y (pi@[(a,a')]))))\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   605
    using a12 a11 by (rule rec.r3)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   606
  have a2: "finite ((supp (\<lambda>pi. fresh_fun (\<lambda>a'. f3 a' (y (pi@[(a,a')])))))::name set)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   607
    using f' a12 c by (rule f3_fresh_fun_supp_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   608
  from a1 a2 show ?case by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   609
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   610
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   611
lemma rec_total:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   612
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   613
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   614
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   615
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   616
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   617
  shows "\<exists>(y::name prm\<Rightarrow>('a::pt_name)). ((t,y)\<in>rec f1 f2 f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   618
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   619
  have "\<exists>y. ((t,y)\<in>rec f1 f2 f3) \<and> (finite ((supp y)::name set))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   620
    by (rule rec_total_aux[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   621
  thus ?thesis by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   622
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   623
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   624
lemma rec_function:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   625
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   626
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   627
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   628
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   629
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   630
  shows "\<exists>!y. (t,y)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   631
proof 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   632
  case goal1
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   633
  show ?case by (rule rec_total[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   634
next
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   635
  case (goal2 y1 y2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   636
  assume a1: "(t,y1)\<in>rec f1 f2 f3" and a2: "(t,y2)\<in>rec f1 f2 f3"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   637
  hence "\<forall>pi. y1 pi = y2 pi" using rec_unique[OF f, OF c] by force
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   638
  thus ?case by (force simp add: expand_fun_eq) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   639
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   640
  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   641
lemma theI2':
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   642
  assumes a1: "P a" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   643
  and     a2: "\<exists>!x. P x" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   644
  and     a3: "P a \<Longrightarrow> Q a"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   645
  shows "Q (THE x. P x)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   646
apply(rule theI2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   647
apply(rule a1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   648
apply(subgoal_tac "\<exists>!x. P x")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   649
apply(auto intro: a1 simp add: Ex1_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   650
apply(fold Ex1_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   651
apply(rule a2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   652
apply(subgoal_tac "x=a")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   653
apply(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   654
apply(rule a3)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   655
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   656
apply(subgoal_tac "\<exists>!x. P x")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   657
apply(auto intro: a1 simp add: Ex1_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   658
apply(fold Ex1_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   659
apply(rule a2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   660
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   661
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   662
lemma rfun'_equiv:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   663
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   664
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   665
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   666
  and   pi::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   667
  and   t ::"lam"  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   668
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   669
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   670
  shows "pi\<bullet>(rfun' f1 f2 f3 t) = rfun' (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3) (pi\<bullet>t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   671
apply(auto simp add: rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   672
apply(subgoal_tac "\<exists>y. (t,y)\<in>rec f1 f2 f3 \<and> finite ((supp y)::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   673
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   674
apply(rule sym)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   675
apply(rule_tac a="y" in theI2')
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   676
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   677
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   678
apply(rule the1_equality)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   679
apply(rule rec_function)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   680
apply(subgoal_tac "finite ((supp (f1,f2,f3))::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   681
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   682
apply(simp add: pt_supp_finite_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   683
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   684
apply(subgoal_tac "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   685
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   686
apply(rule_tac x="pi\<bullet>a" in exI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   687
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   688
apply(simp add: pt_fresh_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   689
apply(drule_tac x="(rev pi)\<bullet>x" in spec)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   690
apply(subgoal_tac "(pi\<bullet>f3) (pi\<bullet>a) x  = pi\<bullet>(f3 a ((rev pi)\<bullet>x))")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   691
apply(simp add: pt_fresh_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   692
apply(subgoal_tac "pi\<bullet>(f3 a ((rev pi)\<bullet>x)) = (pi\<bullet>f3) (pi\<bullet>a) (pi\<bullet>((rev pi)\<bullet>x))")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   693
apply(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   694
apply(simp add: pt_pi_rev[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   695
apply(simp add: pt_fun_app_eq[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   696
apply(rule c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   697
apply(rule rec_prm_equiv)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   698
apply(rule f, rule c, assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   699
apply(rule rec_total_aux)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   700
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   701
apply(rule c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   702
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   703
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   704
lemma rfun'_supports:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   705
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   706
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   707
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   708
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   709
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   710
  shows "((supp (f1,f2,f3,t))::name set) supports (rfun' f1 f2 f3 t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   711
proof (auto simp add: "op supports_def" fresh_def[symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   712
  fix a::"name" and b::"name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   713
  assume a1: "a\<sharp>(f1,f2,f3,t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   714
  and    a2: "b\<sharp>(f1,f2,f3,t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   715
  from a1 a2 have "[(a,b)]\<bullet>f1=f1" and "[(a,b)]\<bullet>f2=f2" and "[(a,b)]\<bullet>f3=f3" and "[(a,b)]\<bullet>t=t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   716
    by (simp_all add: pt_fresh_fresh[OF pt_name_inst, OF at_name_inst] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   717
  thus "[(a,b)]\<bullet>(rfun' f1 f2 f3 t) = rfun' f1 f2 f3 t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   718
    by (simp add: rfun'_equiv[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   719
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   720
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   721
lemma rfun'_finite_supp:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   722
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   723
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   724
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   725
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   726
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   727
  shows "finite ((supp (rfun' f1 f2 f3 t))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   728
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   729
apply(rule rfun'_supports[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   730
apply(subgoal_tac "finite ((supp (f1,f2,f3))::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   731
apply(simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   732
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   733
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   734
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   735
lemma rfun'_prm:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   736
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   737
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   738
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   739
  and   pi1::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   740
  and   pi2::"name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   741
  and   t ::"lam"  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   742
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   743
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   744
  shows "rfun' f1 f2 f3 (pi1\<bullet>t) pi2 = rfun' f1 f2 f3 t (pi2@pi1)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   745
apply(auto simp add: rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   746
apply(subgoal_tac "\<exists>y. (t,y)\<in>rec f1 f2 f3 \<and> finite ((supp y)::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   747
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   748
apply(rule_tac a="y" in theI2')
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   749
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   750
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   751
apply(rule_tac a="\<lambda>pi2. y (pi2@pi1)" in theI2')
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   752
apply(rule rec_perm)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   753
apply(rule f, rule c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   754
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   755
apply(rule rec_function)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   756
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   757
apply(rule c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   758
apply(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   759
apply(rule rec_total_aux)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   760
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   761
apply(rule c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   762
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   763
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   764
lemma rfun_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   765
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   766
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   767
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   768
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   769
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   770
  shows "rfun f1 f2 f3 (Var c) = (f1 c)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   771
apply(auto simp add: rfun_def rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   772
apply(subgoal_tac "(THE y. (Var c, y) \<in> rec f1 f2 f3) = (\<lambda>(pi::name prm). f1 (pi\<bullet>c))")(*A*)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   773
apply(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   774
apply(rule the1_equality)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   775
apply(rule rec_function)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   776
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   777
apply(rule c)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   778
apply(rule rec.r1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   779
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   780
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   781
lemma rfun_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   782
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   783
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   784
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   785
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   786
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   787
  shows "rfun f1 f2 f3 (App t1 t2) = (f2 (rfun f1 f2 f3 t1) (rfun f1 f2 f3 t2))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   788
apply(auto simp add: rfun_def rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   789
apply(subgoal_tac "(THE y. (App t1 t2, y)\<in>rec f1 f2 f3) = 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   790
      (\<lambda>(pi::name prm). f2 ((rfun' f1 f2 f3 t1) pi) ((rfun' f1 f2 f3 t2) pi))")(*A*)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   791
apply(simp add: rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   792
apply(rule the1_equality)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   793
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   794
apply(rule rec.r2)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   795
apply(rule rfun'_finite_supp[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   796
apply(subgoal_tac "\<exists>y. (t1,y)\<in>rec f1 f2 f3")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   797
apply(erule exE, simp add: rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   798
apply(rule_tac a="y" in theI2')
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   799
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   800
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   801
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   802
apply(rule rec_total[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   803
apply(rule rfun'_finite_supp[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   804
apply(subgoal_tac "\<exists>y. (t2,y)\<in>rec f1 f2 f3")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   805
apply(auto simp add: rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   806
apply(rule_tac a="y" in theI2')
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   807
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   808
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   809
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   810
apply(rule rec_total[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   811
done 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   812
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   813
lemma rfun_Lam_aux1:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   814
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   815
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   816
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   817
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   818
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   819
  shows "rfun f1 f2 f3 (Lam [a].t) = fresh_fun (\<lambda>a'. f3 a' (rfun' f1 f2 f3 t ([]@[(a,a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   820
apply(simp add: rfun_def rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   821
apply(subgoal_tac "(THE y. (Lam [a].t, y)\<in>rec f1 f2 f3) = 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   822
        (\<lambda>(pi::name prm). fresh_fun(\<lambda>a'. f3 a' ((rfun' f1 f2 f3 t) (pi@[(a,a')]))))")(*A*)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   823
apply(simp add: rfun'_def[symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   824
apply(rule the1_equality)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   825
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   826
apply(rule rec.r3)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   827
apply(rule rfun'_finite_supp[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   828
apply(subgoal_tac "\<exists>y. (t,y)\<in>rec f1 f2 f3")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   829
apply(erule exE, simp add: rfun'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   830
apply(rule_tac a="y" in theI2')
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   831
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   832
apply(rule rec_function[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   833
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   834
apply(rule rec_total[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   835
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   836
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   837
lemma rfun_Lam_aux2:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   838
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   839
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   840
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   841
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   842
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   843
  and     a: "b\<sharp>(a,t,f1,f2,f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   844
  shows "rfun f1 f2 f3 (Lam [b].([(a,b)]\<bullet>t)) = f3 b (rfun f1 f2 f3 ([(a,b)]\<bullet>t))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   845
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   846
  from f have f': "finite ((supp f3)::name set)" by (simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   847
  have eq1: "rfun f1 f2 f3 (Lam [b].([(a,b)]\<bullet>t)) = rfun f1 f2 f3 (Lam [a].t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   848
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   849
    have "Lam [a].t = Lam [b].([(a,b)]\<bullet>t)" using a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   850
      by (force simp add: lam.inject alpha fresh_prod at_fresh[OF at_name_inst]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   851
             pt_swap_bij[OF pt_name_inst, OF at_name_inst] 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   852
             pt_fresh_left[OF pt_name_inst, OF at_name_inst] at_calc[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   853
    thus ?thesis by simp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   854
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   855
  let ?g = "(\<lambda>a'. f3 a' (rfun' f1 f2 f3 t ([]@[(a,a')])))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   856
  have a0: "((supp (f3,a,([]::name prm),rfun' f1 f2 f3 t))::name set) supports ?g"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   857
    by (supports_simp add: perm_append)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   858
  have a1: "finite ((supp (f3,a,([]::name prm),rfun' f1 f2 f3 t))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   859
    using f' by (simp add: supp_prod fs_name1 rfun'_finite_supp[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   860
  from a0 a1 have a2: "finite ((supp ?g)::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   861
    by (rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   862
  have c0: "finite ((supp (rfun' f1 f2 f3 t))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   863
    by (rule rfun'_finite_supp[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   864
  have c1: "\<exists>(a''::name). a''\<sharp>?g \<and> a''\<sharp>(?g a'')"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   865
    by (rule f3_freshness_conditions_simple[OF f', OF c0, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   866
  have c2: "b\<sharp>?g"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   867
  proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   868
    have fs_g: "finite ((supp (f1,f2,f3,t))::name set)" using f
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   869
      by (simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   870
    have "((supp (f1,f2,f3,t))::name set) supports (rfun' f1 f2 f3 t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   871
      by (simp add: rfun'_supports[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   872
    hence c3: "b\<sharp>(rfun' f1 f2 f3 t)" using fs_g 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   873
    proof(rule supports_fresh, simp add: fresh_def[symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   874
      show "b\<sharp>(f1,f2,f3,t)" using a by (simp add: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   875
    qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   876
    show ?thesis 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   877
    proof(rule supports_fresh[OF a0, OF a1], simp add: fresh_def[symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   878
      show "b\<sharp>(f3,a,([]::name prm),rfun' f1 f2 f3 t)" using a c3
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   879
	by (simp add: fresh_prod fresh_list_nil)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   880
    qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   881
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   882
  (* main proof *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   883
  have "rfun f1 f2 f3 (Lam [b].([(a,b)]\<bullet>t)) = rfun f1 f2 f3 (Lam [a].t)" by (simp add: eq1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   884
  also have "\<dots> = fresh_fun ?g" by (rule rfun_Lam_aux1[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   885
  also have "\<dots> = ?g b" using c2
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   886
    by (rule fresh_fun_app[OF pt_name_inst, OF at_name_inst, OF a2, OF c1])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   887
  also have "\<dots> = f3 b (rfun f1 f2 f3 ([(a,b)]\<bullet>t))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   888
    by (simp add: rfun_def rfun'_prm[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   889
  finally show "rfun f1 f2 f3 (Lam [b].([(a,b)]\<bullet>t)) = f3 b (rfun f1 f2 f3 ([(a,b)]\<bullet>t))" .
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   890
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   891
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   892
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   893
lemma rfun_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   894
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   895
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   896
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   897
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   898
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   899
  and     a: "b\<sharp>(f1,f2,f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   900
  shows "rfun f1 f2 f3 (Lam [b].t) = f3 b (rfun f1 f2 f3 t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   901
proof -
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   902
  have "\<exists>(a::name). a\<sharp>(b,t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   903
    by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   904
  then obtain a::"name" where a1: "a\<sharp>b" and a2: "a\<sharp>t" by (force simp add: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   905
  have "rfun f1 f2 f3 (Lam [b].t) = rfun f1 f2 f3 (Lam [b].(([(a,b)])\<bullet>([(a,b)]\<bullet>t)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   906
    by (simp add: pt_swap_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   907
  also have "\<dots> = f3 b (rfun f1 f2 f3 (([(a,b)])\<bullet>([(a,b)]\<bullet>t)))" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   908
  proof(rule rfun_Lam_aux2[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   909
    have "b\<sharp>([(a,b)]\<bullet>t)" using a1 a2
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   910
      by (simp add: pt_fresh_left[OF pt_name_inst, OF at_name_inst] at_calc[OF at_name_inst] 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   911
        at_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   912
    thus "b\<sharp>(a,[(a,b)]\<bullet>t,f1,f2,f3)" using a a1 by (force simp add: fresh_prod at_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   913
  qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   914
  also have "\<dots> = f3 b (rfun f1 f2 f3 t)" by (simp add: pt_swap_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   915
  finally show ?thesis .
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   916
qed
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   917
  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   918
lemma rec_unique:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   919
  fixes fun::"lam \<Rightarrow> ('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   920
  and   f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   921
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   922
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   923
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   924
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   925
  and     a1: "\<forall>c. fun (Var c) = f1 c" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   926
  and     a2: "\<forall>t1 t2. fun (App t1 t2) = f2 (fun t1) (fun t2)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   927
  and     a3: "\<forall>a t. a\<sharp>(f1,f2,f3) \<longrightarrow> fun (Lam [a].t) = f3 a (fun t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   928
  shows "fun t = rfun f1 f2 f3 t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   929
(*apply(nominal_induct t rule: lam_induct')*)
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
   930
apply (rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>_ t. fun t = rfun f1 f2 f3 t"])
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   931
(* finite support *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   932
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   933
(* VAR *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   934
apply(simp add: a1 rfun_Var[OF f, OF c, symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   935
(* APP *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   936
apply(simp add: a2 rfun_App[OF f, OF c, symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   937
(* LAM *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   938
apply(simp add: a3 rfun_Lam[OF f, OF c, symmetric])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   939
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   940
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   941
lemma rec_function:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   942
  fixes f1::"('a::pt_name) f1_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   943
  and   f2::"('a::pt_name) f2_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   944
  and   f3::"('a::pt_name) f3_ty"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   945
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   946
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   947
  shows "(\<exists>!(fun::lam \<Rightarrow> ('a::pt_name)).
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   948
              (\<forall>c.     fun (Var c)     = f1 c) \<and> 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   949
              (\<forall>t1 t2. fun (App t1 t2) = f2 (fun t1) (fun t2)) \<and> 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   950
              (\<forall>a t.   a\<sharp>(f1,f2,f3) \<longrightarrow> fun (Lam [a].t) = f3 a (fun t)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   951
apply(rule_tac a="\<lambda>t. rfun f1 f2 f3 t" in ex1I)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   952
(* existence *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   953
apply(simp add: rfun_Var[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   954
apply(simp add: rfun_App[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   955
apply(simp add: rfun_Lam[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   956
(* uniqueness *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   957
apply(auto simp add: expand_fun_eq)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   958
apply(rule rec_unique[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   959
apply(force)+
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   960
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   961
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   962
(* "real" recursion *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   963
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   964
types 'a f1_ty' = "name\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   965
      'a f2_ty' = "lam\<Rightarrow>lam\<Rightarrow>'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   966
      'a f3_ty' = "lam\<Rightarrow>name\<Rightarrow>'a\<Rightarrow>('a::pt_name)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   967
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   968
constdefs
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   969
  rfun_gen' :: "'a f1_ty' \<Rightarrow> 'a f2_ty' \<Rightarrow> 'a f3_ty' \<Rightarrow> lam \<Rightarrow> (lam\<times>'a::pt_name)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   970
  "rfun_gen' f1 f2 f3 t \<equiv> (rfun 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   971
                             (\<lambda>(a::name). (Var a,f1 a)) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   972
                             (\<lambda>r1 r2. (App (fst r1) (fst r2), f2 (fst r1) (fst r2) (snd r1) (snd r2))) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   973
                             (\<lambda>(a::name) r. (Lam [a].(fst r),f3 (fst r) a (snd r)))
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   974
                           t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   975
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   976
  rfun_gen :: "'a f1_ty' \<Rightarrow> 'a f2_ty' \<Rightarrow> 'a f3_ty' \<Rightarrow> lam \<Rightarrow> 'a::pt_name" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   977
  "rfun_gen f1 f2 f3 t \<equiv> snd(rfun_gen' f1 f2 f3 t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   978
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   979
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   980
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   981
lemma f1'_supports:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   982
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   983
  shows "((supp f1)::name set) supports (\<lambda>(a::name). (Var a,f1 a))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   984
  by (supports_simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   985
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   986
lemma f2'_supports:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   987
  fixes f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   988
  shows "((supp f2)::name set) supports 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   989
                         (\<lambda>r1 r2. (App (fst r1) (fst r2), f2 (fst r1) (fst r2) (snd r1) (snd r2)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   990
  by (supports_simp add: perm_fst perm_snd)  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   991
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   992
lemma f3'_supports:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   993
  fixes f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   994
  shows "((supp f3)::name set) supports (\<lambda>(a::name) r. (Lam [a].(fst r),f3 (fst r) a (snd r)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   995
by (supports_simp add: perm_fst perm_snd)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   996
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   997
lemma fcb': 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   998
  fixes f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
   999
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1000
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1001
  shows  "\<exists>a.  a \<sharp> (\<lambda>a r. (Lam [a].fst r, f3 (fst r) a (snd r))) \<and>
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1002
                (\<forall>y.  a \<sharp> (Lam [a].fst y, f3 (fst y) a (snd y)))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1003
using c f
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1004
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1005
apply(rule_tac x="a" in exI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1006
apply(auto simp add: abs_fresh fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1007
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1008
apply(rule f3'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1009
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1010
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1011
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1012
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1013
lemma fsupp':
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1014
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1015
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1016
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1017
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1018
  shows "finite((supp
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1019
          (\<lambda>a. (Var a, f1 a),
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1020
           \<lambda>r1 r2.
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1021
              (App (fst r1) (fst r2),
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1022
               f2 (fst r1) (fst r2) (snd r1) (snd r2)),
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1023
           \<lambda>a r. (Lam [a].fst r, f3 (fst r) a (snd r))))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1024
using f
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1025
apply(auto simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1026
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1027
apply(rule f1'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1028
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1029
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1030
apply(rule f2'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1031
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1032
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1033
apply(rule f3'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1034
apply(assumption)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1035
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1036
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1037
lemma rfun_gen'_fst:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1038
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1039
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1040
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1041
  assumes f: "finite ((supp (f1,f2,f3))::name set)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1042
  and     c: "(\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1043
  shows "fst (rfun_gen' f1 f2 f3 t) = t"
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
  1044
apply(rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>_ t. fst (rfun_gen' f1 f2 f3 t) = t"])
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1045
apply(simp add: f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1046
apply(unfold rfun_gen'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1047
apply(simp only: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1048
apply(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1049
apply(simp only: rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1050
apply(simp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1051
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1052
apply(rule trans)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1053
apply(rule_tac f="fst" in arg_cong)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1054
apply(rule rfun_Lam[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1055
apply(auto simp add: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1056
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1057
apply(rule f1'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1058
apply(subgoal_tac "finite ((supp (f1,f2,f3))::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1059
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1060
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1061
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1062
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1063
apply(rule f2'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1064
apply(subgoal_tac "finite ((supp (f1,f2,f3))::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1065
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1066
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1067
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1068
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1069
apply(rule f3'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1070
apply(subgoal_tac "finite ((supp (f1,f2,f3))::name set)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1071
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1072
apply(rule f)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1073
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1074
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1075
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1076
lemma rfun_gen'_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1077
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1078
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1079
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1080
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1081
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1082
  shows "rfun_gen' f1 f2 f3 (Var c) = (Var c, f1 c)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1083
apply(simp add: rfun_gen'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1084
apply(simp add: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1085
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1086
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1087
lemma rfun_gen'_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1088
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1089
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1090
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1091
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1092
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1093
  shows "rfun_gen' f1 f2 f3 (App t1 t2) = 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1094
                (App t1 t2, f2 t1 t2 (rfun_gen f1 f2 f3 t1) (rfun_gen f1 f2 f3 t2))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1095
apply(simp add: rfun_gen'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1096
apply(rule trans)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1097
apply(rule rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1098
apply(fold rfun_gen'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1099
apply(simp_all add: rfun_gen'_fst[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1100
apply(simp_all add: rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1101
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1102
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1103
lemma rfun_gen'_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1104
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1105
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1106
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1107
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1108
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1109
  and     a: "b\<sharp>(f1,f2,f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1110
  shows "rfun_gen' f1 f2 f3 (Lam [b].t) = (Lam [b].t, f3 t b (rfun_gen f1 f2 f3 t))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1111
using a f
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1112
apply(simp add: rfun_gen'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1113
apply(rule trans)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1114
apply(rule rfun_Lam[OF fsupp'[OF f],OF fcb'[OF f, OF c]])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1115
apply(auto simp add: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1116
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1117
apply(rule f1'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1118
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1119
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1120
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1121
apply(rule f2'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1122
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1123
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1124
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1125
apply(rule f3'_supports)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1126
apply(simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1127
apply(simp add: fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1128
apply(fold rfun_gen'_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1129
apply(simp_all add: rfun_gen'_fst[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1130
apply(simp_all add: rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1131
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1132
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1133
lemma rfun_gen_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1134
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1135
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1136
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1137
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1138
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1139
  shows "rfun_gen f1 f2 f3 (Var c) = f1 c"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1140
apply(unfold rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1141
apply(simp add: rfun_gen'_Var[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1142
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1143
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1144
lemma rfun_gen_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1145
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1146
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1147
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1148
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1149
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1150
  shows "rfun_gen f1 f2 f3 (App t1 t2) = f2 t1 t2 (rfun_gen f1 f2 f3 t1) (rfun_gen f1 f2 f3 t2)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1151
apply(unfold rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1152
apply(simp add: rfun_gen'_App[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1153
apply(simp add: rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1154
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1155
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1156
lemma rfun_gen_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1157
  fixes f1::"('a::pt_name) f1_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1158
  and   f2::"('a::pt_name) f2_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1159
  and   f3::"('a::pt_name) f3_ty'"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1160
  assumes f: "finite ((supp (f1,f2,f3))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1161
  and     c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1162
  and     a: "b\<sharp>(f1,f2,f3)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1163
  shows "rfun_gen f1 f2 f3 (Lam [b].t) = f3 t b (rfun_gen f1 f2 f3 t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1164
using a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1165
apply(unfold rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1166
apply(simp add: rfun_gen'_Lam[OF f, OF c])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1167
apply(simp add: rfun_gen_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1168
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1169
18269
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
  1170
(* FIXME: this should be automatically proved in nominal_atoms *)
3f36e2165e51 some small tuning
urbanc
parents: 18263
diff changeset
  1171
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1172
instance nat :: pt_name
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1173
apply(intro_classes)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1174
apply(simp_all add: perm_nat_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1175
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1176
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1177
constdefs 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1178
  depth_Var :: "name \<Rightarrow> nat"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1179
  "depth_Var \<equiv> \<lambda>(a::name). 1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1180
  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1181
  depth_App :: "nat \<Rightarrow> nat \<Rightarrow> nat"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1182
  "depth_App \<equiv> \<lambda>n1 n2. (max n1 n2)+1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1183
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1184
  depth_Lam :: "name \<Rightarrow> nat \<Rightarrow> nat"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1185
  "depth_Lam \<equiv> \<lambda>(a::name) n. n+1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1186
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1187
  depth_lam :: "lam \<Rightarrow> nat"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1188
  "depth_lam \<equiv> rfun depth_Var depth_App depth_Lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1189
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1190
lemma supp_depth_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1191
  shows "((supp depth_Var)::name set)={}"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1192
  apply(simp add: depth_Var_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1193
  apply(simp add: supp_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1194
  apply(simp add: perm_fun_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1195
  apply(simp add: perm_nat_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1196
  done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1197
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1198
lemma supp_depth_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1199
  shows "((supp depth_App)::name set)={}"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1200
  apply(simp add: depth_App_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1201
  apply(simp add: supp_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1202
  apply(simp add: perm_fun_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1203
  apply(simp add: perm_nat_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1204
  done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1205
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1206
lemma supp_depth_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1207
  shows "((supp depth_Lam)::name set)={}"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1208
  apply(simp add: depth_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1209
  apply(simp add: supp_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1210
  apply(simp add: perm_fun_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1211
  apply(simp add: perm_nat_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1212
  done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1213
 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1214
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1215
lemma fin_supp_depth:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1216
  shows "finite ((supp (depth_Var,depth_App,depth_Lam))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1217
  using supp_depth_Var supp_depth_Lam supp_depth_App
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1218
by (simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1219
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1220
lemma fresh_depth_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1221
  shows "\<exists>(a::name). a\<sharp>depth_Lam \<and> (\<forall>n. a\<sharp>depth_Lam a n)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1222
apply(rule exI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1223
apply(rule conjI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1224
apply(simp add: fresh_def supp_depth_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1225
apply(auto simp add: depth_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1226
apply(unfold fresh_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1227
apply(simp add: supp_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1228
apply(simp add: perm_nat_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1229
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1230
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1231
lemma depth_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1232
  shows "depth_lam (Var c) = 1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1233
apply(simp add: depth_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1234
apply(simp add: rfun_Var[OF fin_supp_depth, OF fresh_depth_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1235
apply(simp add: depth_Var_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1236
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1237
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1238
lemma depth_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1239
  shows "depth_lam (App t1 t2) = (max (depth_lam t1) (depth_lam t2))+1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1240
apply(simp add: depth_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1241
apply(simp add: rfun_App[OF fin_supp_depth, OF fresh_depth_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1242
apply(simp add: depth_App_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1243
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1244
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1245
lemma depth_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1246
  shows "depth_lam (Lam [a].t) = (depth_lam t)+1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1247
apply(simp add: depth_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1248
apply(rule trans)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1249
apply(rule rfun_Lam[OF fin_supp_depth, OF fresh_depth_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1250
apply(simp add: fresh_def supp_prod supp_depth_Var supp_depth_App supp_depth_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1251
apply(simp add: depth_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1252
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1253
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1254
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1255
(* substitution *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1256
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1257
constdefs 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1258
  subst_Var :: "name \<Rightarrow>lam \<Rightarrow> name \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1259
  "subst_Var b t \<equiv> \<lambda>a. (if a=b then t else (Var a))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1260
  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1261
  subst_App :: "name \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1262
  "subst_App b t \<equiv> \<lambda>r1 r2. App r1 r2"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1263
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1264
  subst_Lam :: "name \<Rightarrow> lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1265
  "subst_Lam b t \<equiv> \<lambda>a r. Lam [a].r"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1266
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1267
  subst_lam :: "name \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1268
  "subst_lam b t \<equiv> rfun (subst_Var b t) (subst_App b t) (subst_Lam b t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1269
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1270
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1271
lemma supports_subst_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1272
  shows "((supp (b,t))::name set) supports (subst_Var b t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1273
apply(supports_simp add: subst_Var_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1274
apply(rule impI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1275
apply(drule pt_bij1[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1276
apply(simp add: pt_fresh_fresh[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1277
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1278
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1279
lemma supports_subst_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1280
  shows "((supp (b,t))::name set) supports subst_App b t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1281
by (supports_simp add: subst_App_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1282
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1283
lemma supports_subst_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1284
  shows "((supp (b,t))::name set) supports subst_Lam b t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1285
  by (supports_simp add: subst_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1286
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1287
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1288
lemma fin_supp_subst:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1289
  shows "finite ((supp (subst_Var b t,subst_App b t,subst_Lam b t))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1290
apply(auto simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1291
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1292
apply(rule supports_subst_Var)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1293
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1294
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1295
apply(rule supports_subst_App)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1296
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1297
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1298
apply(rule supports_subst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1299
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1300
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1301
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1302
lemma fresh_subst_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1303
  shows "\<exists>(a::name). a\<sharp>(subst_Lam b t)\<and> (\<forall>y. a\<sharp>(subst_Lam b t) a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1304
apply(subgoal_tac "\<exists>(c::name). c\<sharp>(b,t)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1305
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1306
apply(rule_tac x="c" in exI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1307
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1308
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1309
apply(rule supports_subst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1310
apply(simp_all add: fresh_def[symmetric] fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1311
apply(simp add: subst_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1312
apply(simp add: abs_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1313
apply(rule at_exists_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1314
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1315
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1316
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1317
lemma subst_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1318
  shows "subst_lam b t (Var a) = (if a=b then t else (Var a))"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1319
apply(simp add: subst_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1320
apply(auto simp add: rfun_Var[OF fin_supp_subst, OF fresh_subst_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1321
apply(auto simp add: subst_Var_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1322
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1323
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1324
lemma subst_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1325
  shows "subst_lam b t (App t1 t2) = App (subst_lam b t t1) (subst_lam b t t2)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1326
apply(simp add: subst_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1327
apply(auto simp add: rfun_App[OF fin_supp_subst, OF fresh_subst_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1328
apply(auto simp add: subst_App_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1329
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1330
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1331
lemma subst_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1332
  assumes a: "a\<sharp>(b,t)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1333
  shows "subst_lam b t (Lam [a].t1) = Lam [a].(subst_lam b t t1)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1334
using a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1335
apply(simp add: subst_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1336
apply(subgoal_tac "a\<sharp>(subst_Var b t,subst_App b t,subst_Lam b t)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1337
apply(auto simp add: rfun_Lam[OF fin_supp_subst, OF fresh_subst_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1338
apply(simp (no_asm) add: subst_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1339
apply(auto simp add: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1340
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1341
apply(rule supports_subst_Var)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1342
apply(simp_all add: fs_name1 fresh_def[symmetric] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1343
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1344
apply(rule supports_subst_App)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1345
apply(simp_all add: fs_name1 fresh_def[symmetric] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1346
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1347
apply(rule supports_subst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1348
apply(simp_all add: fs_name1 fresh_def[symmetric] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1349
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1350
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1351
lemma subst_Lam':
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1352
  assumes a: "a\<noteq>b"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1353
  and     b: "a\<sharp>t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1354
  shows "subst_lam b t (Lam [a].t1) = Lam [a].(subst_lam b t t1)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1355
apply(rule subst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1356
apply(simp add: fresh_prod a b fresh_atm)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1357
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1358
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1359
consts
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1360
  subst_syn  :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam" ("_[_::=_]" [100,100,100] 900)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1361
translations 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1362
  "t1[a::=t2]" \<rightleftharpoons> "subst_lam a t2 t1"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1363
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1364
declare subst_Var[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1365
declare subst_App[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1366
declare subst_Lam[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1367
declare subst_Lam'[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1368
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1369
lemma subst_eqvt[simp]:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1370
  fixes pi:: "name prm"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1371
  and   t1:: "lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1372
  and   t2:: "lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1373
  and   a :: "name"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1374
  shows "pi\<bullet>(t1[a::=t2]) = (pi\<bullet>t1)[(pi\<bullet>a)::=(pi\<bullet>t2)]"
18284
cd217d16c90d changed the order of the induction variable and the context
urbanc
parents: 18269
diff changeset
  1375
thm lam_induct
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1376
apply(nominal_induct t1 rule: lam_induct)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1377
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1378
apply(auto simp add: perm_bij fresh_prod fresh_atm)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1379
apply(subgoal_tac "(aa\<bullet>ab)\<sharp>(aa\<bullet>a,aa\<bullet>b)")(*A*)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1380
apply(simp) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1381
apply(simp add: perm_bij fresh_prod fresh_atm pt_fresh_bij[OF pt_name_inst, OF at_name_inst]) 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1382
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1383
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1384
lemma subst_supp: "supp(t1[a::=t2])\<subseteq>(((supp(t1)-{a})\<union>supp(t2))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1385
apply(nominal_induct t1 rule: lam_induct)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1386
apply(auto simp add: lam.supp supp_atm fresh_prod abs_supp)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1387
apply(blast)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1388
apply(blast)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1389
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1390
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1391
(* parallel substitution *)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1392
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1393
consts
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1394
  "domain" :: "(name\<times>lam) list \<Rightarrow> (name list)"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1395
primrec
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1396
  "domain []    = []"
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1397
  "domain (x#\<theta>) = (fst x)#(domain \<theta>)" 
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1398
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1399
consts
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1400
  "apply_sss"  :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam" (" _ < _ >" [80,80] 80)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1401
primrec  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1402
"(x#\<theta>)<a>  = (if (a = fst x) then (snd x) else \<theta><a>)" 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1403
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1404
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1405
lemma apply_sss_eqvt[rule_format]:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1406
  fixes pi::"name prm"
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1407
  shows "a\<in>set (domain \<theta>) \<longrightarrow> pi\<bullet>(\<theta><a>) = (pi\<bullet>\<theta>)<pi\<bullet>a>"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1408
apply(induct_tac \<theta>)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1409
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1410
apply(simp add: pt_bij[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1411
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1412
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1413
lemma domain_eqvt[rule_format]:
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1414
  fixes pi::"name prm"
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1415
  shows "((pi\<bullet>a)\<in>set (domain \<theta>)) =  (a\<in>set (domain ((rev pi)\<bullet>\<theta>)))"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1416
apply(induct_tac \<theta>)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1417
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1418
apply(simp_all add: pt_rev_pi[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1419
apply(simp_all add: pt_pi_rev[OF pt_name_inst, OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1420
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1421
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1422
constdefs 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1423
  psubst_Var :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam"
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1424
  "psubst_Var \<theta> \<equiv> \<lambda>a. (if a\<in>set (domain \<theta>) then \<theta><a> else (Var a))"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1425
  
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1426
  psubst_App :: "(name\<times>lam) list \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1427
  "psubst_App \<theta> \<equiv> \<lambda>r1 r2. App r1 r2"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1428
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1429
  psubst_Lam :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1430
  "psubst_Lam \<theta> \<equiv> \<lambda>a r. Lam [a].r"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1431
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1432
  psubst_lam :: "(name\<times>lam) list \<Rightarrow> lam \<Rightarrow> lam"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1433
  "psubst_lam \<theta> \<equiv> rfun (psubst_Var \<theta>) (psubst_App \<theta>) (psubst_Lam \<theta>)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1434
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1435
lemma supports_psubst_Var:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1436
  shows "((supp \<theta>)::name set) supports (psubst_Var \<theta>)"
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1437
  by (supports_simp add: psubst_Var_def apply_sss_eqvt domain_eqvt)
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1438
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1439
lemma supports_psubst_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1440
  shows "((supp \<theta>)::name set) supports psubst_App \<theta>"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1441
  by (supports_simp add: psubst_App_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1442
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1443
lemma supports_psubst_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1444
  shows "((supp \<theta>)::name set) supports psubst_Lam \<theta>"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1445
  by (supports_simp add: psubst_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1446
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1447
lemma fin_supp_psubst:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1448
  shows "finite ((supp (psubst_Var \<theta>,psubst_App \<theta>,psubst_Lam \<theta>))::name set)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1449
apply(auto simp add: supp_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1450
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1451
apply(rule supports_psubst_Var)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1452
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1453
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1454
apply(rule supports_psubst_App)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1455
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1456
apply(rule supports_finite)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1457
apply(rule supports_psubst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1458
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1459
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1460
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1461
lemma fresh_psubst_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1462
  shows "\<exists>(a::name). a\<sharp>(psubst_Lam \<theta>)\<and> (\<forall>y. a\<sharp>(psubst_Lam \<theta>) a y)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1463
apply(subgoal_tac "\<exists>(c::name). c\<sharp>\<theta>")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1464
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1465
apply(rule_tac x="c" in exI)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1466
apply(auto)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1467
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1468
apply(rule supports_psubst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1469
apply(simp_all add: fresh_def[symmetric] fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1470
apply(simp add: psubst_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1471
apply(simp add: abs_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1472
apply(rule at_exists_fresh[OF at_name_inst])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1473
apply(simp add: fs_name1)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1474
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1475
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1476
lemma psubst_Var:
18263
7f75925498da cleaned up all examples so that they work with the
urbanc
parents: 18106
diff changeset
  1477
  shows "psubst_lam \<theta> (Var a) = (if a\<in>set (domain \<theta>) then \<theta><a> else (Var a))"
18106
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1478
apply(simp add: psubst_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1479
apply(auto simp add: rfun_Var[OF fin_supp_psubst, OF fresh_psubst_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1480
apply(auto simp add: psubst_Var_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1481
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1482
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1483
lemma psubst_App:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1484
  shows "psubst_lam \<theta> (App t1 t2) = App (psubst_lam \<theta> t1) (psubst_lam \<theta> t2)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1485
apply(simp add: psubst_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1486
apply(auto simp add: rfun_App[OF fin_supp_psubst, OF fresh_psubst_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1487
apply(auto simp add: psubst_App_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1488
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1489
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1490
lemma psubst_Lam:
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1491
  assumes a: "a\<sharp>\<theta>"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1492
  shows "psubst_lam \<theta> (Lam [a].t1) = Lam [a].(psubst_lam \<theta> t1)"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1493
using a
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1494
apply(simp add: psubst_lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1495
apply(subgoal_tac "a\<sharp>(psubst_Var \<theta>,psubst_App \<theta>,psubst_Lam \<theta>)")
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1496
apply(auto simp add: rfun_Lam[OF fin_supp_psubst, OF fresh_psubst_Lam])
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1497
apply(simp (no_asm) add: psubst_Lam_def)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1498
apply(auto simp add: fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1499
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1500
apply(rule supports_psubst_Var)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1501
apply(simp_all add: fs_name1 fresh_def[symmetric] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1502
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1503
apply(rule supports_psubst_App)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1504
apply(simp_all add: fs_name1 fresh_def[symmetric] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1505
apply(rule supports_fresh)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1506
apply(rule supports_psubst_Lam)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1507
apply(simp_all add: fs_name1 fresh_def[symmetric] fresh_prod)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1508
done
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1509
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1510
declare psubst_Var[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1511
declare psubst_App[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1512
declare psubst_Lam[simp]
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1513
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1514
consts
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1515
  psubst_syn  :: "lam \<Rightarrow> (name\<times>lam) list \<Rightarrow> lam" ("_[<_>]" [100,100] 900)
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1516
translations 
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1517
  "t[<\<theta>>]" \<rightleftharpoons> "psubst_lam \<theta> t"
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1518
836135c8acb2 Initial commit.
urbanc
parents:
diff changeset
  1519
end