src/HOL/Nominal/Examples/Lam_Funs.thy
author urbanc
Mon, 30 Oct 2006 13:07:51 +0100
changeset 21107 e69c0e82955a
child 21404 eb85850d3eb7
permissions -rw-r--r--
new file for defining functions in the lambda-calculus
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21107
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     1
(* $Id: *)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     2
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     3
theory Lam_Funs
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     4
imports Nominal
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     5
begin
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     6
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     7
atom_decl name
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     8
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
     9
nominal_datatype lam = Var "name"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    10
                     | App "lam" "lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    11
                     | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    12
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    13
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    14
constdefs 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    15
  depth_Var :: "name \<Rightarrow> nat"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    16
  "depth_Var \<equiv> \<lambda>(a::name). 1"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    17
  
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    18
  depth_App :: "lam \<Rightarrow> lam \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    19
  "depth_App \<equiv> \<lambda>_ _ n1 n2. (max n1 n2)+1"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    20
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    21
  depth_Lam :: "name \<Rightarrow> lam \<Rightarrow> nat \<Rightarrow> nat"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    22
  "depth_Lam \<equiv> \<lambda>_ _ n. n+1"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    23
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    24
  depth_lam :: "lam \<Rightarrow> nat"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    25
  "depth_lam t \<equiv> (lam_rec depth_Var depth_App depth_Lam) t"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    26
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    27
lemma fin_supp_depth_lam:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    28
  shows "finite ((supp depth_Var)::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    29
  and   "finite ((supp depth_Lam)::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    30
  and   "finite ((supp depth_App)::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    31
  by (finite_guess add: depth_Var_def depth_Lam_def depth_App_def perm_nat_def)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    32
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    33
lemma fcb_depth_lam:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    34
  fixes a::"name"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    35
  shows "a\<sharp>(depth_Lam a t n)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    36
  by (simp add: fresh_nat)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    37
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    38
lemma depth_lam:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    39
  shows "depth_lam (Var a)     = 1"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    40
  and   "depth_lam (App t1 t2) = (max (depth_lam t1) (depth_lam t2))+1"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    41
  and   "depth_lam (Lam [a].t) = (depth_lam t)+1"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    42
apply -
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    43
apply(unfold depth_lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    44
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    45
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    46
apply(simp_all add: fin_supp_depth_lam supp_unit)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    47
apply(simp add: fcb_depth_lam)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    48
apply(simp add: depth_Var_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    49
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    50
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    51
apply(simp_all add: fin_supp_depth_lam supp_unit)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    52
apply(simp add: fcb_depth_lam)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    53
apply(simp add: depth_App_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    54
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    55
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    56
apply(simp_all add: fin_supp_depth_lam supp_unit)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    57
apply(simp add: fcb_depth_lam)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    58
apply(simp add: depth_Var_def, fresh_guess add: perm_nat_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    59
apply(simp add: depth_App_def, fresh_guess add: perm_nat_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    60
apply(simp add: depth_Lam_def, fresh_guess add: perm_nat_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    61
apply(simp add: depth_Lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    62
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    63
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    64
text {* capture-avoiding substitution *}
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    65
constdefs 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    66
  subst_Var :: "name \<Rightarrow>lam \<Rightarrow> name \<Rightarrow> lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    67
  "subst_Var b t \<equiv> \<lambda>a. (if a=b then t else (Var a))"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    68
  
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    69
  subst_App :: "name \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    70
  "subst_App b t \<equiv> \<lambda>_ _ r1 r2. App r1 r2"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    71
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    72
  subst_Lam :: "name \<Rightarrow> lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    73
  "subst_Lam b t \<equiv> \<lambda>a _ r. Lam [a].r"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    74
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    75
abbreviation
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    76
  subst_syn  :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam" ("_[_::=_]" [100,100,100] 900) 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    77
  "t'[b::=t] \<equiv> (lam_rec (subst_Var b t) (subst_App b t) (subst_Lam b t)) t'"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    78
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    79
(* FIXME: this lemma needs to be in Nominal.thy *)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    80
lemma eq_eqvt:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    81
  fixes pi::"name prm"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    82
  and   x::"'a::pt_name"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    83
  shows "pi\<bullet>(x=y) = ((pi\<bullet>x)=(pi\<bullet>y))"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    84
  apply(simp add: perm_bool perm_bij)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    85
  done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    86
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    87
lemma fin_supp_subst:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    88
  shows "finite ((supp (subst_Var b t))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    89
  and   "finite ((supp (subst_Lam b t))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    90
  and   "finite ((supp (subst_App b t))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    91
apply -
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    92
apply(finite_guess add: subst_Var_def perm_if eq_eqvt fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    93
apply(finite_guess add: subst_Lam_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    94
apply(finite_guess add: subst_App_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    95
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    96
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    97
lemma fcb_subst:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    98
  fixes a::"name"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
    99
  shows "a\<sharp>(subst_Lam b t) a t' r"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   100
  by (simp add: subst_Lam_def abs_fresh)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   101
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   102
lemma subst[simp]:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   103
  shows "(Var a)[b::=t] = (if a=b then t else (Var a))"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   104
  and   "(App t1 t2)[b::=t] = App (t1[b::=t]) (t2[b::=t])"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   105
  and   "a\<sharp>(b,t)    \<Longrightarrow> (Lam [a].t1)[b::=t] = Lam [a].(t1[b::=t])"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   106
  and   "\<lbrakk>a\<noteq>b; a\<sharp>t\<rbrakk> \<Longrightarrow> (Lam [a].t1)[b::=t] = Lam [a].(t1[b::=t])"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   107
  and   "\<lbrakk>a\<sharp>b; a\<sharp>t\<rbrakk> \<Longrightarrow> (Lam [a].t1)[b::=t] = Lam [a].(t1[b::=t])"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   108
apply -
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   109
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   110
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   111
apply(simp add: fs_name1 fin_supp_subst)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   112
apply(simp add: fcb_subst)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   113
apply(simp add: subst_Var_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   114
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   115
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   116
apply(simp add: fs_name1 fin_supp_subst)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   117
apply(simp add: fcb_subst)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   118
apply(simp add: subst_App_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   119
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   120
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   121
apply(simp add: fs_name1 fin_supp_subst)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   122
apply(simp add: fcb_subst)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   123
apply(fresh_guess add: subst_Var_def perm_if eq_eqvt fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   124
apply(fresh_guess add: subst_App_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   125
apply(fresh_guess add: subst_Lam_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   126
apply(simp add: subst_Lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   127
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   128
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   129
apply(simp add: fs_name1 fin_supp_subst)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   130
apply(simp add: fcb_subst)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   131
apply(fresh_guess add: subst_Var_def perm_if eq_eqvt fs_name1 fresh_atm)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   132
apply(fresh_guess add: subst_App_def fs_name1 fresh_atm)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   133
apply(fresh_guess add: subst_Lam_def fs_name1 fresh_atm)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   134
apply(simp add: subst_Lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   135
apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   136
apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   137
apply(simp add: fs_name1 fin_supp_subst)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   138
apply(simp add: fcb_subst)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   139
apply(fresh_guess add: subst_Var_def perm_if eq_eqvt fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   140
apply(fresh_guess add: subst_App_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   141
apply(fresh_guess add: subst_Lam_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   142
apply(simp add: subst_Lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   143
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   144
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   145
lemma subst_eqvt[simp]:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   146
  fixes pi:: "name prm"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   147
  and   t1:: "lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   148
  and   t2:: "lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   149
  and   a :: "name"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   150
  shows "pi\<bullet>(t1[b::=t2]) = (pi\<bullet>t1)[(pi\<bullet>b)::=(pi\<bullet>t2)]"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   151
apply(nominal_induct t1 avoiding: b t2 rule: lam.induct)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   152
apply(auto simp add: perm_bij fresh_prod fresh_atm fresh_bij)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   153
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   154
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   155
lemma subst_supp: 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   156
  shows "supp(t1[a::=t2]) \<subseteq> (((supp(t1)-{a})\<union>supp(t2))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   157
apply(nominal_induct t1 avoiding: a t2 rule: lam.induct)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   158
apply(auto simp add: lam.supp supp_atm fresh_prod abs_supp)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   159
apply(blast)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   160
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   161
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   162
(* parallel substitution *)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   163
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   164
(* simultaneous substitution *)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   165
consts
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   166
  "domain" :: "(name\<times>lam) list \<Rightarrow> (name list)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   167
primrec
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   168
  "domain []    = []"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   169
  "domain (x#\<theta>) = (fst x)#(domain \<theta>)" 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   170
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   171
consts
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   172
  "apply_sss"  :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam" (" _ < _ >" [80,80] 80)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   173
primrec  
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   174
"(x#\<theta>)<a>  = (if (a = fst x) then (snd x) else \<theta><a>)" 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   175
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   176
lemma apply_sss_eqvt:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   177
  fixes pi::"name prm"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   178
  assumes a: "a\<in>set (domain \<theta>)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   179
  shows "pi\<bullet>(\<theta><a>) = (pi\<bullet>\<theta>)<pi\<bullet>a>"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   180
using a
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   181
by (induct \<theta>)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   182
   (auto simp add: perm_bij)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   183
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   184
lemma domain_eqvt:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   185
  fixes pi::"name prm"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   186
  shows "((pi\<bullet>a)\<in>set (domain \<theta>)) = (a\<in>set (domain ((rev pi)\<bullet>\<theta>)))"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   187
apply(induct \<theta>)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   188
apply(auto)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   189
apply(perm_simp)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   190
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   191
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   192
constdefs 
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   193
  psubst_Var :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   194
  "psubst_Var \<theta> \<equiv> \<lambda>a. (if a\<in>set (domain \<theta>) then \<theta><a> else (Var a))"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   195
  
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   196
  psubst_App :: "(name\<times>lam) list \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   197
  "psubst_App \<theta> \<equiv> \<lambda>_ _ r1 r2. App r1 r2"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   198
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   199
  psubst_Lam :: "(name\<times>lam) list \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam \<Rightarrow> lam"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   200
  "psubst_Lam \<theta> \<equiv> \<lambda>a _ r. Lam [a].r"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   201
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   202
abbreviation
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   203
  psubst_lam :: "lam \<Rightarrow> (name\<times>lam) list \<Rightarrow> lam" ("_[<_>]" [100,100] 900)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   204
  "t[<\<theta>>] \<equiv> (lam_rec (psubst_Var \<theta>) (psubst_App \<theta>) (psubst_Lam \<theta>)) t"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   205
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   206
lemma fin_supp_psubst:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   207
  shows "finite ((supp (psubst_Var \<theta>))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   208
  and   "finite ((supp (psubst_Lam \<theta>))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   209
  and   "finite ((supp (psubst_App \<theta>))::name set)"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   210
  apply -
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   211
  apply(finite_guess add: fs_name1 psubst_Var_def domain_eqvt apply_sss_eqvt)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   212
  apply(finite_guess add: fs_name1 psubst_Lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   213
  apply(finite_guess add: fs_name1 psubst_App_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   214
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   215
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   216
lemma fcb_psubst_Lam:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   217
  shows "x\<sharp>(psubst_Lam \<theta>) x t r"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   218
  by (simp add: psubst_Lam_def abs_fresh)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   219
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   220
lemma psubst[simp]:
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   221
  shows "(Var a)[<\<theta>>] = (if a\<in>set (domain \<theta>) then \<theta><a> else (Var a))"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   222
  and   "(App t1 t2)[<\<theta>>] = App (t1[<\<theta>>]) (t2[<\<theta>>])"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   223
  and   "a\<sharp>\<theta> \<Longrightarrow> (Lam [a].t1)[<\<theta>>] = Lam [a].(t1[<\<theta>>])"
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   224
  apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   225
  apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   226
  apply(simp add: fin_supp_psubst fs_name1)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   227
  apply(simp add: fcb_psubst_Lam)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   228
  apply(simp add: psubst_Var_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   229
  apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   230
  apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   231
  apply(simp add: fin_supp_psubst fs_name1)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   232
  apply(simp add: fcb_psubst_Lam)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   233
  apply(simp add: psubst_App_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   234
  apply(rule trans)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   235
  apply(rule lam.recs[where P="\<lambda>_. True" and z="()", simplified])
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   236
  apply(simp add: fin_supp_psubst fs_name1)+
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   237
  apply(simp add: fcb_psubst_Lam)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   238
  apply(fresh_guess add: psubst_Var_def domain_eqvt apply_sss_eqvt fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   239
  apply(fresh_guess add: psubst_App_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   240
  apply(fresh_guess add: psubst_Lam_def fs_name1)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   241
  apply(simp add: psubst_Lam_def)
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   242
done
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   243
e69c0e82955a new file for defining functions in the lambda-calculus
urbanc
parents:
diff changeset
   244
end