Quot/Nominal/LamEx2.thy
changeset 1017 4239a0784e5f
parent 1011 1dd314a00b0c
child 1019 d7b8c4243cd6
equal deleted inserted replaced
1011:1dd314a00b0c 1017:4239a0784e5f
     1 theory LamEx
     1 theory LamEx
     2 imports Nominal "../QuotMain" "../QuotList"
     2 imports "Nominal2_Atoms" "Nominal2_Eqvt" "Nominal2_Supp" "../QuotMain" "Abs" "../QuotProd"
     3 begin
     3 begin
       
     4 
       
     5 
       
     6 (* lemmas that should be in Nominal \<dots>\<dots>must be cleaned *)
       
     7 lemma in_permute_iff:
       
     8   shows "(p \<bullet> x) \<in> (p \<bullet> X) \<longleftrightarrow> x \<in> X"
       
     9 apply(unfold mem_def permute_fun_def)[1]
       
    10 apply(simp add: permute_bool_def) 
       
    11 done
       
    12 
       
    13 lemma fresh_star_permute_iff:
       
    14   shows "(p \<bullet> a) \<sharp>* (p \<bullet> x) \<longleftrightarrow> a \<sharp>* x"
       
    15 apply(simp add: fresh_star_def)
       
    16 apply(auto)
       
    17 apply(drule_tac x="p \<bullet> xa" in bspec)
       
    18 apply(unfold mem_def permute_fun_def)[1] 
       
    19 apply(simp add: eqvts)
       
    20 apply(simp add: fresh_permute_iff)
       
    21 apply(rule_tac ?p1="- p" in fresh_permute_iff[THEN iffD1])
       
    22 apply(simp)
       
    23 apply(drule_tac x="- p \<bullet> xa" in bspec)
       
    24 apply(rule_tac ?p1="p" in in_permute_iff[THEN iffD1])
       
    25 apply(simp)
       
    26 apply(simp)
       
    27 done
       
    28 
       
    29 lemma fresh_plus:
       
    30   fixes p q::perm
       
    31   shows "\<lbrakk>a \<sharp> p;  a \<sharp> q\<rbrakk> \<Longrightarrow> a \<sharp> (p + q)"
       
    32 unfolding fresh_def
       
    33 using supp_plus_perm
       
    34 apply(auto)
       
    35 done
       
    36 
       
    37 lemma fresh_star_plus:
       
    38   fixes p q::perm
       
    39   shows "\<lbrakk>a \<sharp>* p;  a \<sharp>* q\<rbrakk> \<Longrightarrow> a \<sharp>* (p + q)"
       
    40 unfolding fresh_star_def
       
    41 by (simp add: fresh_plus)
       
    42 
       
    43 lemma supp_finite_set:
       
    44   fixes S::"atom set"
       
    45   assumes "finite S"
       
    46   shows "supp S = S"
       
    47   apply(rule finite_supp_unique)
       
    48   apply(simp add: supports_def)
       
    49   apply(auto simp add: permute_set_eq swap_atom)[1]
       
    50   apply(metis)
       
    51   apply(rule assms)
       
    52   apply(auto simp add: permute_set_eq swap_atom)[1]
       
    53 done
       
    54   
     4 
    55 
     5 atom_decl name
    56 atom_decl name
     6 
    57 
     7 datatype rlam =
    58 datatype rlam =
     8   rVar "name"
    59   rVar "name"
     9 | rApp "rlam" "rlam"
    60 | rApp "rlam" "rlam"
    10 | rLam "name" "rlam"
    61 | rLam "name" "rlam"
    11 
    62 
    12 fun
    63 fun
    13   rfv :: "rlam \<Rightarrow> name set"
    64   rfv :: "rlam \<Rightarrow> atom set"
    14 where
    65 where
    15   rfv_var: "rfv (rVar a) = {a}"
    66   rfv_var: "rfv (rVar a) = {atom a}"
    16 | rfv_app: "rfv (rApp t1 t2) = (rfv t1) \<union> (rfv t2)"
    67 | rfv_app: "rfv (rApp t1 t2) = (rfv t1) \<union> (rfv t2)"
    17 | rfv_lam: "rfv (rLam a t) = (rfv t) - {a}"
    68 | rfv_lam: "rfv (rLam a t) = (rfv t) - {atom a}"
    18 
    69 
    19 overloading
    70 instantiation rlam :: pt
    20   perm_rlam \<equiv> "perm :: 'x prm \<Rightarrow> rlam \<Rightarrow> rlam"   (unchecked)
       
    21 begin
    71 begin
    22 
    72 
    23 fun
    73 primrec
    24   perm_rlam
    74   permute_rlam
    25 where
    75 where
    26   "perm_rlam pi (rVar a) = rVar (pi \<bullet> a)"
    76   "permute_rlam pi (rVar a) = rVar (pi \<bullet> a)"
    27 | "perm_rlam pi (rApp t1 t2) = rApp (perm_rlam pi t1) (perm_rlam pi t2)"
    77 | "permute_rlam pi (rApp t1 t2) = rApp (permute_rlam pi t1) (permute_rlam pi t2)"
    28 | "perm_rlam pi (rLam a t) = rLam (pi \<bullet> a) (perm_rlam pi t)"
    78 | "permute_rlam pi (rLam a t) = rLam (pi \<bullet> a) (permute_rlam pi t)"
       
    79 
       
    80 instance
       
    81 apply default
       
    82 apply(induct_tac [!] x)
       
    83 apply(simp_all)
       
    84 done
    29 
    85 
    30 end
    86 end
    31 
    87 
    32 declare perm_rlam.simps[eqvt]
    88 instantiation rlam :: fs
    33 
    89 begin
    34 instance rlam::pt_name
    90 
    35   apply(default)
    91 lemma neg_conj:
    36   apply(induct_tac [!] x rule: rlam.induct)
    92   "\<not>(P \<and> Q) \<longleftrightarrow> (\<not>P) \<or> (\<not>Q)"
    37   apply(simp_all add: pt_name2 pt_name3)
    93   by simp
    38   done
    94 
    39 
    95 lemma infinite_Un:
    40 instance rlam::fs_name
    96   "infinite (S \<union> T) \<longleftrightarrow> infinite S \<or> infinite T"
    41   apply(default)
    97   by simp
    42   apply(induct_tac [!] x rule: rlam.induct)
    98 
    43   apply(simp add: supp_def)
    99 instance
    44   apply(fold supp_def)
   100 apply default
    45   apply(simp add: supp_atm)
   101 apply(induct_tac x)
    46   apply(simp add: supp_def Collect_imp_eq Collect_neg_eq)
   102 (* var case *)
    47   apply(simp add: supp_def)
   103 apply(simp add: supp_def)
    48   apply(simp add: supp_def Collect_imp_eq Collect_neg_eq[symmetric])
   104 apply(fold supp_def)[1]
    49   apply(fold supp_def)
   105 apply(simp add: supp_at_base)
    50   apply(simp add: supp_atm)
   106 (* app case *)
    51   done
   107 apply(simp only: supp_def)
    52 
   108 apply(simp only: permute_rlam.simps) 
    53 declare set_diff_eqvt[eqvt]
   109 apply(simp only: rlam.inject) 
       
   110 apply(simp only: neg_conj)
       
   111 apply(simp only: Collect_disj_eq)
       
   112 apply(simp only: infinite_Un)
       
   113 apply(simp only: Collect_disj_eq)
       
   114 apply(simp)
       
   115 (* lam case *)
       
   116 apply(simp only: supp_def)
       
   117 apply(simp only: permute_rlam.simps) 
       
   118 apply(simp only: rlam.inject) 
       
   119 apply(simp only: neg_conj)
       
   120 apply(simp only: Collect_disj_eq)
       
   121 apply(simp only: infinite_Un)
       
   122 apply(simp only: Collect_disj_eq)
       
   123 apply(simp)
       
   124 apply(fold supp_def)[1]
       
   125 apply(simp add: supp_at_base)
       
   126 done
       
   127 
       
   128 end
       
   129 
       
   130 
       
   131 (* for the eqvt proof of the alpha-equivalence *)
       
   132 declare permute_rlam.simps[eqvt]
    54 
   133 
    55 lemma rfv_eqvt[eqvt]:
   134 lemma rfv_eqvt[eqvt]:
    56   fixes pi::"name prm"
       
    57   shows "(pi\<bullet>rfv t) = rfv (pi\<bullet>t)"
   135   shows "(pi\<bullet>rfv t) = rfv (pi\<bullet>t)"
    58 apply(induct t)
   136 apply(induct t)
    59 apply(simp_all)
   137 apply(simp_all)
    60 apply(simp add: perm_set_eq)
   138 apply(simp add: permute_set_eq atom_eqvt)
    61 apply(simp add: union_eqvt)
   139 apply(simp add: union_eqvt)
    62 apply(simp add: set_diff_eqvt)
   140 apply(simp add: Diff_eqvt)
    63 apply(simp add: perm_set_eq)
   141 apply(simp add: permute_set_eq atom_eqvt)
    64 done
   142 done
    65 
   143 
    66 inductive
   144 inductive
    67     alpha :: "rlam \<Rightarrow> rlam \<Rightarrow> bool" ("_ \<approx> _" [100, 100] 100)
   145     alpha :: "rlam \<Rightarrow> rlam \<Rightarrow> bool" ("_ \<approx> _" [100, 100] 100)
    68 where
   146 where
    69   a1: "a = b \<Longrightarrow> (rVar a) \<approx> (rVar b)"
   147   a1: "a = b \<Longrightarrow> (rVar a) \<approx> (rVar b)"
    70 | a2: "\<lbrakk>t1 \<approx> t2; s1 \<approx> s2\<rbrakk> \<Longrightarrow> rApp t1 s1 \<approx> rApp t2 s2"
   148 | a2: "\<lbrakk>t1 \<approx> t2; s1 \<approx> s2\<rbrakk> \<Longrightarrow> rApp t1 s1 \<approx> rApp t2 s2"
    71 | a3: "\<exists>pi::name prm. (rfv t - {a} = rfv s - {b} \<and> (rfv t - {a})\<sharp>* pi \<and> (pi \<bullet> t) \<approx> s \<and> (pi \<bullet> a) = b)
   149 | a3: "\<exists>pi. (({atom a}, t) \<approx>gen alpha rfv pi ({atom b}, s)) \<Longrightarrow> rLam a t \<approx> rLam b s"
    72        \<Longrightarrow> rLam a t \<approx> rLam b s"
   150 
    73 
   151 thm alpha.induct
    74 
   152 
    75 
   153 lemma a3_inverse:
    76 
   154   assumes "rLam a t \<approx> rLam b s"
    77 (* should be automatic with new version of eqvt-machinery *)
   155   shows "\<exists>pi. (({atom a}, t) \<approx>gen alpha rfv pi ({atom b}, s))"
       
   156 using assms
       
   157 apply(erule_tac alpha.cases)
       
   158 apply(auto)
       
   159 done
       
   160 
       
   161 text {* should be automatic with new version of eqvt-machinery *}
    78 lemma alpha_eqvt:
   162 lemma alpha_eqvt:
    79   fixes pi::"name prm"
       
    80   shows "t \<approx> s \<Longrightarrow> (pi \<bullet> t) \<approx> (pi \<bullet> s)"
   163   shows "t \<approx> s \<Longrightarrow> (pi \<bullet> t) \<approx> (pi \<bullet> s)"
    81 apply(induct rule: alpha.induct)
   164 apply(induct rule: alpha.induct)
    82 apply(simp add: a1)
   165 apply(simp add: a1)
    83 apply(simp add: a2)
   166 apply(simp add: a2)
    84 apply(simp)
   167 apply(simp)
    85 apply(rule a3)
   168 apply(rule a3)
    86 apply(erule conjE)
       
    87 apply(erule exE)
   169 apply(erule exE)
    88 apply(erule conjE)
       
    89 apply(rule_tac x="pi \<bullet> pia" in exI)
   170 apply(rule_tac x="pi \<bullet> pia" in exI)
       
   171 apply(simp add: alpha_gen.simps)
       
   172 apply(erule conjE)+
       
   173 apply(rule conjI)+
       
   174 apply(rule_tac ?p1="- pi" in permute_eq_iff[THEN iffD1])
       
   175 apply(simp add: eqvts atom_eqvt)
    90 apply(rule conjI)
   176 apply(rule conjI)
    91 apply(rule_tac pi1="rev pi" in perm_bij[THEN iffD1])
   177 apply(rule_tac ?p1="- pi" in fresh_star_permute_iff[THEN iffD1])
    92 apply(perm_simp add: eqvts)
   178 apply(simp add: eqvts atom_eqvt)
    93 apply(rule conjI)
   179 apply(subst permute_eqvt[symmetric])
    94 apply(rule_tac pi1="rev pi" in pt_fresh_star_bij(1)[OF pt_name_inst at_name_inst, THEN iffD1])
       
    95 apply(perm_simp add: eqvts)
       
    96 apply(rule conjI)
       
    97 apply(subst perm_compose[symmetric])
       
    98 apply(simp)
       
    99 apply(subst perm_compose[symmetric])
       
   100 apply(simp)
   180 apply(simp)
   101 done
   181 done
   102 
   182 
   103 lemma alpha_refl:
   183 lemma alpha_refl:
   104   shows "t \<approx> t"
   184   shows "t \<approx> t"
   105 apply(induct t rule: rlam.induct)
   185 apply(induct t rule: rlam.induct)
   106 apply(simp add: a1)
   186 apply(simp add: a1)
   107 apply(simp add: a2)
   187 apply(simp add: a2)
   108 apply(rule a3)
   188 apply(rule a3)
   109 apply(rule_tac x="[]" in exI)
   189 apply(rule_tac x="0" in exI)
   110 apply(simp_all add: fresh_star_def fresh_list_nil)
   190 apply(rule alpha_gen_refl)
   111 done
   191 apply(assumption)
       
   192 done
       
   193 
       
   194 lemma fresh_minus_perm:
       
   195   fixes p::perm
       
   196   shows "a \<sharp> (- p) \<longleftrightarrow> a \<sharp> p"
       
   197   apply(simp add: fresh_def)
       
   198   apply(simp only: supp_minus_perm)
       
   199   done
       
   200 
       
   201 lemma alpha_gen_atom_sym:
       
   202   assumes a: "\<And>pi t s. (R t s \<Longrightarrow> R (pi \<bullet> t) (pi \<bullet> s))"
       
   203   shows "\<exists>pi. ({atom a}, t) \<approx>gen \<lambda>x1 x2. R x1 x2 \<and> R x2 x1 f pi ({atom b}, s) \<Longrightarrow>
       
   204        \<exists>pi. ({atom b}, s) \<approx>gen R f pi ({atom a}, t)"
       
   205   apply(erule exE)
       
   206   apply(rule_tac x="- pi" in exI)
       
   207   apply(simp add: alpha_gen.simps)
       
   208   apply(erule conjE)+
       
   209   apply(rule conjI)
       
   210   apply(simp add: fresh_star_def fresh_minus_perm)
       
   211   apply(subgoal_tac "R (- pi \<bullet> s) ((- pi) \<bullet> (pi \<bullet> t))")
       
   212   apply simp
       
   213   apply(rule a)
       
   214   apply assumption
       
   215   done
   112 
   216 
   113 lemma alpha_sym:
   217 lemma alpha_sym:
   114   shows "t \<approx> s \<Longrightarrow> s \<approx> t"
   218   shows "t \<approx> s \<Longrightarrow> s \<approx> t"
   115 apply(induct rule: alpha.induct)
   219   apply(induct rule: alpha.induct)
   116 apply(simp add: a1)
   220   apply(simp add: a1)
   117 apply(simp add: a2)
   221   apply(simp add: a2)
   118 apply(rule a3)
   222   apply(rule a3)
   119 apply(erule exE)
   223   apply(rule alpha_gen_atom_sym)
   120 apply(rule_tac x="rev pi" in exI)
   224   apply(rule alpha_eqvt)
   121 apply(simp)
   225   apply(assumption)+
   122 apply(simp add: fresh_star_def fresh_list_rev)
   226   done
   123 apply(rule conjI)
       
   124 apply(erule conjE)+
       
   125 apply(rotate_tac 3)
       
   126 apply(drule_tac pi="rev pi" in alpha_eqvt)
       
   127 apply(perm_simp)
       
   128 apply(rule pt_bij2[OF pt_name_inst at_name_inst])
       
   129 apply(simp)
       
   130 done
       
   131 
   227 
   132 lemma alpha_trans:
   228 lemma alpha_trans:
   133   shows "t1 \<approx> t2 \<Longrightarrow> t2 \<approx> t3 \<Longrightarrow> t1 \<approx> t3"
   229   shows "t1 \<approx> t2 \<Longrightarrow> t2 \<approx> t3 \<Longrightarrow> t1 \<approx> t3"
   134 apply(induct arbitrary: t3 rule: alpha.induct)
   230 apply(induct arbitrary: t3 rule: alpha.induct)
   135 apply(erule alpha.cases)
   231 apply(erule alpha.cases)
   140 apply(simp_all)
   236 apply(simp_all)
   141 apply(simp add: a2)
   237 apply(simp add: a2)
   142 apply(rotate_tac 1)
   238 apply(rotate_tac 1)
   143 apply(erule alpha.cases)
   239 apply(erule alpha.cases)
   144 apply(simp_all)
   240 apply(simp_all)
       
   241 apply(simp add: alpha_gen.simps)
   145 apply(erule conjE)+
   242 apply(erule conjE)+
   146 apply(erule exE)+
   243 apply(erule exE)+
   147 apply(erule conjE)+
   244 apply(erule conjE)+
   148 apply(rule a3)
   245 apply(rule a3)
   149 apply(rule_tac x="pia @ pi" in exI)
   246 apply(rule_tac x="pia + pi" in exI)
   150 apply(simp add: fresh_star_def fresh_list_append)
   247 apply(simp add: alpha_gen.simps)
   151 apply(simp add: pt_name2)
   248 apply(simp add: fresh_star_plus)
   152 apply(drule_tac x="rev pia \<bullet> sa" in spec)
   249 apply(drule_tac x="- pia \<bullet> sa" in spec)
   153 apply(drule mp)
   250 apply(drule mp)
   154 apply(rotate_tac 8)
   251 apply(rotate_tac 7)
   155 apply(drule_tac pi="rev pia" in alpha_eqvt)
   252 apply(drule_tac pi="- pia" in alpha_eqvt)
   156 apply(perm_simp)
   253 apply(simp)
   157 apply(rotate_tac 11)
   254 apply(rotate_tac 9)
   158 apply(drule_tac pi="pia" in alpha_eqvt)
   255 apply(drule_tac pi="pia" in alpha_eqvt)
   159 apply(perm_simp)
   256 apply(simp)
   160 done
   257 done
   161 
   258 
   162 lemma alpha_equivp:
   259 lemma alpha_equivp:
   163   shows "equivp alpha"
   260   shows "equivp alpha"
   164 apply(rule equivpI)
   261   apply(rule equivpI)
   165 unfolding reflp_def symp_def transp_def
   262   unfolding reflp_def symp_def transp_def
   166 apply(auto intro: alpha_refl alpha_sym alpha_trans)
   263   apply(auto intro: alpha_refl alpha_sym alpha_trans)
   167 done
   264   done
   168 
   265 
   169 lemma alpha_rfv:
   266 lemma alpha_rfv:
   170   shows "t \<approx> s \<Longrightarrow> rfv t = rfv s"
   267   shows "t \<approx> s \<Longrightarrow> rfv t = rfv s"
   171 apply(induct rule: alpha.induct)
   268   apply(induct rule: alpha.induct)
   172 apply(simp)
   269   apply(simp_all add: alpha_gen.simps)
   173 apply(simp)
   270   done
   174 apply(simp)
       
   175 done
       
   176 
   271 
   177 quotient_type lam = rlam / alpha
   272 quotient_type lam = rlam / alpha
   178   by (rule alpha_equivp)
   273   by (rule alpha_equivp)
   179 
       
   180 
   274 
   181 quotient_definition
   275 quotient_definition
   182   "Var :: name \<Rightarrow> lam"
   276   "Var :: name \<Rightarrow> lam"
   183 as
   277 as
   184   "rVar"
   278   "rVar"
   192   "Lam :: name \<Rightarrow> lam \<Rightarrow> lam"
   286   "Lam :: name \<Rightarrow> lam \<Rightarrow> lam"
   193 as
   287 as
   194   "rLam"
   288   "rLam"
   195 
   289 
   196 quotient_definition
   290 quotient_definition
   197   "fv :: lam \<Rightarrow> name set"
   291   "fv :: lam \<Rightarrow> atom set"
   198 as
   292 as
   199   "rfv"
   293   "rfv"
   200 
   294 
   201 (* definition of overloaded permutation function *)
       
   202 (* for the lifted type lam                       *)
       
   203 overloading
       
   204   perm_lam \<equiv> "perm :: 'x prm \<Rightarrow> lam \<Rightarrow> lam"   (unchecked)
       
   205 begin
       
   206 
       
   207 quotient_definition
       
   208   "perm_lam :: 'x prm \<Rightarrow> lam \<Rightarrow> lam"
       
   209 as
       
   210   "perm::'x prm \<Rightarrow> rlam \<Rightarrow> rlam"
       
   211 
       
   212 end
       
   213 
       
   214 lemma perm_rsp[quot_respect]:
   295 lemma perm_rsp[quot_respect]:
   215   "(op = ===> alpha ===> alpha) op \<bullet> op \<bullet>"
   296   "(op = ===> alpha ===> alpha) permute permute"
   216   apply(auto)
   297   apply(auto)
   217   (* this is propably true if some type conditions are imposed ;o) *)
   298   apply(rule alpha_eqvt)
   218   sorry
   299   apply(simp)
   219 
   300   done
   220 lemma fresh_rsp:
       
   221   "(op = ===> alpha ===> op =) fresh fresh"
       
   222   apply(auto)
       
   223   (* this is probably only true if some type conditions are imposed *)
       
   224   sorry
       
   225 
   301 
   226 lemma rVar_rsp[quot_respect]:
   302 lemma rVar_rsp[quot_respect]:
   227   "(op = ===> alpha) rVar rVar"
   303   "(op = ===> alpha) rVar rVar"
   228   by (auto intro: a1)
   304   by (auto intro: a1)
   229 
   305 
   230 lemma rApp_rsp[quot_respect]: "(alpha ===> alpha ===> alpha) rApp rApp"
   306 lemma rApp_rsp[quot_respect]: 
       
   307   "(alpha ===> alpha ===> alpha) rApp rApp"
   231   by (auto intro: a2)
   308   by (auto intro: a2)
   232 
   309 
   233 lemma rLam_rsp[quot_respect]: "(op = ===> alpha ===> alpha) rLam rLam"
   310 lemma rLam_rsp[quot_respect]: 
       
   311   "(op = ===> alpha ===> alpha) rLam rLam"
   234   apply(auto)
   312   apply(auto)
   235   apply(rule a3)
   313   apply(rule a3)
   236   apply(rule_tac x="[]" in exI)
   314   apply(rule_tac x="0" in exI)
   237   unfolding fresh_star_def
   315   unfolding fresh_star_def 
   238   apply(simp add: fresh_list_nil)
   316   apply(simp add: fresh_star_def fresh_zero_perm alpha_gen.simps)
   239   apply(simp add: alpha_rfv)
   317   apply(simp add: alpha_rfv)
   240   done
   318   done
   241 
   319 
   242 lemma rfv_rsp[quot_respect]: 
   320 lemma rfv_rsp[quot_respect]: 
   243   "(alpha ===> op =) rfv rfv"
   321   "(alpha ===> op =) rfv rfv"
   244 apply(simp add: alpha_rfv)
   322 apply(simp add: alpha_rfv)
   245 done
   323 done
       
   324 
   246 
   325 
   247 section {* lifted theorems *}
   326 section {* lifted theorems *}
   248 
   327 
   249 lemma lam_induct:
   328 lemma lam_induct:
   250   "\<lbrakk>\<And>name. P (Var name);
   329   "\<lbrakk>\<And>name. P (Var name);
   251     \<And>lam1 lam2. \<lbrakk>P lam1; P lam2\<rbrakk> \<Longrightarrow> P (App lam1 lam2);
   330     \<And>lam1 lam2. \<lbrakk>P lam1; P lam2\<rbrakk> \<Longrightarrow> P (App lam1 lam2);
   252     \<And>name lam. P lam \<Longrightarrow> P (Lam name lam)\<rbrakk> 
   331     \<And>name lam. P lam \<Longrightarrow> P (Lam name lam)\<rbrakk> 
   253     \<Longrightarrow> P lam"
   332     \<Longrightarrow> P lam"
   254   by (lifting rlam.induct)
   333   apply (lifting rlam.induct)
   255 
   334   done
   256 lemma perm_lam [simp]:
   335 
   257   fixes pi::"'a prm"
   336 instantiation lam :: pt
       
   337 begin
       
   338 
       
   339 quotient_definition
       
   340   "permute_lam :: perm \<Rightarrow> lam \<Rightarrow> lam"
       
   341 as
       
   342   "permute :: perm \<Rightarrow> rlam \<Rightarrow> rlam"
       
   343 
       
   344 lemma permute_lam [simp]:
   258   shows "pi \<bullet> Var a = Var (pi \<bullet> a)"
   345   shows "pi \<bullet> Var a = Var (pi \<bullet> a)"
   259   and   "pi \<bullet> App t1 t2 = App (pi \<bullet> t1) (pi \<bullet> t2)"
   346   and   "pi \<bullet> App t1 t2 = App (pi \<bullet> t1) (pi \<bullet> t2)"
   260   and   "pi \<bullet> Lam a t = Lam (pi \<bullet> a) (pi \<bullet> t)"
   347   and   "pi \<bullet> Lam a t = Lam (pi \<bullet> a) (pi \<bullet> t)"
   261 apply(lifting perm_rlam.simps)
   348 apply(lifting permute_rlam.simps)
   262 done
   349 done
   263 
   350 
   264 instance lam::pt_name
   351 instance
   265 apply(default)
   352 apply default
   266 apply(induct_tac [!] x rule: lam_induct)
   353 apply(induct_tac [!] x rule: lam_induct)
   267 apply(simp_all add: pt_name2 pt_name3)
   354 apply(simp_all)
   268 done
   355 done
       
   356 
       
   357 end
   269 
   358 
   270 lemma fv_lam [simp]: 
   359 lemma fv_lam [simp]: 
   271   shows "fv (Var a) = {a}"
   360   shows "fv (Var a) = {atom a}"
   272   and   "fv (App t1 t2) = fv t1 \<union> fv t2"
   361   and   "fv (App t1 t2) = fv t1 \<union> fv t2"
   273   and   "fv (Lam a t) = fv t - {a}"
   362   and   "fv (Lam a t) = fv t - {atom a}"
   274 apply(lifting rfv_var rfv_app rfv_lam)
   363 apply(lifting rfv_var rfv_app rfv_lam)
   275 done
   364 done
   276 
   365 
       
   366 lemma fv_eqvt:
       
   367   shows "(p \<bullet> fv t) = fv (p \<bullet> t)"
       
   368 apply(lifting rfv_eqvt)
       
   369 done
   277 
   370 
   278 lemma a1: 
   371 lemma a1: 
   279   "a = b \<Longrightarrow> Var a = Var b"
   372   "a = b \<Longrightarrow> Var a = Var b"
   280   by  (lifting a1)
   373   by  (lifting a1)
   281 
   374 
   282 lemma a2: 
   375 lemma a2: 
   283   "\<lbrakk>x = xa; xb = xc\<rbrakk> \<Longrightarrow> App x xb = App xa xc"
   376   "\<lbrakk>x = xa; xb = xc\<rbrakk> \<Longrightarrow> App x xb = App xa xc"
   284   by  (lifting a2)
   377   by  (lifting a2)
   285 
   378 
   286 lemma a3: 
   379 lemma alpha_gen_rsp_pre:
   287   "\<lbrakk>\<exists>pi::name prm. (fv t - {a} = fv s - {b} \<and> (fv t - {a})\<sharp>* pi \<and> (pi \<bullet> t) = s \<and> (pi \<bullet> a) = b)\<rbrakk> 
   380   assumes a5: "\<And>t s. R t s \<Longrightarrow> R (pi \<bullet> t) (pi \<bullet> s)"
   288    \<Longrightarrow> Lam a t = Lam b s"
   381   and     a1: "R s1 t1"
   289   by  (lifting a3)
   382   and     a2: "R s2 t2"
       
   383   and     a3: "\<And>a b c d. R a b \<Longrightarrow> R c d \<Longrightarrow> R1 a c = R2 b d"
       
   384   and     a4: "\<And>x y. R x y \<Longrightarrow> fv1 x = fv2 y"
       
   385   shows   "(a, s1) \<approx>gen R1 fv1 pi (b, s2) = (a, t1) \<approx>gen R2 fv2 pi (b, t2)"
       
   386 apply (simp add: alpha_gen.simps)
       
   387 apply (simp only: a4[symmetric, OF a1] a4[symmetric, OF a2])
       
   388 apply auto
       
   389 apply (subst a3[symmetric])
       
   390 apply (rule a5)
       
   391 apply (rule a1)
       
   392 apply (rule a2)
       
   393 apply (assumption)
       
   394 apply (subst a3)
       
   395 apply (rule a5)
       
   396 apply (rule a1)
       
   397 apply (rule a2)
       
   398 apply (assumption)
       
   399 done
       
   400 
       
   401 lemma [quot_respect]: "(prod_rel op = alpha ===>
       
   402            (alpha ===> alpha ===> op =) ===> (alpha ===> op =) ===> op = ===> prod_rel op = alpha ===> op =)
       
   403            alpha_gen alpha_gen"
       
   404 apply simp
       
   405 apply clarify
       
   406 apply (rule alpha_gen_rsp_pre[of "alpha",OF alpha_eqvt])
       
   407 apply auto
       
   408 done
       
   409 
       
   410 lemma pi_rep: "pi \<bullet> (rep_lam x) = rep_lam (pi \<bullet> x)"
       
   411 apply (unfold rep_lam_def)
       
   412 sorry
       
   413 
       
   414 lemma [quot_preserve]: "(prod_fun id rep_lam --->
       
   415            (abs_lam ---> abs_lam ---> id) ---> (abs_lam ---> id) ---> id ---> (prod_fun id rep_lam) ---> id)
       
   416            alpha_gen = alpha_gen"
       
   417 apply (simp add: expand_fun_eq)
       
   418 apply (simp add: alpha_gen.simps)
       
   419 apply (simp add: pi_rep)
       
   420 apply (simp only: Quotient_abs_rep[OF Quotient_lam])
       
   421 apply auto
       
   422 done
       
   423 
       
   424 lemma alpha_prs [quot_preserve]: "(rep_lam ---> rep_lam ---> id) alpha = (op =)"
       
   425 apply (simp add: expand_fun_eq)
       
   426 sorry
       
   427 
       
   428 
       
   429 lemma a3:
       
   430   "\<exists>pi. ({atom a}, t) \<approx>gen (op =) fv pi ({atom b}, s) \<Longrightarrow> Lam a t = Lam b s"
       
   431   apply (lifting a3)
       
   432   done
       
   433 
       
   434 lemma a3_inv:
       
   435   assumes "Lam a t = Lam b s"
       
   436   shows "\<exists>pi. (fv t - {atom a} = fv s - {atom b} \<and> (fv t - {atom a})\<sharp>* pi \<and> (pi \<bullet> t) = s)"
       
   437 using assms
       
   438 apply(lifting a3_inverse)
       
   439 done
   290 
   440 
   291 lemma alpha_cases: 
   441 lemma alpha_cases: 
   292   "\<lbrakk>a1 = a2; \<And>a b. \<lbrakk>a1 = Var a; a2 = Var b; a = b\<rbrakk> \<Longrightarrow> P;
   442   "\<lbrakk>a1 = a2; \<And>a b. \<lbrakk>a1 = Var a; a2 = Var b; a = b\<rbrakk> \<Longrightarrow> P;
   293     \<And>x xa xb xc. \<lbrakk>a1 = App x xb; a2 = App xa xc; x = xa; xb = xc\<rbrakk> \<Longrightarrow> P;
   443     \<And>x xa xb xc. \<lbrakk>a1 = App x xb; a2 = App xa xc; x = xa; xb = xc\<rbrakk> \<Longrightarrow> P;
   294     \<And>t a s b. \<lbrakk>a1 = Lam a t; a2 = Lam b s; 
   444     \<And>t a s b. \<lbrakk>a1 = Lam a t; a2 = Lam b s; 
   295          \<exists>pi::name prm. fv t - {a} = fv s - {b} \<and> (fv t - {a}) \<sharp>* pi \<and> (pi \<bullet> t) = s \<and> pi \<bullet> a = b\<rbrakk> \<Longrightarrow> P\<rbrakk>
   445          \<exists>pi. fv t - {atom a} = fv s - {atom b} \<and> (fv t - {atom a}) \<sharp>* pi \<and> (pi \<bullet> t) = s\<rbrakk> 
       
   446    \<Longrightarrow> P\<rbrakk>
   296     \<Longrightarrow> P"
   447     \<Longrightarrow> P"
   297   by (lifting alpha.cases)
   448   by (lifting alpha.cases)
   298 
   449 
       
   450 (* not sure whether needed *)
   299 lemma alpha_induct: 
   451 lemma alpha_induct: 
   300   "\<lbrakk>qx = qxa; \<And>a b. a = b \<Longrightarrow> qxb (Var a) (Var b);
   452   "\<lbrakk>qx = qxa; \<And>a b. a = b \<Longrightarrow> qxb (Var a) (Var b);
   301     \<And>x xa xb xc. \<lbrakk>x = xa; qxb x xa; xb = xc; qxb xb xc\<rbrakk> \<Longrightarrow> qxb (App x xb) (App xa xc);
   453     \<And>x xa xb xc. \<lbrakk>x = xa; qxb x xa; xb = xc; qxb xb xc\<rbrakk> \<Longrightarrow> qxb (App x xb) (App xa xc);
   302      \<And>t a s b.
   454      \<And>t a s b.
   303         \<lbrakk>\<exists>pi::name prm. fv t - {a} = fv s - {b} \<and>
   455         \<lbrakk>\<exists>pi. fv t - {atom a} = fv s - {atom b} \<and>
   304          (fv t - {a}) \<sharp>* pi \<and> ((pi \<bullet> t) = s \<and> qxb (pi \<bullet> t) s) \<and> pi \<bullet> a = b\<rbrakk> \<Longrightarrow> qxb (Lam a t) (Lam b s)\<rbrakk>
   456          (fv t - {atom a}) \<sharp>* pi \<and> ((pi \<bullet> t) = s \<and> qxb (pi \<bullet> t) s)\<rbrakk> 
       
   457      \<Longrightarrow> qxb (Lam a t) (Lam b s)\<rbrakk>
   305     \<Longrightarrow> qxb qx qxa"
   458     \<Longrightarrow> qxb qx qxa"
   306   by (lifting alpha.induct)
   459   by (lifting alpha.induct)
   307 
   460 
       
   461 (* should they lift automatically *)
   308 lemma lam_inject [simp]: 
   462 lemma lam_inject [simp]: 
   309   shows "(Var a = Var b) = (a = b)"
   463   shows "(Var a = Var b) = (a = b)"
   310   and   "(App t1 t2 = App s1 s2) = (t1 = s1 \<and> t2 = s2)"
   464   and   "(App t1 t2 = App s1 s2) = (t1 = s1 \<and> t2 = s2)"
   311 apply(lifting rlam.inject(1) rlam.inject(2))
   465 apply(lifting rlam.inject(1) rlam.inject(2))
       
   466 apply(regularize)
       
   467 prefer 2
       
   468 apply(regularize)
       
   469 prefer 2
   312 apply(auto)
   470 apply(auto)
   313 apply(drule alpha.cases)
   471 apply(drule alpha.cases)
   314 apply(simp_all)
   472 apply(simp_all)
   315 apply(simp add: alpha.a1)
   473 apply(simp add: alpha.a1)
   316 apply(drule alpha.cases)
   474 apply(drule alpha.cases)
   317 apply(simp_all)
   475 apply(simp_all)
   318 apply(drule alpha.cases)
   476 apply(drule alpha.cases)
   319 apply(simp_all)
   477 apply(simp_all)
   320 apply(rule alpha.a2)
   478 apply(rule alpha.a2)
   321 apply(simp_all)
   479 apply(simp_all)
       
   480 done
       
   481 
       
   482 lemma Lam_pseudo_inject:
       
   483   shows "(Lam a t = Lam b s) = 
       
   484       (\<exists>pi. (fv t - {atom a} = fv s - {atom b} \<and> (fv t - {atom a})\<sharp>* pi \<and> (pi \<bullet> t) = s))"
       
   485 apply(rule iffI)
       
   486 apply(rule a3_inv)
       
   487 apply(assumption)
       
   488 apply(rule a3)
       
   489 apply(assumption)
   322 done
   490 done
   323 
   491 
   324 lemma rlam_distinct:
   492 lemma rlam_distinct:
   325   shows "\<not>(rVar nam \<approx> rApp rlam1' rlam2')"
   493   shows "\<not>(rVar nam \<approx> rApp rlam1' rlam2')"
   326   and   "\<not>(rApp rlam1' rlam2' \<approx> rVar nam)"
   494   and   "\<not>(rApp rlam1' rlam2' \<approx> rVar nam)"
   327   and   "\<not>(rVar nam \<approx> rLam nam' rlam')"
   495   and   "\<not>(rVar nam \<approx> rLam nam' rlam')"
   328   and   "\<not>(rLam nam' rlam' \<approx> rVar nam)"
   496   and   "\<not>(rLam nam' rlam' \<approx> rVar nam)"
   329   and   "\<not>(rApp rlam1 rlam2 \<approx> rLam nam' rlam')"
   497   and   "\<not>(rApp rlam1 rlam2 \<approx> rLam nam' rlam')"
   330   and   "\<not>(rLam nam' rlam' \<approx> rApp rlam1 rlam2)"
   498   and   "\<not>(rLam nam' rlam' \<approx> rApp rlam1 rlam2)"
   331 apply auto
   499 apply auto
   332 apply(erule alpha.cases)
   500 apply (erule alpha.cases)
   333 apply simp_all
   501 apply (simp_all only: rlam.distinct)
   334 apply(erule alpha.cases)
   502 apply (erule alpha.cases)
   335 apply simp_all
   503 apply (simp_all only: rlam.distinct)
   336 apply(erule alpha.cases)
   504 apply (erule alpha.cases)
   337 apply simp_all
   505 apply (simp_all only: rlam.distinct)
   338 apply(erule alpha.cases)
   506 apply (erule alpha.cases)
   339 apply simp_all
   507 apply (simp_all only: rlam.distinct)
   340 apply(erule alpha.cases)
   508 apply (erule alpha.cases)
   341 apply simp_all
   509 apply (simp_all only: rlam.distinct)
   342 apply(erule alpha.cases)
   510 apply (erule alpha.cases)
   343 apply simp_all
   511 apply (simp_all only: rlam.distinct)
   344 done
   512 done
   345 
   513 
   346 lemma lam_distinct[simp]:
   514 lemma lam_distinct[simp]:
   347   shows "Var nam \<noteq> App lam1' lam2'"
   515   shows "Var nam \<noteq> App lam1' lam2'"
   348   and   "App lam1' lam2' \<noteq> Var nam"
   516   and   "App lam1' lam2' \<noteq> Var nam"
   352   and   "Lam nam' lam' \<noteq> App lam1 lam2"
   520   and   "Lam nam' lam' \<noteq> App lam1 lam2"
   353 apply(lifting rlam_distinct(1) rlam_distinct(2) rlam_distinct(3) rlam_distinct(4) rlam_distinct(5) rlam_distinct(6))
   521 apply(lifting rlam_distinct(1) rlam_distinct(2) rlam_distinct(3) rlam_distinct(4) rlam_distinct(5) rlam_distinct(6))
   354 done
   522 done
   355 
   523 
   356 lemma var_supp1:
   524 lemma var_supp1:
   357   shows "(supp (Var a)) = ((supp a)::name set)"
   525   shows "(supp (Var a)) = (supp a)"
   358   by (simp add: supp_def)
   526   apply (simp add: supp_def)
       
   527   done
   359 
   528 
   360 lemma var_supp:
   529 lemma var_supp:
   361   shows "(supp (Var a)) = {a::name}"
   530   shows "(supp (Var a)) = {a:::name}"
   362   using var_supp1 by (simp add: supp_atm)
   531   using var_supp1 by (simp add: supp_at_base)
   363 
   532 
   364 lemma app_supp:
   533 lemma app_supp:
   365   shows "supp (App t1 t2) = (supp t1) \<union> ((supp t2)::name set)"
   534   shows "supp (App t1 t2) = (supp t1) \<union> (supp t2)"
   366 apply(simp only: perm_lam supp_def lam_inject)
   535 apply(simp only: supp_def lam_inject)
   367 apply(simp add: Collect_imp_eq Collect_neg_eq)
   536 apply(simp add: Collect_imp_eq Collect_neg_eq)
   368 done
   537 done
   369 
   538 
   370 lemma lam_supp:
   539 (* supp for lam *)
   371   shows "supp (Lam x t) = ((supp ([x].t))::name set)"
   540 lemma lam_supp1:
   372 apply(simp add: supp_def)
   541   shows "(supp (atom x, t)) supports (Lam x t) "
   373 apply(simp add: abs_perm)
   542 apply(simp add: supports_def)
   374 sorry
   543 apply(fold fresh_def)
   375 
   544 apply(simp add: fresh_Pair swap_fresh_fresh)
   376 
   545 apply(clarify)
   377 instance lam::fs_name
   546 apply(subst swap_at_base_simps(3))
       
   547 apply(simp_all add: fresh_atom)
       
   548 done
       
   549 
       
   550 lemma lam_fsupp1:
       
   551   assumes a: "finite (supp t)"
       
   552   shows "finite (supp (Lam x t))"
       
   553 apply(rule supports_finite)
       
   554 apply(rule lam_supp1)
       
   555 apply(simp add: a supp_Pair supp_atom)
       
   556 done
       
   557 
       
   558 instance lam :: fs
   378 apply(default)
   559 apply(default)
   379 apply(induct_tac x rule: lam_induct)
   560 apply(induct_tac x rule: lam_induct)
   380 apply(simp add: var_supp)
   561 apply(simp add: var_supp)
   381 apply(simp add: app_supp)
   562 apply(simp add: app_supp)
   382 apply(simp add: lam_supp abs_supp)
   563 apply(simp add: lam_fsupp1)
       
   564 done
       
   565 
       
   566 lemma supp_fv:
       
   567   shows "supp t = fv t"
       
   568 apply(induct t rule: lam_induct)
       
   569 apply(simp add: var_supp)
       
   570 apply(simp add: app_supp)
       
   571 apply(subgoal_tac "supp (Lam name lam) = supp (Abst {atom name} lam)")
       
   572 apply(simp add: supp_Abst)
       
   573 apply(simp (no_asm) add: supp_def permute_set_eq atom_eqvt)
       
   574 apply(simp add: Lam_pseudo_inject)
       
   575 apply(simp add: abs_eq alpha_gen)
       
   576 apply(simp add: supp_eqvt[symmetric] fv_eqvt[symmetric])
       
   577 done
       
   578 
       
   579 lemma lam_supp2:
       
   580   shows "supp (Lam x t) = supp (Abst {atom x} t)"
       
   581 apply(simp add: supp_def permute_set_eq atom_eqvt)
       
   582 apply(simp add: Lam_pseudo_inject)
       
   583 apply(simp add: abs_eq supp_fv alpha_gen)
       
   584 done
       
   585 
       
   586 lemma lam_supp:
       
   587   shows "supp (Lam x t) = ((supp t) - {atom x})"
       
   588 apply(simp add: lam_supp2)
       
   589 apply(simp add: supp_Abst)
   383 done
   590 done
   384 
   591 
   385 lemma fresh_lam:
   592 lemma fresh_lam:
   386   "(a \<sharp> Lam b t) \<longleftrightarrow> (a = b) \<or> (a \<noteq> b \<and> a \<sharp> t)"
   593   "(atom a \<sharp> Lam b t) \<longleftrightarrow> (a = b) \<or> (a \<noteq> b \<and> atom a \<sharp> t)"
   387 apply(simp add: fresh_def)
   594 apply(simp add: fresh_def)
   388 apply(simp add: lam_supp abs_supp)
   595 apply(simp add: lam_supp)
   389 apply(auto)
   596 apply(auto)
   390 done
   597 done
   391 
   598 
   392 lemma lam_induct_strong:
   599 lemma lam_induct_strong:
   393   fixes a::"'a::fs_name"
   600   fixes a::"'a::fs"
   394   assumes a1: "\<And>name b. P b (Var name)"
   601   assumes a1: "\<And>name b. P b (Var name)"
   395   and     a2: "\<And>lam1 lam2 b. \<lbrakk>\<And>c. P c lam1; \<And>c. P c lam2\<rbrakk> \<Longrightarrow> P b (App lam1 lam2)"
   602   and     a2: "\<And>lam1 lam2 b. \<lbrakk>\<And>c. P c lam1; \<And>c. P c lam2\<rbrakk> \<Longrightarrow> P b (App lam1 lam2)"
   396   and     a3: "\<And>name lam b. \<lbrakk>\<And>c. P c lam; name \<sharp> b\<rbrakk> \<Longrightarrow> P b (Lam name lam)"
   603   and     a3: "\<And>name lam b. \<lbrakk>\<And>c. P c lam; (atom name) \<sharp> b\<rbrakk> \<Longrightarrow> P b (Lam name lam)"
   397   shows "P a lam"
   604   shows "P a lam"
   398 proof -
   605 proof -
   399   have "\<And>(pi::name prm) a. P a (pi \<bullet> lam)" 
   606   have "\<And>pi a. P a (pi \<bullet> lam)" 
   400   proof (induct lam rule: lam_induct)
   607   proof (induct lam rule: lam_induct)
   401     case (1 name pi)
   608     case (1 name pi)
   402     show "P a (pi \<bullet> Var name)"
   609     show "P a (pi \<bullet> Var name)"
   403       apply (simp)
   610       apply (simp)
   404       apply (rule a1)
   611       apply (rule a1)
   405       done
   612       done
   406   next
   613   next
   407     case (2 lam1 lam2 pi)
   614     case (2 lam1 lam2 pi)
   408     have b1: "\<And>(pi::name prm) a. P a (pi \<bullet> lam1)" by fact
   615     have b1: "\<And>pi a. P a (pi \<bullet> lam1)" by fact
   409     have b2: "\<And>(pi::name prm) a. P a (pi \<bullet> lam2)" by fact
   616     have b2: "\<And>pi a. P a (pi \<bullet> lam2)" by fact
   410     show "P a (pi \<bullet> App lam1 lam2)"
   617     show "P a (pi \<bullet> App lam1 lam2)"
   411       apply (simp)
   618       apply (simp)
   412       apply (rule a2)
   619       apply (rule a2)
   413       apply (rule b1)
   620       apply (rule b1)
   414       apply (rule b2)
   621       apply (rule b2)
   415       done
   622       done
   416   next
   623   next
   417     case (3 name lam pi a)
   624     case (3 name lam pi a)
   418     have b: "\<And>(pi::name prm) a. P a (pi \<bullet> lam)" by fact
   625     have b: "\<And>pi a. P a (pi \<bullet> lam)" by fact
   419     obtain c::name where fr: "c\<sharp>(a, pi\<bullet>name, pi\<bullet>lam)"
   626     obtain c::name where fr: "atom c\<sharp>(a, pi\<bullet>name, pi\<bullet>lam)"
   420       apply(rule exists_fresh[of "(a, pi\<bullet>name, pi\<bullet>lam)"])
   627       apply(rule obtain_atom)
   421       apply(simp_all add: fs_name1)
   628       apply(auto)
   422       done
   629       sorry
   423     from b fr have p: "P a (Lam c (([(c, pi\<bullet>name)]@pi)\<bullet>lam))" 
   630     from b fr have p: "P a (Lam c (((c \<leftrightarrow> (pi \<bullet> name)) + pi)\<bullet>lam))" 
   424       apply -
   631       apply -
   425       apply(rule a3)
   632       apply(rule a3)
   426       apply(blast)
   633       apply(blast)
   427       apply(simp)
   634       apply(simp add: fresh_Pair)
   428       done
   635       done
   429     have eq: "[(c, pi\<bullet>name)] \<bullet> Lam (pi \<bullet> name) (pi \<bullet> lam) = Lam (pi \<bullet> name) (pi \<bullet> lam)"
   636     have eq: "(atom c \<rightleftharpoons> atom (pi\<bullet>name)) \<bullet> Lam (pi \<bullet> name) (pi \<bullet> lam) = Lam (pi \<bullet> name) (pi \<bullet> lam)"
   430       apply(rule perm_fresh_fresh)
   637       apply(rule swap_fresh_fresh)
   431       using fr
   638       using fr
   432       apply(simp add: fresh_lam)
   639       apply(simp add: fresh_lam fresh_Pair)
   433       apply(simp add: fresh_lam)
   640       apply(simp add: fresh_lam fresh_Pair)
   434       done
   641       done
   435     show "P a (pi \<bullet> Lam name lam)" 
   642     show "P a (pi \<bullet> Lam name lam)" 
   436       apply (simp)
   643       apply (simp)
   437       apply(subst eq[symmetric])
   644       apply(subst eq[symmetric])
   438       using p
   645       using p
   439       apply(simp only: perm_lam pt_name2 swap_simps)
   646       apply(simp only: permute_lam)
       
   647       apply(simp add: flip_def)
   440       done
   648       done
   441   qed
   649   qed
   442   then have "P a (([]::name prm) \<bullet> lam)" by blast
   650   then have "P a (0 \<bullet> lam)" by blast
   443   then show "P a lam" by simp 
   651   then show "P a lam" by simp 
   444 qed
   652 qed
   445 
   653 
   446 
   654 
   447 lemma var_fresh:
   655 lemma var_fresh:
   448   fixes a::"name"
   656   fixes a::"name"
   449   shows "(a \<sharp> (Var b)) = (a \<sharp> b)"
   657   shows "(atom a \<sharp> (Var b)) = (atom a \<sharp> b)"
   450   apply(simp add: fresh_def)
   658   apply(simp add: fresh_def)
   451   apply(simp add: var_supp1)
   659   apply(simp add: var_supp1)
   452   done
   660   done
   453 
   661 
   454 (* lemma hom_reg: *)
       
   455 
       
   456 lemma rlam_rec_eqvt:
       
   457   fixes pi::"name prm"
       
   458   and   f1::"name \<Rightarrow> ('a::pt_name)"
       
   459   shows "(pi\<bullet>rlam_rec f1 f2 f3 t) = rlam_rec (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3) (pi\<bullet>t)"
       
   460 apply(induct t)
       
   461 apply(simp_all)
       
   462 apply(simp add: perm_fun_def)
       
   463 apply(perm_simp)
       
   464 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   465 back
       
   466 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   467 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   468 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   469 apply(simp)
       
   470 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   471 back
       
   472 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   473 apply(subst pt_fun_app_eq[OF pt_name_inst at_name_inst])
       
   474 apply(simp)
       
   475 done
       
   476  
       
   477 
       
   478 lemma rlam_rec_respects:
       
   479   assumes f1: "f_var \<in> Respects (op= ===> op=)"
       
   480   and     f2: "f_app \<in> Respects (alpha ===> alpha ===> op= ===> op= ===> op=)"
       
   481   and     f3: "f_lam \<in> Respects (op= ===> alpha ===> op= ===> op=)"
       
   482   shows "rlam_rec f_var f_app f_lam \<in> Respects (alpha ===> op =)"
       
   483 apply(simp add: mem_def)
       
   484 apply(simp add: Respects_def)
       
   485 apply(rule allI)
       
   486 apply(rule allI)
       
   487 apply(rule impI)
       
   488 apply(erule alpha.induct)
       
   489 apply(simp)
       
   490 apply(simp)
       
   491 using f2
       
   492 apply(simp add: mem_def)
       
   493 apply(simp add: Respects_def)
       
   494 using f3[simplified mem_def Respects_def]
       
   495 apply(simp)
       
   496 apply(case_tac "a=b")
       
   497 apply(clarify)
       
   498 apply(simp)
       
   499 (* probably true *)
       
   500 sorry
       
   501 
       
   502 function
       
   503   term1_hom :: "(name \<Rightarrow> 'a) \<Rightarrow>
       
   504                 (rlam \<Rightarrow> rlam \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow>
       
   505                 ((name \<Rightarrow> rlam) \<Rightarrow> (name \<Rightarrow> 'a) \<Rightarrow> 'a) \<Rightarrow> rlam \<Rightarrow> 'a"
       
   506 where
       
   507   "term1_hom var app abs' (rVar x) = (var x)"
       
   508 | "term1_hom var app abs' (rApp t u) =
       
   509      app t u (term1_hom var app abs' t) (term1_hom var app abs' u)"
       
   510 | "term1_hom var app abs' (rLam x u) =
       
   511      abs' (\<lambda>y. [(x, y)] \<bullet> u) (\<lambda>y. term1_hom var app abs' ([(x, y)] \<bullet> u))"
       
   512 apply(pat_completeness)
       
   513 apply(auto)
       
   514 done
       
   515 
       
   516 lemma pi_size:
       
   517   fixes pi::"name prm"
       
   518   and   t::"rlam"
       
   519   shows "size (pi \<bullet> t) = size t"
       
   520 apply(induct t)
       
   521 apply(auto)
       
   522 done
       
   523 
       
   524 termination term1_hom
       
   525   apply(relation "measure (\<lambda>(f1, f2, f3, t). size t)")
       
   526 apply(auto simp add: pi_size)
       
   527 done
       
   528 
       
   529 lemma lam_exhaust:
       
   530   "\<lbrakk>\<And>name. y = Var name \<Longrightarrow> P; \<And>rlam1 rlam2. y = App rlam1 rlam2 \<Longrightarrow> P; \<And>name rlam. y = Lam name rlam \<Longrightarrow> P\<rbrakk>
       
   531     \<Longrightarrow> P"
       
   532 apply(lifting rlam.exhaust)
       
   533 done
       
   534 
       
   535 (* THIS IS NOT TRUE, but it lets prove the existence of the hom function *)
       
   536 lemma lam_inject':
       
   537   "(Lam a x = Lam b y) = ((\<lambda>c. [(a, c)] \<bullet> x) = (\<lambda>c. [(b, c)] \<bullet> y))"
       
   538 sorry
       
   539 
       
   540 function
       
   541   hom :: "(name \<Rightarrow> 'a) \<Rightarrow>
       
   542                 (lam \<Rightarrow> lam \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow>
       
   543                 ((name \<Rightarrow> lam) \<Rightarrow> (name \<Rightarrow> 'a) \<Rightarrow> 'a) \<Rightarrow> lam \<Rightarrow> 'a"
       
   544 where
       
   545   "hom f_var f_app f_lam (Var x) = f_var x"
       
   546 | "hom f_var f_app f_lam (App l r) = f_app l r (hom f_var f_app f_lam l) (hom f_var f_app f_lam r)"
       
   547 | "hom f_var f_app f_lam (Lam a x) = f_lam (\<lambda>b. ([(a,b)] \<bullet> x)) (\<lambda>b. hom f_var f_app f_lam ([(a,b)] \<bullet> x))"
       
   548 defer
       
   549 apply(simp_all add: lam_inject') (* inject, distinct *)
       
   550 apply(tactic {* Cong_Tac.cong_tac @{thm cong} 1 *})
       
   551 apply(rule refl)
       
   552 apply(rule ext)
       
   553 apply(tactic {* Cong_Tac.cong_tac @{thm cong} 1 *})
       
   554 apply simp_all
       
   555 apply(erule conjE)+
       
   556 apply(rule_tac x="b" in cong)
       
   557 apply simp_all
       
   558 apply auto
       
   559 apply(rule_tac y="b" in lam_exhaust)
       
   560 apply simp_all
       
   561 apply auto
       
   562 apply meson
       
   563 apply(simp_all add: lam_inject')
       
   564 apply metis
       
   565 done
       
   566 
       
   567 termination hom
       
   568   apply -
       
   569 (*
       
   570 ML_prf {* Size.size_thms @{theory} "LamEx.lam" *}
       
   571 *)
       
   572 sorry
       
   573 
       
   574 thm hom.simps
       
   575 
       
   576 lemma term1_hom_rsp:
       
   577   "\<lbrakk>(alpha ===> alpha ===> op =) f_app f_app; ((op = ===> alpha) ===> op =) f_lam f_lam\<rbrakk>
       
   578        \<Longrightarrow> (alpha ===> op =) (term1_hom f_var f_app f_lam) (term1_hom f_var f_app f_lam)"
       
   579 apply(simp)
       
   580 apply(rule allI)+
       
   581 apply(rule impI)
       
   582 apply(erule alpha.induct)
       
   583 apply(auto)[1]
       
   584 apply(auto)[1]
       
   585 apply(simp)
       
   586 apply(erule conjE)+
       
   587 apply(erule exE)+
       
   588 apply(erule conjE)+
       
   589 apply(clarify)
       
   590 sorry
       
   591 
       
   592 lemma hom: "
       
   593 \<forall>f_var. \<forall>f_app \<in> Respects(alpha ===> alpha ===> op =).
       
   594 \<forall>f_lam \<in> Respects((op = ===> alpha) ===> op =).
       
   595 \<exists>hom\<in>Respects (alpha ===> op =). 
       
   596     ((\<forall>x. hom (rVar x) = f_var x) \<and>
       
   597      (\<forall>l r. hom (rApp l r) = f_app l r (hom l) (hom r)) \<and>
       
   598      (\<forall>x a. hom (rLam a x) = f_lam (\<lambda>b. ([(a,b)]\<bullet> x)) (\<lambda>b. hom ([(a,b)] \<bullet> x))))"
       
   599 apply(rule allI)
       
   600 apply(rule ballI)+
       
   601 apply(rule_tac x="term1_hom f_var f_app f_lam" in bexI)
       
   602 apply(simp_all)
       
   603 apply(simp only: in_respects)
       
   604 apply(rule term1_hom_rsp)
       
   605 apply(assumption)+
       
   606 done
       
   607 
       
   608 lemma hom':
       
   609 "\<exists>hom.
       
   610   ((\<forall>x. hom (Var x) = f_var x) \<and>
       
   611    (\<forall>l r. hom (App l r) = f_app l r (hom l) (hom r)) \<and>
       
   612    (\<forall>x a. hom (Lam a x) = f_lam (\<lambda>b. ([(a,b)] \<bullet> x)) (\<lambda>b. hom ([(a,b)] \<bullet> x))))"
       
   613 apply (lifting hom)
       
   614 done
       
   615 
       
   616 (* test test
       
   617 lemma raw_hom_correct: 
       
   618   assumes f1: "f_var \<in> Respects (op= ===> op=)"
       
   619   and     f2: "f_app \<in> Respects (alpha ===> alpha ===> op= ===> op= ===> op=)"
       
   620   and     f3: "f_lam \<in> Respects ((op= ===> alpha) ===> (op= ===> op=) ===> op=)"
       
   621   shows "\<exists>!hom\<in>Respects (alpha ===> op =). 
       
   622     ((\<forall>x. hom (rVar x) = f_var x) \<and>
       
   623      (\<forall>l r. hom (rApp l r) = f_app l r (hom l) (hom r)) \<and>
       
   624      (\<forall>x a. hom (rLam a x) = f_lam (\<lambda>b. ([(a,b)]\<bullet> x)) (\<lambda>b. hom ([(a,b)] \<bullet> x))))"
       
   625 unfolding Bex1_def
       
   626 apply(rule ex1I)
       
   627 sorry
       
   628 *)
       
   629 
   662 
   630 
   663 
   631 end
   664 end
   632 
   665