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 |