Nominal/Ex/Lambda.thy
changeset 1831 16653e702d89
parent 1828 f374ffd50c7c
child 1833 2050b5723c04
equal deleted inserted replaced
1829:ac8cb569a17b 1831:16653e702d89
   125 where
   125 where
   126     t_Var[intro]: "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
   126     t_Var[intro]: "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
   127   | t_App[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2 \<or> \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : T2"
   127   | t_App[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2 \<or> \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : T2"
   128   | t_Lam[intro]: "\<lbrakk>atom x \<sharp> \<Gamma>; (x, T1) # \<Gamma> \<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam x t : T1 \<rightarrow> T2"
   128   | t_Lam[intro]: "\<lbrakk>atom x \<sharp> \<Gamma>; (x, T1) # \<Gamma> \<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam x t : T1 \<rightarrow> T2"
   129 
   129 
       
   130 ML {*
       
   131 val inductive_atomize = @{thms induct_atomize};
       
   132 
       
   133 val atomize_conv = 
       
   134   MetaSimplifier.rewrite_cterm (true, false, false) (K (K NONE))
       
   135     (HOL_basic_ss addsimps inductive_atomize);
       
   136 val atomize_intr = Conv.fconv_rule (Conv.prems_conv ~1 atomize_conv);
       
   137 fun atomize_induct ctxt = Conv.fconv_rule (Conv.prems_conv ~1
       
   138   (Conv.params_conv ~1 (K (Conv.prems_conv ~1 atomize_conv)) ctxt));
       
   139 *}
   130 
   140 
   131 ML {*
   141 ML {*
   132 fun map_term f t = 
   142 fun map_term f t = 
   133   (case f t of
   143   (case f t of
   134      NONE => map_term' f t 
   144      NONE => map_term' f t 
   184 end
   194 end
   185 *}
   195 *}
   186 
   196 
   187 ML {*
   197 ML {*
   188 open Nominal_Permeq
   198 open Nominal_Permeq
       
   199 open Nominal_ThmDecls
       
   200 *}
       
   201 
       
   202 ML {*
       
   203 fun mk_perm p trm =
       
   204 let
       
   205   val ty = fastype_of trm
       
   206 in
       
   207   Const (@{const_name "permute"}, @{typ "perm"} --> ty --> ty) $ p $ trm
       
   208 end
       
   209 
       
   210 fun mk_minus p = 
       
   211  Const (@{const_name "uminus"}, @{typ "perm => perm"}) $ p   
   189 *}
   212 *}
   190 
   213 
   191 ML {* 
   214 ML {* 
   192 fun single_case_tac ctxt pred_names pi intro  = 
   215 fun single_case_tac ctxt pred_names pi intro  = 
   193 let
   216 let
   194   val rule = Drule.instantiate' [] [SOME pi] @{thm permute_boolE}
   217   val thy = ProofContext.theory_of ctxt
       
   218   val cpi = Thm.cterm_of thy (mk_minus pi)
       
   219   val rule = Drule.instantiate' [] [SOME cpi] @{thm permute_boolE}
   195 in
   220 in
   196   eqvt_strict_tac ctxt [] [] THEN' 
   221   eqvt_strict_tac ctxt [] [] THEN' 
   197   SUBPROOF (fn {prems, context as ctxt, ...} =>
   222   SUBPROOF (fn {prems, context as ctxt, ...} =>
   198     let
   223     let
   199       val prems' = map (transform_prem ctxt pred_names) prems
   224       val prems' = map (transform_prem ctxt pred_names) prems
   206     end) ctxt
   231     end) ctxt
   207 end
   232 end
   208 *}
   233 *}
   209 
   234 
   210 ML {*
   235 ML {*
   211 fun eqvt_rel_tac pred_name = 
   236 fun prepare_pred params_no pi pred =
       
   237 let
       
   238   val (c, xs) = strip_comb pred;
       
   239   val (xs1, xs2) = chop params_no xs
       
   240 in
       
   241   HOLogic.mk_imp 
       
   242     (pred, list_comb (c, xs1 @ map (mk_perm pi) xs2))
       
   243 end
       
   244 *}
       
   245 
       
   246 ML {*
       
   247 fun transp ([] :: _) = []
       
   248   | transp xs = map hd xs :: transp (map tl xs);
       
   249 *}
       
   250 
       
   251 ML {* 
       
   252   Local_Theory.note;
       
   253   Local_Theory.notes;
       
   254   fold_map
       
   255 *}
       
   256 
       
   257 ML {*
       
   258 fun note_named_thm (name, thm) ctxt = 
       
   259 let
       
   260   val thm_name = Binding.qualified_name 
       
   261     (Long_Name.qualify (Long_Name.base_name name) "eqvt")
       
   262   val attr = Attrib.internal (K eqvt_add)
       
   263 in
       
   264   Local_Theory.note ((thm_name, [attr]), [thm]) ctxt
       
   265 end
       
   266 *}
       
   267 
       
   268 ML {*
       
   269 fun eqvt_rel_tac pred_name ctxt = 
   212 let
   270 let
   213   val thy = ProofContext.theory_of ctxt
   271   val thy = ProofContext.theory_of ctxt
   214   val ({names, ...}, {raw_induct, intrs, ...}) =
   272   val ({names, ...}, {raw_induct, intrs, ...}) =
   215     Inductive.the_inductive ctxt (Sign.intern_const thy pred_name)
   273     Inductive.the_inductive ctxt (Sign.intern_const thy pred_name)
   216   val param_no = length (Inductive.params_of raw_induct)
   274   val raw_induct = atomize_induct ctxt raw_induct;
   217   val (([raw_concl], [pi]), ctxt') = 
   275   val intros = map atomize_intr intrs;
       
   276   val params_no = length (Inductive.params_of raw_induct)
       
   277   val (([raw_concl], [raw_pi]), ctxt') = 
   218     ctxt |> Variable.import_terms false [concl_of raw_induct] 
   278     ctxt |> Variable.import_terms false [concl_of raw_induct] 
   219          ||>> Variable.variant_fixes ["pi"];
   279          ||>> Variable.variant_fixes ["pi"]
       
   280   val pi = Free (raw_pi, @{typ perm})
   220   val preds = map (fst o HOLogic.dest_imp)
   281   val preds = map (fst o HOLogic.dest_imp)
   221     (HOLogic.dest_conj (HOLogic.dest_Trueprop raw_concl));
   282     (HOLogic.dest_conj (HOLogic.dest_Trueprop raw_concl));
   222 in
   283   val goal = HOLogic.mk_Trueprop 
   223 
   284     (foldr1 HOLogic.mk_conj (map (prepare_pred params_no pi) preds))
   224 end
   285   val thm = Goal.prove ctxt' [] [] goal (fn {context,...} => 
   225 *}
   286     HEADGOAL (EVERY' (rtac raw_induct :: map (single_case_tac context names pi) intros)))
   226 
   287     |> singleton (ProofContext.export ctxt' ctxt)
   227 
   288   val thms = map (fn th => zero_var_indexes (th RS mp)) (Datatype_Aux.split_conj_thm thm)
   228 
   289 in
   229 lemma [eqvt]:
   290    ctxt |> fold_map note_named_thm (names ~~ thms)
   230   assumes a: "valid Gamma" 
   291         |> snd
   231   shows "valid (p \<bullet> Gamma)"
   292 end
   232 using a
   293 *}
   233 apply(induct)
   294 
   234 apply(tactic {* my_tac @{context} ["Lambda.valid"] @{cterm "- p"} @{thm valid.intros(1)} 1 *})
   295 
   235 apply(tactic {* my_tac @{context }["Lambda.valid"] @{cterm "- p"} @{thm valid.intros(2)} 1 *})
   296 ML {*
   236 done
   297 local structure P = OuterParse and K = OuterKeyword in
   237 
   298 
   238 lemma 
   299 val _ =
   239   shows "Gamma \<turnstile> t : T \<longrightarrow> (p \<bullet> Gamma) \<turnstile> (p \<bullet> t) : (p \<bullet> T)"
   300   OuterSyntax.local_theory "equivariance"
   240 ML_prf {*
   301     "prove equivariance for inductive predicate involving nominal datatypes" K.thy_decl
   241 val ({names, ...}, {raw_induct, ...}) =
   302     (P.xname >> eqvt_rel_tac);
   242       Inductive.the_inductive @{context} (Sign.intern_const @{theory} "typing")
   303 
   243 *}
   304 end;
   244 apply(tactic {* rtac raw_induct 1 *})
   305 *}
   245 apply(tactic {* my_tac @{context} ["Lambda.typing"] @{cterm "- p"} @{thm typing.intros(1)} 1 *})
   306 
   246 apply(tactic {* my_tac @{context} ["Lambda.typing"] @{cterm "- p"} @{thm typing.intros(2)} 1 *})
   307 equivariance valid
   247 apply(tactic {* my_tac @{context} ["Lambda.typing"] @{cterm "- p"} @{thm typing.intros(3)} 1 *})
   308 equivariance typing
   248 done
   309 
   249 
   310 thm valid.eqvt
   250 lemma uu[eqvt]:
   311 thm typing.eqvt
   251   assumes a: "Gamma \<turnstile> t : T" 
       
   252   shows "(p \<bullet> Gamma) \<turnstile> (p \<bullet> t) : (p \<bullet> T)"
       
   253 using a
       
   254 apply(induct)
       
   255 apply(tactic {* my_tac @{context} @{thms typing.intros} 1 *})
       
   256 apply(perm_strict_simp)
       
   257 apply(rule typing.intros)
       
   258 apply(rule conj_mono[THEN mp])
       
   259 prefer 3
       
   260 apply(assumption)
       
   261 apply(rule impI)
       
   262 prefer 2
       
   263 apply(rule impI)
       
   264 apply(simp)
       
   265 apply(auto)[1]
       
   266 apply(simp)
       
   267 apply(tactic {* my_tac @{context} @{thms typing.intros} 1 *})
       
   268 done
       
   269 
       
   270 (*
       
   271 inductive
       
   272   typing :: "(name\<times>ty) list \<Rightarrow> lam \<Rightarrow> ty \<Rightarrow> bool" ("_ \<turnstile> _ : _" [60,60,60] 60) 
       
   273 where
       
   274     t_Var[intro]: "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
       
   275   | t_App[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2 \<and> \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : T2"
       
   276   | t_Lam[intro]: "\<lbrakk>atom x \<sharp> \<Gamma>; (x, T1) # \<Gamma> \<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam x t : T1 \<rightarrow> T2"
       
   277 
       
   278 lemma uu[eqvt]:
       
   279   assumes a: "Gamma \<turnstile> t : T" 
       
   280   shows "(p \<bullet> Gamma) \<turnstile> (p \<bullet> t) : (p \<bullet> T)"
       
   281 using a
       
   282 apply(induct)
       
   283 apply(tactic {* my_tac @{context} @{thms typing.intros} 1 *})
       
   284 apply(tactic {* my_tac @{context} @{thms typing.intros} 1 *})
       
   285 apply(tactic {* my_tac @{context} @{thms typing.intros} 1 *})
       
   286 done
       
   287 *)
       
   288 
       
   289 ML {*
       
   290 val inductive_atomize = @{thms induct_atomize};
       
   291 
       
   292 val atomize_conv =
       
   293   MetaSimplifier.rewrite_cterm (true, false, false) (K (K NONE))
       
   294     (HOL_basic_ss addsimps inductive_atomize);
       
   295 val atomize_intr = Conv.fconv_rule (Conv.prems_conv ~1 atomize_conv);
       
   296 fun atomize_induct ctxt = Conv.fconv_rule (Conv.prems_conv ~1
       
   297   (Conv.params_conv ~1 (K (Conv.prems_conv ~1 atomize_conv)) ctxt));
       
   298 *}
       
   299 
       
   300 ML {*
       
   301 val ({names, ...}, {raw_induct, intrs, elims, ...}) =
       
   302       Inductive.the_inductive @{context} (Sign.intern_const @{theory} "typing")
       
   303 *}
       
   304 
       
   305 ML {* val ind_params = Inductive.params_of raw_induct *}
       
   306 ML {* val raw_induct = atomize_induct @{context} raw_induct; *}
       
   307 ML {* val elims = map (atomize_induct @{context}) elims; *}
       
   308 ML {* val monos = Inductive.get_monos @{context}; *}
       
   309 
       
   310 lemma 
       
   311   shows "Gamma \<turnstile> t : T \<longrightarrow> (p \<bullet> Gamma) \<turnstile> (p \<bullet> t) : (p \<bullet> T)"
       
   312 apply(tactic {* rtac raw_induct 1 *})
       
   313 apply(tactic {* my_tac @{context} intrs 1 *})
       
   314 apply(perm_strict_simp)
       
   315 apply(rule typing.intros)
       
   316 oops
       
   317 
       
   318 
       
   319 thm eqvts
   312 thm eqvts
   320 thm eqvts_raw
   313 thm eqvts_raw
   321 
   314 
   322 declare permute_lam_raw.simps[eqvt]
       
   323 thm alpha_gen_real_eqvt
       
   324 (*declare alpha_gen_real_eqvt[eqvt]*)
       
   325 
       
   326 lemma
       
   327   assumes a: "alpha_lam_raw t1 t2"
       
   328   shows "alpha_lam_raw (p \<bullet> t1) (p \<bullet> t2)"
       
   329 using a
       
   330 apply(induct)
       
   331 apply(tactic {* my_tac @{context} @{thms alpha_lam_raw.intros} 1 *})
       
   332 oops
       
   333 
       
   334 thm alpha_lam_raw.intros[no_vars]
       
   335 
   315 
   336 inductive
   316 inductive
   337  alpha_lam_raw'
   317  alpha_lam_raw'
   338 where
   318 where
   339   "name = namea \<Longrightarrow> alpha_lam_raw' (Var_raw name) (Var_raw namea)"
   319   "name = namea \<Longrightarrow> alpha_lam_raw' (Var_raw name) (Var_raw namea)"
   340 | "\<lbrakk>alpha_lam_raw' lam_raw1 lam_raw1a; alpha_lam_raw' lam_raw2 lam_raw2a\<rbrakk> \<Longrightarrow>
   320 | "\<lbrakk>alpha_lam_raw' lam_raw1 lam_raw1a; alpha_lam_raw' lam_raw2 lam_raw2a\<rbrakk> \<Longrightarrow>
   341    alpha_lam_raw' (App_raw lam_raw1 lam_raw2) (App_raw lam_raw1a lam_raw2a)"
   321    alpha_lam_raw' (App_raw lam_raw1 lam_raw2) (App_raw lam_raw1a lam_raw2a)"
   342 | "\<exists>pi. ({atom name}, lam_raw) \<approx>gen alpha_lam_raw fv_lam_raw pi ({atom namea}, lam_rawa) \<Longrightarrow>
   322 | "\<exists>pi. ({atom name}, lam_raw) \<approx>gen alpha_lam_raw fv_lam_raw pi ({atom namea}, lam_rawa) \<Longrightarrow>
   343    alpha_lam_raw' (Lam_raw name lam_raw) (Lam_raw namea lam_rawa)"
   323    alpha_lam_raw' (Lam_raw name lam_raw) (Lam_raw namea lam_rawa)"
   344 
   324 
       
   325 declare permute_lam_raw.simps[eqvt]
       
   326 (*declare alpha_gen_real_eqvt[eqvt]*)
       
   327 (*equivariance alpha_lam_raw'*)
       
   328 
   345 lemma
   329 lemma
   346   assumes a: "alpha_lam_raw' t1 t2"
   330   assumes a: "alpha_lam_raw' t1 t2"
   347   shows "alpha_lam_raw' (p \<bullet> t1) (p \<bullet> t2)"
   331   shows "alpha_lam_raw' (p \<bullet> t1) (p \<bullet> t2)"
   348 using a
   332 using a
   349 apply(induct)
   333 apply(induct)
   350 apply(tactic {* my_tac @{context} @{thms alpha_lam_raw'.intros} 1 *})
       
   351 apply(tactic {* my_tac @{context} @{thms alpha_lam_raw'.intros} 1 *})
       
   352 apply(perm_strict_simp)
       
   353 apply(rule alpha_lam_raw'.intros)
       
   354 apply(simp add: alphas)
       
   355 apply(rule_tac p="- p" in permute_boolE)
       
   356 apply(perm_simp permute_minus_cancel(2))
       
   357 oops
   334 oops
   358 
   335 
   359 
   336 
   360 section {* size function *}
   337 section {* size function *}
   361 
   338