Nominal/Ex/Exec/Lambda_Exec.thy
author Cezary Kaliszyk <cezarykaliszyk@gmail.com>
Thu, 24 May 2012 10:17:32 +0200
changeset 3175 52730e5ec8cb
parent 3173 9876d73adb2b
child 3235 5ebd327ffb96
permissions -rw-r--r--
Synchronize Nominal2_Base_Exec with Nominal2_Base, equivariance for Let, avoid overloading approx twice and changes for new isabelle
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3173
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     1
theory Lambda_Exec
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     2
imports Name_Exec
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     3
begin
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     4
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     5
nominal_datatype lam =
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     6
  Var "name"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     7
| App "lam" "lam"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     8
| Lam x::"name" l::"lam"  binds x in l ("Lam [_]. _" [100, 100] 100)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
     9
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    10
nominal_primrec
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    11
  subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [90, 90, 90] 90)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    12
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    13
  "(Var x)[y ::= s] = (if x = y then s else (Var x))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    14
| "(App t1 t2)[y ::= s] = App (t1[y ::= s]) (t2[y ::= s])"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    15
| "atom x \<sharp> (y, s) \<Longrightarrow> (Lam [x]. t)[y ::= s] = Lam [x].(t[y ::= s])"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    16
proof auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    17
  fix a b :: lam and aa :: name and P
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    18
  assume "\<And>x y s. a = Var x \<and> aa = y \<and> b = s \<Longrightarrow> P"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    19
    "\<And>t1 t2 y s. a = App t1 t2 \<and> aa = y \<and> b = s \<Longrightarrow> P"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    20
    "\<And>x y s t. \<lbrakk>atom x \<sharp> (y, s); a = Lam [x]. t \<and> aa = y \<and> b = s\<rbrakk> \<Longrightarrow> P"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    21
  then show "P"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    22
    by (rule_tac y="a" and c="(aa, b)" in lam.strong_exhaust)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    23
       (blast, blast, simp add: fresh_star_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    24
next
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    25
  fix x :: name and t and xa :: name and ya sa ta
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    26
  assume *: "eqvt_at subst_sumC (t, ya, sa)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    27
    "atom x \<sharp> (ya, sa)" "atom xa \<sharp> (ya, sa)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    28
    "[[atom x]]lst. t = [[atom xa]]lst. ta"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    29
  then show "[[atom x]]lst. subst_sumC (t, ya, sa) = [[atom xa]]lst. subst_sumC (ta, ya, sa)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    30
    apply -
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    31
    apply (erule Abs_lst1_fcb)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    32
    apply(simp (no_asm) add: Abs_fresh_iff)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    33
    apply(drule_tac a="atom xa" in fresh_eqvt_at)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    34
    apply(simp add: finite_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    35
    apply(simp_all add: fresh_Pair_elim Abs_fresh_iff Abs1_eq_iff)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    36
    apply(subgoal_tac "(atom x \<rightleftharpoons> atom xa) \<bullet> ya = ya")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    37
    apply(subgoal_tac "(atom x \<rightleftharpoons> atom xa) \<bullet> sa = sa")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    38
    apply(simp add: atom_eqvt eqvt_at_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    39
    apply(rule perm_supp_eq, simp add: supp_swap fresh_star_def fresh_Pair)+
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    40
    done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    41
next
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    42
  show "eqvt subst_graph" unfolding eqvt_def subst_graph_def
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    43
    by (rule, perm_simp, rule)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    44
qed
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    45
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    46
termination (eqvt) by lexicographic_order
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    47
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    48
datatype ln =
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    49
  LNBnd nat
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    50
| LNVar name
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    51
| LNApp ln ln
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    52
| LNLam ln
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    53
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    54
instantiation ln :: pt begin
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    55
fun
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    56
  permute_ln
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    57
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    58
  "p \<bullet> LNBnd n = LNBnd (p \<bullet> n)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    59
| "p \<bullet> LNVar v = LNVar (p \<bullet> v)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    60
| "p \<bullet> LNApp d1 d2 = LNApp (p \<bullet> d1) (p \<bullet> d2)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    61
| "p \<bullet> LNLam d = LNLam (p \<bullet> d)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    62
instance
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    63
  by (default, induct_tac [!] x) simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    64
end
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    65
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    66
lemmas [eqvt] = permute_ln.simps
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    67
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    68
lemma ln_supports:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    69
  "supp (n) supports LNBnd n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    70
  "supp (v) supports LNVar v"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    71
  "supp (za, z) supports LNApp z za"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    72
  "supp (z) supports LNLam z"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    73
  by (simp_all add: supports_def fresh_def[symmetric])
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    74
     (perm_simp, simp add: swap_fresh_fresh fresh_Pair)+
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    75
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    76
instance ln :: fs
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    77
  apply default
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    78
  apply (induct_tac x)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    79
  apply (rule supports_finite, rule ln_supports, simp add: finite_supp supp_Pair)+
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    80
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    81
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    82
lemma ln_supp:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    83
  "supp (LNBnd n) = supp n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    84
  "supp (LNVar name) = supp name"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    85
  "supp (LNApp ln1 ln2) = supp ln1 \<union> supp ln2"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    86
  "supp (LNLam ln) = supp ln"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    87
  unfolding supp_Pair[symmetric]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    88
  by (simp_all add: supp_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    89
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    90
lemma ln_fresh:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    91
  "x \<sharp> LNBnd n \<longleftrightarrow> True"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    92
  "x \<sharp> LNVar name \<longleftrightarrow> x \<sharp> name"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    93
  "x \<sharp> LNApp ln1 ln2 \<longleftrightarrow> x \<sharp> ln1 \<and> x \<sharp> ln2"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    94
  "x \<sharp> LNLam ln = x \<sharp> ln"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    95
  unfolding fresh_def
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    96
  by (simp_all add: ln_supp pure_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    97
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    98
fun
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
    99
  lookup :: "name list \<Rightarrow> nat \<Rightarrow> name \<Rightarrow> ln"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   100
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   101
  "lookup [] n x = LNVar x"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   102
| "lookup (y # ys) n x = (if x = y then LNBnd n else (lookup ys (n + 1) x))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   103
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   104
lemma supp_lookup:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   105
  shows "supp (lookup xs n x) \<subseteq> {atom x}"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   106
  by (induct arbitrary: n rule: lookup.induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   107
     (simp_all add: supp_at_base ln_supp pure_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   108
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   109
lemma supp_lookup_in:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   110
  shows "x \<in> set xs \<Longrightarrow> supp (lookup xs n x) = {}"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   111
  by (induct arbitrary: n rule: lookup.induct) (auto simp add: ln_supp pure_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   112
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   113
lemma supp_lookup_notin:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   114
  shows "x \<notin> set xs \<Longrightarrow> supp (lookup xs n x) = {atom x}"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   115
  by (induct arbitrary: n rule: lookup.induct) (auto simp add: ln_supp pure_supp supp_at_base)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   116
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   117
lemma supp_lookup_fresh:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   118
  shows "atom ` set xs \<sharp>* lookup xs n x"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   119
  by (case_tac "x \<in> set xs") (auto simp add: fresh_star_def fresh_def supp_lookup_in supp_lookup_notin)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   120
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   121
lemma lookup_eqvt[eqvt]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   122
  shows "(p \<bullet> lookup xs n x) = lookup (p \<bullet> xs) (p \<bullet> n) (p \<bullet> x)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   123
  by (induct xs arbitrary: n) (simp_all add: permute_pure)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   124
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   125
nominal_primrec (invariant "\<lambda>(_, xs) y. atom ` set xs \<sharp>* y")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   126
  lam_ln_aux :: "lam \<Rightarrow> name list \<Rightarrow> ln"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   127
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   128
  "lam_ln_aux (Var x) xs = lookup xs 0 x"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   129
| "lam_ln_aux (App t1 t2) xs = LNApp (lam_ln_aux t1 xs) (lam_ln_aux t2 xs)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   130
| "atom x \<sharp> xs \<Longrightarrow> lam_ln_aux (Lam [x]. t) xs = LNLam (lam_ln_aux t (x # xs))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   131
  apply (simp add: eqvt_def lam_ln_aux_graph_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   132
  apply (rule, perm_simp, rule)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   133
  apply (erule lam_ln_aux_graph.induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   134
  apply (auto simp add: ln_supp)[3]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   135
  apply (simp add: supp_lookup_fresh)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   136
  apply (simp add: fresh_star_def ln_supp fresh_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   137
  apply (simp add: ln_supp fresh_def fresh_star_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   138
  apply (case_tac x)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   139
  apply (rule_tac y="a" and c="b" in lam.strong_exhaust)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   140
  apply (auto simp add: fresh_star_def)[3]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   141
  apply(simp_all)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   142
  apply(erule conjE)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   143
  apply (erule_tac c="xsa" in Abs_lst1_fcb2')
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   144
  apply (simp_all add: fresh_star_def)[2]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   145
  apply (simp_all add: eqvt_at_def atom_eqvt fresh_star_Pair perm_supp_eq)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   146
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   147
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   148
termination (eqvt) by lexicographic_order
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   149
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   150
definition lam_ln where "lam_ln t \<equiv> lam_ln_aux t []"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   151
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   152
fun nth_or_def where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   153
  "nth_or_def [] _ d = d"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   154
| "nth_or_def (h # t) 0 d = h"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   155
| "nth_or_def (h # t) (Suc n) d = nth_or_def t n d"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   156
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   157
lemma nth_or_def_eqvt [eqvt]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   158
  "p \<bullet> (nth_or_def l n d) = nth_or_def (p \<bullet> l) (p \<bullet> n) (p \<bullet> d)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   159
  apply (cases l)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   160
  apply auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   161
  apply (induct n arbitrary: list)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   162
  apply (auto simp add: permute_pure)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   163
  apply (case_tac list)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   164
  apply simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   165
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   166
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   167
nominal_primrec
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   168
  ln_lam_aux :: "ln \<Rightarrow> name list \<Rightarrow> lam"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   169
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   170
  "ln_lam_aux (LNBnd n) ns = (nth_or_def (map Var ns) n (Lam [x]. Var x))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   171
| "ln_lam_aux (LNVar v) ns = Var v"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   172
| "ln_lam_aux (LNApp l1 l2) ns = App (ln_lam_aux l1 ns) (ln_lam_aux l2 ns)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   173
| "atom x \<sharp> (ns, l) \<Longrightarrow> ln_lam_aux (LNLam l) ns = Lam [x]. (ln_lam_aux l (x # ns))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   174
  apply (simp add: eqvt_def ln_lam_aux_graph_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   175
  apply (rule, perm_simp, rule)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   176
  apply rule
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   177
  apply(auto)[1]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   178
  apply (rule_tac y="a" in ln.exhaust)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   179
  apply (auto simp add: fresh_star_def)[4]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   180
  using obtain_fresh apply metis
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   181
  apply (auto simp add: fresh_Pair_elim)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   182
  apply (subgoal_tac "Lam [x]. Var x = Lam [xa]. Var xa")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   183
  apply (simp del: lam.eq_iff)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   184
  apply (simp add: Abs1_eq_iff lam.fresh fresh_at_base)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   185
  apply (simp add: Abs1_eq_iff)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   186
  apply (case_tac "x=xa")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   187
  apply simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   188
  apply rule
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   189
  apply (auto simp add: eqvt_at_def swap_fresh_fresh)[1]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   190
  apply (erule fresh_eqvt_at)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   191
  apply (simp add: supp_Pair finite_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   192
  apply (simp add: fresh_Pair fresh_Cons fresh_at_base)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   193
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   194
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   195
termination (eqvt)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   196
  by lexicographic_order
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   197
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   198
definition ln_lam where "ln_lam t \<equiv> ln_lam_aux t []"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   199
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   200
lemma l_fresh_lam_ln_aux: "atom ` set l \<sharp>* lam_ln_aux t l"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   201
  apply (nominal_induct t avoiding: l rule: lam.strong_induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   202
  apply (simp_all add: fresh_def ln_supp pure_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   203
  apply (auto simp add: fresh_star_def)[1]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   204
  apply (case_tac "a = name")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   205
  apply (auto simp add: supp_lookup_in fresh_def)[1]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   206
  apply (simp add: fresh_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   207
  using supp_lookup
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   208
  apply (metis (lifting) atom_eq_iff equals0D singletonE supp_lookup_in supp_lookup_notin)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   209
  apply (simp add: fresh_star_def fresh_def ln_supp)+
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   210
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   211
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   212
lemma supp_lam_ln_aux: "supp (lam_ln_aux t l) \<subseteq> supp t"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   213
proof -
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   214
  have "eqvt lam_ln_aux" unfolding eqvt_def using eqvts_raw by simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   215
  then have "supp lam_ln_aux = {}" using supp_fun_eqvt by auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   216
  then have "supp (lam_ln_aux t) \<subseteq> supp t" using supp_fun_app by auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   217
  then have "supp (lam_ln_aux t l) \<subseteq> supp t \<union> supp l" using supp_fun_app by auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   218
  moreover have "\<forall>x \<in> supp l. x \<notin> supp (lam_ln_aux t l)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   219
    using l_fresh_lam_ln_aux unfolding fresh_star_def fresh_def
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   220
    by (metis finite_set supp_finite_set_at_base supp_set)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   221
  ultimately show "supp (lam_ln_aux t l) \<subseteq> supp t" by blast
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   222
qed
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   223
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   224
lemma lookup_flip: "x \<noteq> y \<Longrightarrow> y \<noteq> a \<Longrightarrow> lookup ((x \<leftrightarrow> a) \<bullet> xs) n y = lookup xs n y"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   225
  apply (induct xs arbitrary: n)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   226
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   227
  apply (simp only: Cons_eqvt)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   228
  apply (simp only: lookup.simps)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   229
  apply (subgoal_tac "y = (x \<leftrightarrow> a) \<bullet> aa \<longleftrightarrow> y = aa")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   230
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   231
  by (metis permute_flip_at)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   232
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   233
lemma lookup_append_flip: "x \<noteq> y \<Longrightarrow> lookup (l @ a # (x \<leftrightarrow> a) \<bullet> xs) n y = lookup (l @ a # xs) n y"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   234
  by (induct l arbitrary: n) (auto simp add: lookup_flip)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   235
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   236
lemma lam_ln_aux_flip: "atom x \<sharp> t \<Longrightarrow> lam_ln_aux t (l @ a # (x \<leftrightarrow> a) \<bullet> xs) = lam_ln_aux t (l @ a # xs)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   237
  apply (nominal_induct t avoiding: x a xs l rule: lam.strong_induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   238
  apply (simp_all add: lam_ln_aux.eqvt lam.fresh lookup_append_flip fresh_at_base)[2]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   239
  apply (simp add: lam.fresh fresh_at_base)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   240
  apply (subst lam_ln_aux.simps)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   241
  apply (simp add: fresh_Cons fresh_at_base fresh_append)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   242
  apply (metis atom_eqvt atom_name_def flip_at_base_simps(3) flip_commute fresh_permute_iff)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   243
  apply (subst lam_ln_aux.simps)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   244
  apply (simp add: fresh_Cons fresh_at_base fresh_append)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   245
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   246
  apply (drule_tac x="x" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   247
  apply (drule_tac x="a" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   248
  apply (drule_tac x="xs" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   249
  apply (drule_tac x="name # l" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   250
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   251
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   252
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   253
lemma lam_ln_aux4: "lam_ln_aux (Lam [x]. t) xs = LNLam (lam_ln_aux t (x # xs))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   254
  apply (rule_tac 'a="name" and x="(xs, x, t)" in obtain_fresh)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   255
  apply (simp add: fresh_Pair_elim)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   256
  apply (rule_tac t="Lam [x]. t" and s="Lam [a]. ((x \<leftrightarrow> a) \<bullet> t)" in subst)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   257
  apply (auto simp add: Abs1_eq_iff lam.fresh flip_def swap_commute)[1]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   258
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   259
  apply (rule_tac s="(x \<leftrightarrow> a) \<bullet> lam_ln_aux t (x # xs)" in trans)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   260
  apply (simp add: lam_ln_aux.eqvt)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   261
  apply (subst lam_ln_aux_flip[of _ _ "[]", simplified])
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   262
  apply (metis atom_eqvt flip_at_simps(2) fresh_permute_iff)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   263
  apply rule
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   264
  apply (rule flip_fresh_fresh)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   265
  apply (simp add: l_fresh_lam_ln_aux[of "x # xs", simplified fresh_star_def, simplified])
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   266
  apply (simp add: fresh_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   267
  apply (metis set_rev_mp supp_lam_ln_aux)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   268
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   269
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   270
lemma lookup_in: "n \<notin> set l \<Longrightarrow> lookup l i n = LNVar n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   271
  by (induct l arbitrary: i n) simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   272
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   273
lemma lookup_in2: "n \<in> set l \<Longrightarrow> \<exists>i. lookup l j n = LNBnd i"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   274
  by (induct l arbitrary: j n) auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   275
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   276
lemma lookup_in2': "lookup l j n = LNBnd i \<Longrightarrow> lookup l (Suc j) n = LNBnd (Suc i)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   277
  by (induct l arbitrary: j n) auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   278
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   279
lemma ln_lam_Var: "ln_lam_aux (lookup l (0\<Colon>nat) n) l = Var n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   280
  apply (cases "n \<in> set l")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   281
  apply (simp_all add: lookup_in)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   282
  apply (induct l arbitrary: n)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   283
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   284
  apply (case_tac "a = n")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   285
  apply (simp_all add: ln_lam_aux.simps(1)[of _ _ "Name 0"] )[2]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   286
  apply (drule_tac x="n" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   287
  apply (frule lookup_in2[of _ _ 0])
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   288
  apply (erule exE)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   289
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   290
  apply (frule lookup_in2')
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   291
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   292
  apply (simp_all add: ln_lam_aux.simps(1)[of _ _ "Name 0"] )
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   293
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   294
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   295
lemma ln_lam_ln_aux: "ln_lam_aux (lam_ln_aux t l) l = t"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   296
  apply (nominal_induct t avoiding: l rule: lam.strong_induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   297
  apply (simp_all add: ln_lam_Var)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   298
  apply (subst ln_lam_aux.simps(4)[of name])
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   299
  apply (simp add: fresh_Pair)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   300
  apply (subgoal_tac "atom ` set (name # l) \<sharp>* lam_ln_aux lam (name # l)")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   301
  apply (simp add: fresh_star_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   302
  apply (rule l_fresh_lam_ln_aux)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   303
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   304
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   305
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   306
fun subst_ln_nat where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   307
  "subst_ln_nat (LNBnd n) x _ = LNBnd n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   308
| "subst_ln_nat (LNVar v) x n = (if x = v then LNBnd n else LNVar v)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   309
| "subst_ln_nat (LNApp l r) x n = LNApp (subst_ln_nat l x n) (subst_ln_nat r x n)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   310
| "subst_ln_nat (LNLam l) x n = LNLam (subst_ln_nat l x (n + 1))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   311
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   312
lemma subst_ln_nat_eqvt[eqvt]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   313
  shows "(p \<bullet> subst_ln_nat t x n) = subst_ln_nat (p \<bullet> t) (p \<bullet> x) (p \<bullet> n)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   314
  by (induct t arbitrary: n) (simp_all add: permute_pure)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   315
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   316
lemma supp_subst_ln_nat:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   317
  "supp (subst_ln_nat t x n) = supp t - {atom x}"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   318
  by (induct t arbitrary: n) (auto simp add: permute_pure ln_supp pure_supp supp_at_base)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   319
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   320
lemma fresh_subst_ln_nat:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   321
  "atom y \<sharp> subst_ln_nat t x n \<longleftrightarrow> y = x \<or> atom y \<sharp> t"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   322
  unfolding fresh_def supp_subst_ln_nat by auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   323
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   324
nominal_primrec
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   325
  lam_ln_ex :: "lam \<Rightarrow> ln"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   326
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   327
  "lam_ln_ex (Var x) = LNVar x"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   328
| "lam_ln_ex (App t1 t2) = LNApp (lam_ln_ex t1) (lam_ln_ex t2)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   329
| "lam_ln_ex (Lam [x]. t) = LNLam (subst_ln_nat (lam_ln_ex t) x 0)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   330
  apply (simp add: eqvt_def lam_ln_ex_graph_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   331
  apply (rule, perm_simp, rule)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   332
  apply rule
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   333
  apply (rule_tac y="x" in lam.exhaust)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   334
  apply (auto simp add: fresh_star_def)[3]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   335
  apply(simp_all)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   336
  apply (erule_tac Abs_lst1_fcb)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   337
  apply (simp add: fresh_subst_ln_nat)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   338
  apply (simp add: fresh_subst_ln_nat)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   339
  apply (erule fresh_eqvt_at)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   340
  apply (simp add: finite_supp)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   341
  apply assumption
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   342
  apply(simp add: eqvt_at_def atom_eqvt fresh_star_Pair perm_supp_eq
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   343
    subst_ln_nat_eqvt permute_pure)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   344
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   345
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   346
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   347
termination (eqvt) by lexicographic_order
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   348
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   349
lemma lookup_in3: "lookup l j n = LNBnd i \<Longrightarrow> lookup (l @ l2) j n = LNBnd i"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   350
  by (induct l arbitrary: j n) auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   351
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   352
lemma lookup_in4: "n \<notin> set l \<Longrightarrow> lookup (l @ [n]) j n = LNBnd (length l + j)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   353
  by (induct l arbitrary: j n) auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   354
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   355
lemma subst_ln_nat_lam_ln_aux: "subst_ln_nat (lam_ln_aux l ns) n (List.length ns) = lam_ln_aux l (ns @ [n])"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   356
  apply (nominal_induct l avoiding: n ns rule: lam.strong_induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   357
  apply simp defer
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   358
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   359
  apply (simp add: fresh_Nil fresh_Cons fresh_append)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   360
  apply (drule_tac x="n" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   361
  apply (drule_tac x="name # ns" in meta_spec)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   362
  apply simp
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   363
  apply (case_tac "name \<in> set ns")
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   364
  apply (simp_all add: lookup_in)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   365
  apply (frule lookup_in2[of _ _ 0])
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   366
  apply (erule exE)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   367
  apply (simp add: lookup_in3)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   368
  apply (simp add: lookup_in4)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   369
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   370
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   371
lemma lam_ln_ex: "lam_ln_ex t = lam_ln t"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   372
  apply (induct t rule: lam.induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   373
  apply (simp_all add: lam_ln_def fresh_Nil)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   374
  by (metis (lifting) list.size(3) self_append_conv2 subst_ln_nat_lam_ln_aux)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   375
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   376
(* Lambda terms as a code-abstype *)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   377
lemma ln_abstype[code abstype]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   378
  "ln_lam (lam_ln_ex t) = t"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   379
  by (simp add: ln_lam_def lam_ln_ex lam_ln_def ln_lam_ln_aux)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   380
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   381
lemmas [code abstract] = lam_ln_ex.simps
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   382
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   383
(* Equality for lambda-terms *)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   384
instantiation lam :: equal begin
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   385
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   386
definition equal_lam_def: "equal_lam a b \<longleftrightarrow> lam_ln_ex a = lam_ln_ex b"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   387
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   388
instance
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   389
  by default
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   390
    (metis equal_lam_def lam_ln_def lam_ln_ex ln_lam_ln_aux)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   391
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   392
end
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   393
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   394
(* Execute permutations *)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   395
lemmas [code abstract] = lam_ln_ex.eqvt[symmetric]
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   396
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   397
fun subst_ln where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   398
  "subst_ln (LNBnd n) _ _ = LNBnd n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   399
| "subst_ln (LNVar v) x t = (if x = v then t else LNVar v)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   400
| "subst_ln (LNApp l r) x t = LNApp (subst_ln l x t) (subst_ln r x t)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   401
| "subst_ln (LNLam l) x t = LNLam (subst_ln l x t)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   402
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   403
lemma subst_ln_nat_id[simp]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   404
  "atom name \<sharp> s \<Longrightarrow> name \<noteq> y \<Longrightarrow> subst_ln_nat s name n = s"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   405
  by (induct s arbitrary: n) (simp_all add: ln_fresh fresh_at_base)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   406
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   407
lemma subst_ln_nat_subst_ln_commute:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   408
  assumes "name \<noteq> y" and "atom name \<sharp> s"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   409
  shows "subst_ln_nat (subst_ln ln y s) name n = subst_ln (subst_ln_nat ln name n) y s"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   410
  using assms by (induct ln arbitrary: n) auto
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   411
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   412
lemma supp_lam_ln_ex: "supp (lam_ln_ex t) = supp t"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   413
  by (induct t rule: lam.induct) (simp_all add: lam.supp ln_supp supp_subst_ln_nat)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   414
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   415
lemma subst_code[code abstract]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   416
  "lam_ln_ex (subst t y s) = subst_ln (lam_ln_ex t) y (lam_ln_ex s)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   417
  apply (nominal_induct t avoiding: y s rule: lam.strong_induct)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   418
  apply simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   419
  apply (subst subst_ln_nat_subst_ln_commute)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   420
  apply (simp_all add: fresh_at_base supp_lam_ln_ex fresh_def)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   421
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   422
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   423
(*definition "I0 \<equiv> Lam [N0]. (Var N0)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   424
definition "I1 \<equiv> Lam [N1]. (Var N1)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   425
definition "ppp = (atom N0 \<rightleftharpoons> atom N1)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   426
definition "pp \<equiv> ppp \<bullet> I1 = I0"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   427
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   428
export_code pp in SML*)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   429
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   430
lemma subst_ln_nat_funpow[simp]:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   431
  "subst_ln_nat ((LNLam^^p) l) x n = (LNLam ^^ p) (subst_ln_nat l x (n + p))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   432
  by (induct p arbitrary: n) simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   433
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   434
(*
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   435
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   436
Tests:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   437
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   438
fun Umn :: "nat \<Rightarrow> nat \<Rightarrow> lam"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   439
where
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   440
  "Umn 0 n = Lam [Name 0]. Var (Name n)"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   441
| "Umn (Suc m) n = Lam [Name (Suc m)]. Umn m n"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   442
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   443
lemma Umn_faster:
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   444
  "lam_ln_ex (Umn m n) = (LNLam ^^ (Suc m)) (if n \<le> m then LNBnd n else LNVar (Name n))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   445
  apply (induct m)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   446
  apply (auto simp add: Umn.simps)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   447
  apply (simp_all add: Name_def Abs_name_inject le_SucE)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   448
  apply (erule le_SucE)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   449
  apply simp_all
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   450
  done
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   451
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   452
definition "Bla = Umn 2 2"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   453
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   454
definition vara where "vara \<equiv> Lam [N0]. Lam [N1]. (App (Var N1) (App (Umn 2 2) (App (Var N0) (Var N1))))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   455
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   456
export_code ln_lam_aux nth_or_def ln_lam subst vara in SML
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   457
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   458
value "(atom N0 \<rightleftharpoons> atom N1) \<bullet> (App (Var N0) (Lam [N1]. (Var N1)))"
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   459
value "subst ((N0 \<leftrightarrow> N1) \<bullet> (App (Var N0) (Lam [N1]. (Var N1)))) N1 (Var N0)"*)
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   460
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   461
end
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   462
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   463
9876d73adb2b Executing Lambda Terms
Cezary Kaliszyk <cezarykaliszyk@gmail.com>
parents:
diff changeset
   464