32 val fresh_prod = @{thm fresh_prod}; |
32 val fresh_prod = @{thm fresh_prod}; |
33 |
33 |
34 val perm_bool = mk_meta_eq @{thm perm_bool_def}; |
34 val perm_bool = mk_meta_eq @{thm perm_bool_def}; |
35 val perm_boolI = @{thm perm_boolI}; |
35 val perm_boolI = @{thm perm_boolI}; |
36 val (_, [perm_boolI_pi, _]) = Drule.strip_comb (snd (Thm.dest_comb |
36 val (_, [perm_boolI_pi, _]) = Drule.strip_comb (snd (Thm.dest_comb |
37 (Drule.strip_imp_concl (cprop_of perm_boolI)))); |
37 (Drule.strip_imp_concl (Thm.cprop_of perm_boolI)))); |
38 |
38 |
39 fun mk_perm_bool pi th = th RS Drule.cterm_instantiate |
39 fun mk_perm_bool pi th = th RS Drule.cterm_instantiate |
40 [(perm_boolI_pi, pi)] perm_boolI; |
40 [(perm_boolI_pi, pi)] perm_boolI; |
41 |
41 |
42 fun mk_perm_bool_simproc names = Simplifier.simproc_global_i |
42 fun mk_perm_bool_simproc names = Simplifier.simproc_global_i |
43 (theory_of_thm perm_bool) "perm_bool" [@{term "perm pi x"}] (fn ctxt => |
43 (Thm.theory_of_thm perm_bool) "perm_bool" [@{term "perm pi x"}] (fn ctxt => |
44 fn Const (@{const_name Nominal.perm}, _) $ _ $ t => |
44 fn Const (@{const_name Nominal.perm}, _) $ _ $ t => |
45 if member (op =) names (the_default "" (try (head_of #> dest_Const #> fst) t)) |
45 if member (op =) names (the_default "" (try (head_of #> dest_Const #> fst) t)) |
46 then SOME perm_bool else NONE |
46 then SOME perm_bool else NONE |
47 | _ => NONE); |
47 | _ => NONE); |
48 |
48 |
124 (* Prove F[f t] from F[t], where F is monotone *) |
124 (* Prove F[f t] from F[t], where F is monotone *) |
125 (*********************************************************************) |
125 (*********************************************************************) |
126 |
126 |
127 fun map_thm ctxt f tac monos opt th = |
127 fun map_thm ctxt f tac monos opt th = |
128 let |
128 let |
129 val prop = prop_of th; |
129 val prop = Thm.prop_of th; |
130 fun prove t = |
130 fun prove t = |
131 Goal.prove ctxt [] [] t (fn _ => |
131 Goal.prove ctxt [] [] t (fn _ => |
132 EVERY [cut_facts_tac [th] 1, etac rev_mp 1, |
132 EVERY [cut_facts_tac [th] 1, etac rev_mp 1, |
133 REPEAT_DETERM (FIRSTGOAL (resolve_tac ctxt monos)), |
133 REPEAT_DETERM (FIRSTGOAL (resolve_tac ctxt monos)), |
134 REPEAT_DETERM (rtac impI 1 THEN (atac 1 ORELSE tac))]) |
134 REPEAT_DETERM (rtac impI 1 THEN (atac 1 ORELSE tac))]) |
139 fun first_order_matchs pats objs = Thm.first_order_match |
139 fun first_order_matchs pats objs = Thm.first_order_match |
140 (eta_contract_cterm (Conjunction.mk_conjunction_balanced pats), |
140 (eta_contract_cterm (Conjunction.mk_conjunction_balanced pats), |
141 eta_contract_cterm (Conjunction.mk_conjunction_balanced objs)); |
141 eta_contract_cterm (Conjunction.mk_conjunction_balanced objs)); |
142 |
142 |
143 fun first_order_mrs ths th = ths MRS |
143 fun first_order_mrs ths th = ths MRS |
144 Thm.instantiate (first_order_matchs (cprems_of th) (map cprop_of ths)) th; |
144 Thm.instantiate (first_order_matchs (cprems_of th) (map Thm.cprop_of ths)) th; |
145 |
145 |
146 fun prove_strong_ind s avoids ctxt = |
146 fun prove_strong_ind s avoids ctxt = |
147 let |
147 let |
148 val thy = Proof_Context.theory_of ctxt; |
148 val thy = Proof_Context.theory_of ctxt; |
149 val ({names, ...}, {raw_induct, intrs, elims, ...}) = |
149 val ({names, ...}, {raw_induct, intrs, elims, ...}) = |
157 [] => () |
157 [] => () |
158 | xs => error ("Missing equivariance theorem for predicate(s): " ^ |
158 | xs => error ("Missing equivariance theorem for predicate(s): " ^ |
159 commas_quote xs)); |
159 commas_quote xs)); |
160 val induct_cases = map (fst o fst) (fst (Rule_Cases.get (the |
160 val induct_cases = map (fst o fst) (fst (Rule_Cases.get (the |
161 (Induct.lookup_inductP ctxt (hd names))))); |
161 (Induct.lookup_inductP ctxt (hd names))))); |
162 val ([raw_induct'], ctxt') = Variable.import_terms false [prop_of raw_induct] ctxt; |
162 val ([raw_induct'], ctxt') = Variable.import_terms false [Thm.prop_of raw_induct] ctxt; |
163 val concls = raw_induct' |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |> |
163 val concls = raw_induct' |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |> |
164 HOLogic.dest_conj |> map (HOLogic.dest_imp ##> strip_comb); |
164 HOLogic.dest_conj |> map (HOLogic.dest_imp ##> strip_comb); |
165 val ps = map (fst o snd) concls; |
165 val ps = map (fst o snd) concls; |
166 |
166 |
167 val _ = (case duplicates (op = o apply2 fst) avoids of |
167 val _ = (case duplicates (op = o apply2 fst) avoids of |
202 val (fs_ctxt_tyname, _) = Name.variant "'n" (Variable.names_of ctxt'); |
202 val (fs_ctxt_tyname, _) = Name.variant "'n" (Variable.names_of ctxt'); |
203 val ([fs_ctxt_name], ctxt'') = Variable.variant_fixes ["z"] ctxt'; |
203 val ([fs_ctxt_name], ctxt'') = Variable.variant_fixes ["z"] ctxt'; |
204 val fsT = TFree (fs_ctxt_tyname, ind_sort); |
204 val fsT = TFree (fs_ctxt_tyname, ind_sort); |
205 |
205 |
206 val inductive_forall_def' = Drule.instantiate' |
206 val inductive_forall_def' = Drule.instantiate' |
207 [SOME (ctyp_of thy fsT)] [] inductive_forall_def; |
207 [SOME (Thm.ctyp_of thy fsT)] [] inductive_forall_def; |
208 |
208 |
209 fun lift_pred' t (Free (s, T)) ts = |
209 fun lift_pred' t (Free (s, T)) ts = |
210 list_comb (Free (s, fsT --> T), t :: ts); |
210 list_comb (Free (s, fsT --> T), t :: ts); |
211 val lift_pred = lift_pred' (Bound 0); |
211 val lift_pred = lift_pred' (Bound 0); |
212 |
212 |
303 [etac exE 1, |
303 [etac exE 1, |
304 full_simp_tac (put_simpset HOL_ss ctxt' addsimps (fresh_prod :: fresh_atm)) 1, |
304 full_simp_tac (put_simpset HOL_ss ctxt' addsimps (fresh_prod :: fresh_atm)) 1, |
305 full_simp_tac (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}]) 1, |
305 full_simp_tac (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}]) 1, |
306 REPEAT (etac conjE 1)]) |
306 REPEAT (etac conjE 1)]) |
307 [ex] ctxt |
307 [ex] ctxt |
308 in (freshs1 @ [term_of cx], freshs2 @ ths, ctxt') end; |
308 in (freshs1 @ [Thm.term_of cx], freshs2 @ ths, ctxt') end; |
309 |
309 |
310 fun mk_ind_proof ctxt' thss = |
310 fun mk_ind_proof ctxt' thss = |
311 Goal.prove ctxt' [] prems' concl' (fn {prems = ihyps, context = ctxt} => |
311 Goal.prove ctxt' [] prems' concl' (fn {prems = ihyps, context = ctxt} => |
312 let val th = Goal.prove ctxt [] [] concl (fn {context, ...} => |
312 let val th = Goal.prove ctxt [] [] concl (fn {context, ...} => |
313 rtac raw_induct 1 THEN |
313 rtac raw_induct 1 THEN |
314 EVERY (maps (fn ((((_, bvars, oprems, _), vc_compat_ths), ihyp), (vs, ihypt)) => |
314 EVERY (maps (fn ((((_, bvars, oprems, _), vc_compat_ths), ihyp), (vs, ihypt)) => |
315 [REPEAT (rtac allI 1), simp_tac (put_simpset eqvt_ss context) 1, |
315 [REPEAT (rtac allI 1), simp_tac (put_simpset eqvt_ss context) 1, |
316 SUBPROOF (fn {prems = gprems, params, concl, context = ctxt', ...} => |
316 SUBPROOF (fn {prems = gprems, params, concl, context = ctxt', ...} => |
317 let |
317 let |
318 val (params', (pis, z)) = |
318 val (params', (pis, z)) = |
319 chop (length params - length atomTs - 1) (map (term_of o #2) params) ||> |
319 chop (length params - length atomTs - 1) (map (Thm.term_of o #2) params) ||> |
320 split_last; |
320 split_last; |
321 val bvars' = map |
321 val bvars' = map |
322 (fn (Bound i, T) => (nth params' (length params' - i), T) |
322 (fn (Bound i, T) => (nth params' (length params' - i), T) |
323 | (t, T) => (t, T)) bvars; |
323 | (t, T) => (t, T)) bvars; |
324 val pi_bvars = map (fn (t, _) => |
324 val pi_bvars = map (fn (t, _) => |
325 fold_rev (NominalDatatype.mk_perm []) pis t) bvars'; |
325 fold_rev (NominalDatatype.mk_perm []) pis t) bvars'; |
326 val (P, ts) = strip_comb (HOLogic.dest_Trueprop (term_of concl)); |
326 val (P, ts) = strip_comb (HOLogic.dest_Trueprop (Thm.term_of concl)); |
327 val (freshs1, freshs2, ctxt'') = fold |
327 val (freshs1, freshs2, ctxt'') = fold |
328 (obtain_fresh_name (ts @ pi_bvars)) |
328 (obtain_fresh_name (ts @ pi_bvars)) |
329 (map snd bvars') ([], [], ctxt'); |
329 (map snd bvars') ([], [], ctxt'); |
330 val freshs2' = NominalDatatype.mk_not_sym freshs2; |
330 val freshs2' = NominalDatatype.mk_not_sym freshs2; |
331 val pis' = map NominalDatatype.perm_of_pair (pi_bvars ~~ freshs1); |
331 val pis' = map NominalDatatype.perm_of_pair (pi_bvars ~~ freshs1); |
334 in if T = fastype_of pi2 then |
334 in if T = fastype_of pi2 then |
335 Const (@{const_name append}, T --> T --> T) $ pi1 $ pi2 |
335 Const (@{const_name append}, T --> T --> T) $ pi1 $ pi2 |
336 else pi2 |
336 else pi2 |
337 end; |
337 end; |
338 val pis'' = fold (concat_perm #> map) pis' pis; |
338 val pis'' = fold (concat_perm #> map) pis' pis; |
339 val env = Pattern.first_order_match thy (ihypt, prop_of ihyp) |
339 val env = Pattern.first_order_match thy (ihypt, Thm.prop_of ihyp) |
340 (Vartab.empty, Vartab.empty); |
340 (Vartab.empty, Vartab.empty); |
341 val ihyp' = Thm.instantiate ([], map (apply2 (cterm_of thy)) |
341 val ihyp' = Thm.instantiate ([], map (apply2 (Thm.cterm_of thy)) |
342 (map (Envir.subst_term env) vs ~~ |
342 (map (Envir.subst_term env) vs ~~ |
343 map (fold_rev (NominalDatatype.mk_perm []) |
343 map (fold_rev (NominalDatatype.mk_perm []) |
344 (rev pis' @ pis)) params' @ [z])) ihyp; |
344 (rev pis' @ pis)) params' @ [z])) ihyp; |
345 fun mk_pi th = |
345 fun mk_pi th = |
346 Simplifier.simplify (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}] |
346 Simplifier.simplify (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}] |
347 addsimprocs [NominalDatatype.perm_simproc]) |
347 addsimprocs [NominalDatatype.perm_simproc]) |
348 (Simplifier.simplify (put_simpset eqvt_ss ctxt') |
348 (Simplifier.simplify (put_simpset eqvt_ss ctxt') |
349 (fold_rev (mk_perm_bool o cterm_of thy) |
349 (fold_rev (mk_perm_bool o Thm.cterm_of thy) |
350 (rev pis' @ pis) th)); |
350 (rev pis' @ pis) th)); |
351 val (gprems1, gprems2) = split_list |
351 val (gprems1, gprems2) = split_list |
352 (map (fn (th, t) => |
352 (map (fn (th, t) => |
353 if null (preds_of ps t) then (SOME th, mk_pi th) |
353 if null (preds_of ps t) then (SOME th, mk_pi th) |
354 else |
354 else |
358 (inst_conj_all_tac ctxt' (length pis'')) monos (SOME t) th)))) |
358 (inst_conj_all_tac ctxt' (length pis'')) monos (SOME t) th)))) |
359 (gprems ~~ oprems)) |>> map_filter I; |
359 (gprems ~~ oprems)) |>> map_filter I; |
360 val vc_compat_ths' = map (fn th => |
360 val vc_compat_ths' = map (fn th => |
361 let |
361 let |
362 val th' = first_order_mrs gprems1 th; |
362 val th' = first_order_mrs gprems1 th; |
363 val (bop, lhs, rhs) = (case concl_of th' of |
363 val (bop, lhs, rhs) = (case Thm.concl_of th' of |
364 _ $ (fresh $ lhs $ rhs) => |
364 _ $ (fresh $ lhs $ rhs) => |
365 (fn t => fn u => fresh $ t $ u, lhs, rhs) |
365 (fn t => fn u => fresh $ t $ u, lhs, rhs) |
366 | _ $ (_ $ (_ $ lhs $ rhs)) => |
366 | _ $ (_ $ (_ $ lhs $ rhs)) => |
367 (curry (HOLogic.mk_not o HOLogic.mk_eq), lhs, rhs)); |
367 (curry (HOLogic.mk_not o HOLogic.mk_eq), lhs, rhs)); |
368 val th'' = Goal.prove ctxt'' [] [] (HOLogic.mk_Trueprop |
368 val th'' = Goal.prove ctxt'' [] [] (HOLogic.mk_Trueprop |
380 (vc_compat_ths'' @ freshs2'); |
380 (vc_compat_ths'' @ freshs2'); |
381 val th = Goal.prove ctxt'' [] [] |
381 val th = Goal.prove ctxt'' [] [] |
382 (HOLogic.mk_Trueprop (list_comb (P $ hd ts, |
382 (HOLogic.mk_Trueprop (list_comb (P $ hd ts, |
383 map (fold (NominalDatatype.mk_perm []) pis') (tl ts)))) |
383 map (fold (NominalDatatype.mk_perm []) pis') (tl ts)))) |
384 (fn _ => EVERY ([simp_tac (put_simpset eqvt_ss ctxt'') 1, rtac ihyp' 1, |
384 (fn _ => EVERY ([simp_tac (put_simpset eqvt_ss ctxt'') 1, rtac ihyp' 1, |
385 REPEAT_DETERM_N (nprems_of ihyp - length gprems) |
385 REPEAT_DETERM_N (Thm.nprems_of ihyp - length gprems) |
386 (simp_tac swap_simps_simpset 1), |
386 (simp_tac swap_simps_simpset 1), |
387 REPEAT_DETERM_N (length gprems) |
387 REPEAT_DETERM_N (length gprems) |
388 (simp_tac (put_simpset HOL_basic_ss ctxt'' |
388 (simp_tac (put_simpset HOL_basic_ss ctxt'' |
389 addsimps [inductive_forall_def'] |
389 addsimps [inductive_forall_def'] |
390 addsimprocs [NominalDatatype.perm_simproc]) 1 THEN |
390 addsimprocs [NominalDatatype.perm_simproc]) 1 THEN |
391 resolve_tac ctxt'' gprems2 1)])); |
391 resolve_tac ctxt'' gprems2 1)])); |
392 val final = Goal.prove ctxt'' [] [] (term_of concl) |
392 val final = Goal.prove ctxt'' [] [] (Thm.term_of concl) |
393 (fn _ => cut_facts_tac [th] 1 THEN full_simp_tac (put_simpset HOL_ss ctxt'' |
393 (fn _ => cut_facts_tac [th] 1 THEN full_simp_tac (put_simpset HOL_ss ctxt'' |
394 addsimps vc_compat_ths'' @ freshs2' @ |
394 addsimps vc_compat_ths'' @ freshs2' @ |
395 perm_fresh_fresh @ fresh_atm) 1); |
395 perm_fresh_fresh @ fresh_atm) 1); |
396 val final' = Proof_Context.export ctxt'' ctxt' [final]; |
396 val final' = Proof_Context.export ctxt'' ctxt' [final]; |
397 in resolve_tac ctxt' final' 1 end) context 1]) |
397 in resolve_tac ctxt' final' 1 end) context 1]) |
405 |
405 |
406 (** strong case analysis rule **) |
406 (** strong case analysis rule **) |
407 |
407 |
408 val cases_prems = map (fn ((name, avoids), rule) => |
408 val cases_prems = map (fn ((name, avoids), rule) => |
409 let |
409 let |
410 val ([rule'], ctxt') = Variable.import_terms false [prop_of rule] ctxt; |
410 val ([rule'], ctxt') = Variable.import_terms false [Thm.prop_of rule] ctxt; |
411 val prem :: prems = Logic.strip_imp_prems rule'; |
411 val prem :: prems = Logic.strip_imp_prems rule'; |
412 val concl = Logic.strip_imp_concl rule' |
412 val concl = Logic.strip_imp_concl rule' |
413 in |
413 in |
414 (prem, |
414 (prem, |
415 List.drop (snd (strip_comb (HOLogic.dest_Trueprop prem)), length ind_params), |
415 List.drop (snd (strip_comb (HOLogic.dest_Trueprop prem)), length ind_params), |
470 SUBPROOF (fn {prems = case_hyps, params, context = ctxt2, concl, ...} => |
470 SUBPROOF (fn {prems = case_hyps, params, context = ctxt2, concl, ...} => |
471 if null qs then |
471 if null qs then |
472 rtac (first_order_mrs case_hyps case_hyp) 1 |
472 rtac (first_order_mrs case_hyps case_hyp) 1 |
473 else |
473 else |
474 let |
474 let |
475 val params' = map (term_of o #2 o nth (rev params)) is; |
475 val params' = map (Thm.term_of o #2 o nth (rev params)) is; |
476 val tab = params' ~~ map fst qs; |
476 val tab = params' ~~ map fst qs; |
477 val (hyps1, hyps2) = chop (length args) case_hyps; |
477 val (hyps1, hyps2) = chop (length args) case_hyps; |
478 (* turns a = t and [x1 # t, ..., xn # t] *) |
478 (* turns a = t and [x1 # t, ..., xn # t] *) |
479 (* into [x1 # a, ..., xn # a] *) |
479 (* into [x1 # a, ..., xn # a] *) |
480 fun inst_fresh th' ths = |
480 fun inst_fresh th' ths = |
481 let val (ths1, ths2) = chop (length qs) ths |
481 let val (ths1, ths2) = chop (length qs) ths |
482 in |
482 in |
483 (map (fn th => |
483 (map (fn th => |
484 let |
484 let |
485 val (cf, ct) = |
485 val (cf, ct) = |
486 Thm.dest_comb (Thm.dest_arg (cprop_of th)); |
486 Thm.dest_comb (Thm.dest_arg (Thm.cprop_of th)); |
487 val arg_cong' = Drule.instantiate' |
487 val arg_cong' = Drule.instantiate' |
488 [SOME (ctyp_of_term ct)] |
488 [SOME (Thm.ctyp_of_term ct)] |
489 [NONE, SOME ct, SOME cf] (arg_cong RS iffD2); |
489 [NONE, SOME ct, SOME cf] (arg_cong RS iffD2); |
490 val inst = Thm.first_order_match (ct, |
490 val inst = Thm.first_order_match (ct, |
491 Thm.dest_arg (Thm.dest_arg (cprop_of th'))) |
491 Thm.dest_arg (Thm.dest_arg (Thm.cprop_of th'))) |
492 in [th', th] MRS Thm.instantiate inst arg_cong' |
492 in [th', th] MRS Thm.instantiate inst arg_cong' |
493 end) ths1, |
493 end) ths1, |
494 ths2) |
494 ths2) |
495 end; |
495 end; |
496 val (vc_compat_ths1, vc_compat_ths2) = |
496 val (vc_compat_ths1, vc_compat_ths2) = |
503 (obtain_fresh_name (args @ map fst qs @ params')) |
503 (obtain_fresh_name (args @ map fst qs @ params')) |
504 (map snd qs) ([], [], ctxt2); |
504 (map snd qs) ([], [], ctxt2); |
505 val freshs2' = NominalDatatype.mk_not_sym freshs2; |
505 val freshs2' = NominalDatatype.mk_not_sym freshs2; |
506 val pis = map (NominalDatatype.perm_of_pair) |
506 val pis = map (NominalDatatype.perm_of_pair) |
507 ((freshs1 ~~ map fst qs) @ (params' ~~ freshs1)); |
507 ((freshs1 ~~ map fst qs) @ (params' ~~ freshs1)); |
508 val mk_pis = fold_rev mk_perm_bool (map (cterm_of thy) pis); |
508 val mk_pis = fold_rev mk_perm_bool (map (Thm.cterm_of thy) pis); |
509 val obj = cterm_of thy (foldr1 HOLogic.mk_conj (map (map_aterms |
509 val obj = Thm.cterm_of thy (foldr1 HOLogic.mk_conj (map (map_aterms |
510 (fn x as Free _ => |
510 (fn x as Free _ => |
511 if member (op =) args x then x |
511 if member (op =) args x then x |
512 else (case AList.lookup op = tab x of |
512 else (case AList.lookup op = tab x of |
513 SOME y => y |
513 SOME y => y |
514 | NONE => fold_rev (NominalDatatype.mk_perm []) pis x) |
514 | NONE => fold_rev (NominalDatatype.mk_perm []) pis x) |
515 | x => x) o HOLogic.dest_Trueprop o prop_of) case_hyps)); |
515 | x => x) o HOLogic.dest_Trueprop o Thm.prop_of) case_hyps)); |
516 val inst = Thm.first_order_match (Thm.dest_arg |
516 val inst = Thm.first_order_match (Thm.dest_arg |
517 (Drule.strip_imp_concl (hd (cprems_of case_hyp))), obj); |
517 (Drule.strip_imp_concl (hd (cprems_of case_hyp))), obj); |
518 val th = Goal.prove ctxt3 [] [] (term_of concl) |
518 val th = Goal.prove ctxt3 [] [] (Thm.term_of concl) |
519 (fn {context = ctxt4, ...} => |
519 (fn {context = ctxt4, ...} => |
520 rtac (Thm.instantiate inst case_hyp) 1 THEN |
520 rtac (Thm.instantiate inst case_hyp) 1 THEN |
521 SUBPROOF (fn {prems = fresh_hyps, ...} => |
521 SUBPROOF (fn {prems = fresh_hyps, ...} => |
522 let |
522 let |
523 val fresh_hyps' = NominalDatatype.mk_not_sym fresh_hyps; |
523 val fresh_hyps' = NominalDatatype.mk_not_sym fresh_hyps; |
608 | xs => error ("No such atoms: " ^ commas xs); |
608 | xs => error ("No such atoms: " ^ commas xs); |
609 atoms) |
609 atoms) |
610 end; |
610 end; |
611 val perm_pi_simp = Global_Theory.get_thms thy "perm_pi_simp"; |
611 val perm_pi_simp = Global_Theory.get_thms thy "perm_pi_simp"; |
612 val (([t], [pi]), ctxt') = ctxt |> |
612 val (([t], [pi]), ctxt') = ctxt |> |
613 Variable.import_terms false [concl_of raw_induct] ||>> |
613 Variable.import_terms false [Thm.concl_of raw_induct] ||>> |
614 Variable.variant_fixes ["pi"]; |
614 Variable.variant_fixes ["pi"]; |
615 val eqvt_simpset = put_simpset HOL_basic_ss ctxt' addsimps |
615 val eqvt_simpset = put_simpset HOL_basic_ss ctxt' addsimps |
616 (NominalThmDecls.get_eqvt_thms ctxt' @ perm_pi_simp) addsimprocs |
616 (NominalThmDecls.get_eqvt_thms ctxt' @ perm_pi_simp) addsimprocs |
617 [mk_perm_bool_simproc names, |
617 [mk_perm_bool_simproc names, |
618 NominalPermeq.perm_simproc_app, NominalPermeq.perm_simproc_fun]; |
618 NominalPermeq.perm_simproc_app, NominalPermeq.perm_simproc_fun]; |
619 val ps = map (fst o HOLogic.dest_imp) |
619 val ps = map (fst o HOLogic.dest_imp) |
620 (HOLogic.dest_conj (HOLogic.dest_Trueprop t)); |
620 (HOLogic.dest_conj (HOLogic.dest_Trueprop t)); |
621 fun eqvt_tac pi (intr, vs) st = |
621 fun eqvt_tac pi (intr, vs) st = |
622 let |
622 let |
623 fun eqvt_err s = |
623 fun eqvt_err s = |
624 let val ([t], ctxt'') = Variable.import_terms true [prop_of intr] ctxt' |
624 let val ([t], ctxt'') = Variable.import_terms true [Thm.prop_of intr] ctxt' |
625 in error ("Could not prove equivariance for introduction rule\n" ^ |
625 in error ("Could not prove equivariance for introduction rule\n" ^ |
626 Syntax.string_of_term ctxt'' t ^ "\n" ^ s) |
626 Syntax.string_of_term ctxt'' t ^ "\n" ^ s) |
627 end; |
627 end; |
628 val res = SUBPROOF (fn {context = ctxt'', prems, params, ...} => |
628 val res = SUBPROOF (fn {context = ctxt'', prems, params, ...} => |
629 let |
629 let |
630 val prems' = map (fn th => the_default th (map_thm ctxt'' |
630 val prems' = map (fn th => the_default th (map_thm ctxt'' |
631 (split_conj (K I) names) (etac conjunct2 1) monos NONE th)) prems; |
631 (split_conj (K I) names) (etac conjunct2 1) monos NONE th)) prems; |
632 val prems'' = map (fn th => Simplifier.simplify eqvt_simpset |
632 val prems'' = map (fn th => Simplifier.simplify eqvt_simpset |
633 (mk_perm_bool (cterm_of thy pi) th)) prems'; |
633 (mk_perm_bool (Thm.cterm_of thy pi) th)) prems'; |
634 val intr' = Drule.cterm_instantiate (map (cterm_of thy) vs ~~ |
634 val intr' = Drule.cterm_instantiate (map (Thm.cterm_of thy) vs ~~ |
635 map (cterm_of thy o NominalDatatype.mk_perm [] pi o term_of o #2) params) |
635 map (Thm.cterm_of thy o NominalDatatype.mk_perm [] pi o Thm.term_of o #2) params) |
636 intr |
636 intr |
637 in (rtac intr' THEN_ALL_NEW (TRY o resolve_tac ctxt'' prems'')) 1 |
637 in (rtac intr' THEN_ALL_NEW (TRY o resolve_tac ctxt'' prems'')) 1 |
638 end) ctxt' 1 st |
638 end) ctxt' 1 st |
639 in |
639 in |
640 case (Seq.pull res handle THM (s, _, _) => eqvt_err s) of |
640 case (Seq.pull res handle THM (s, _, _) => eqvt_err s) of |
641 NONE => eqvt_err ("Rule does not match goal\n" ^ |
641 NONE => eqvt_err ("Rule does not match goal\n" ^ |
642 Syntax.string_of_term ctxt' (hd (prems_of st))) |
642 Syntax.string_of_term ctxt' (hd (Thm.prems_of st))) |
643 | SOME (th, _) => Seq.single th |
643 | SOME (th, _) => Seq.single th |
644 end; |
644 end; |
645 val thss = map (fn atom => |
645 val thss = map (fn atom => |
646 let val pi' = Free (pi, NominalAtoms.mk_permT (Type (atom, []))) |
646 let val pi' = Free (pi, NominalAtoms.mk_permT (Type (atom, []))) |
647 in map (fn th => zero_var_indexes (th RS mp)) |
647 in map (fn th => zero_var_indexes (th RS mp)) |