221 val ([p], ctxt') = ctxt |
221 val ([p], ctxt') = ctxt |
222 |> fold Variable.declare_term args |
222 |> fold Variable.declare_term args |
223 |> Variable.variant_fixes ["p"] |
223 |> Variable.variant_fixes ["p"] |
224 val p = Free (p, @{typ perm}) |
224 val p = Free (p, @{typ perm}) |
225 |
225 |
226 val ss = HOL_basic_ss addsimps |
226 val simpset = |
|
227 put_simpset HOL_basic_ss ctxt' addsimps |
227 @{thms permute_sum.simps[symmetric] Pair_eqvt[symmetric]} @ |
228 @{thms permute_sum.simps[symmetric] Pair_eqvt[symmetric]} @ |
228 @{thms Projr.simps Projl.simps} @ |
229 @{thms Projr.simps Projl.simps} @ |
229 [(cond MRS eqvt_thm) RS @{thm sym}] @ |
230 [(cond MRS eqvt_thm) RS @{thm sym}] @ |
230 [inl_perm, inr_perm, simp] |
231 [inl_perm, inr_perm, simp] |
231 val goal_lhs = mk_perm p (list_comb (f, args)) |
232 val goal_lhs = mk_perm p (list_comb (f, args)) |
232 val goal_rhs = list_comb (f, map (mk_perm p) args) |
233 val goal_rhs = list_comb (f, map (mk_perm p) args) |
233 in |
234 in |
234 Goal.prove ctxt' [] [] (HOLogic.Trueprop $ HOLogic.mk_eq (goal_lhs, goal_rhs)) |
235 Goal.prove ctxt' [] [] (HOLogic.Trueprop $ HOLogic.mk_eq (goal_lhs, goal_rhs)) |
235 (fn _ => (Local_Defs.unfold_tac ctxt all_orig_fdefs) |
236 (fn _ => (Local_Defs.unfold_tac ctxt all_orig_fdefs) |
236 THEN (asm_full_simp_tac ss 1)) |
237 THEN (asm_full_simp_tac simpset 1)) |
237 |> singleton (Proof_Context.export ctxt' ctxt) |
238 |> singleton (Proof_Context.export ctxt' ctxt) |
238 |> restore_cond |
239 |> restore_cond |
239 |> export |
240 |> export |
240 end |
241 end |
241 |
242 |
248 |> Conv.fconv_rule (Thm.beta_conversion true) |
249 |> Conv.fconv_rule (Thm.beta_conversion true) |
249 |> fold_rev Thm.forall_intr xs |
250 |> fold_rev Thm.forall_intr xs |
250 |> Thm.forall_elim_vars 0 |
251 |> Thm.forall_elim_vars 0 |
251 end |
252 end |
252 |
253 |
253 fun mutual_induct_rules lthy induct all_f_defs (Mutual {n, ST, parts, ...}) = |
254 fun mutual_induct_rules ctxt induct all_f_defs (Mutual {n, ST, parts, ...}) = |
254 let |
255 let |
255 val cert = cterm_of (Proof_Context.theory_of lthy) |
256 val cert = cterm_of (Proof_Context.theory_of ctxt) |
256 val newPs = |
257 val newPs = |
257 map2 (fn Pname => fn MutualPart {cargTs, ...} => |
258 map2 (fn Pname => fn MutualPart {cargTs, ...} => |
258 Free (Pname, cargTs ---> HOLogic.boolT)) |
259 Free (Pname, cargTs ---> HOLogic.boolT)) |
259 (mutual_induct_Pnames (length parts)) parts |
260 (mutual_induct_Pnames (length parts)) parts |
260 |
261 |
269 val Ps = map2 mk_P parts newPs |
270 val Ps = map2 mk_P parts newPs |
270 val case_exp = SumTree.mk_sumcases HOLogic.boolT Ps |
271 val case_exp = SumTree.mk_sumcases HOLogic.boolT Ps |
271 |
272 |
272 val induct_inst = |
273 val induct_inst = |
273 Thm.forall_elim (cert case_exp) induct |
274 Thm.forall_elim (cert case_exp) induct |
274 |> full_simplify SumTree.sumcase_split_ss |
275 |> full_simplify (put_simpset SumTree.sumcase_split_ss ctxt) |
275 |> full_simplify (HOL_basic_ss addsimps all_f_defs) |
276 |> full_simplify (put_simpset HOL_basic_ss ctxt addsimps all_f_defs) |
276 |
277 |
277 fun project rule (MutualPart {cargTs, i, ...}) k = |
278 fun project rule (MutualPart {cargTs, i, ...}) k = |
278 let |
279 let |
279 val afs = map_index (fn (j,T) => Free ("a" ^ string_of_int (j + k), T)) cargTs (* FIXME! *) |
280 val afs = map_index (fn (j,T) => Free ("a" ^ string_of_int (j + k), T)) cargTs (* FIXME! *) |
280 val inj = SumTree.mk_inj ST n i (foldr1 HOLogic.mk_prod afs) |
281 val inj = SumTree.mk_inj ST n i (foldr1 HOLogic.mk_prod afs) |
281 in |
282 in |
282 (rule |
283 (rule |
283 |> Thm.forall_elim (cert inj) |
284 |> Thm.forall_elim (cert inj) |
284 |> full_simplify SumTree.sumcase_split_ss |
285 |> full_simplify (put_simpset SumTree.sumcase_split_ss ctxt) |
285 |> fold_rev (Thm.forall_intr o cert) (afs @ newPs), |
286 |> fold_rev (Thm.forall_intr o cert) (afs @ newPs), |
286 k + length cargTs) |
287 k + length cargTs) |
287 end |
288 end |
288 in |
289 in |
289 fst (fold_map (project induct_inst) parts 0) |
290 fst (fold_map (project induct_inst) parts 0) |
348 |> singleton (Proof_Context.export ctxt' ctxt) |
349 |> singleton (Proof_Context.export ctxt' ctxt) |
349 |> split_conj_thm |
350 |> split_conj_thm |
350 |> map (fn th => th RS mp) |
351 |> map (fn th => th RS mp) |
351 end |
352 end |
352 |
353 |
353 fun mk_partial_rules_mutual lthy inner_cont (m as Mutual {parts, fqgars, ...}) proof = |
354 fun mk_partial_rules_mutual ctxt inner_cont (m as Mutual {parts, fqgars, ...}) proof = |
354 let |
355 let |
355 val result = inner_cont proof |
356 val result = inner_cont proof |
356 |
357 |
357 val NominalFunctionResult {G, R, cases, psimps, simple_pinducts=[simple_pinduct], |
358 val NominalFunctionResult {G, R, cases, psimps, simple_pinducts=[simple_pinduct], |
358 termination, domintros, eqvts=[eqvt],...} = result |
359 termination, domintros, eqvts=[eqvt],...} = result |
359 |
360 |
360 val (all_f_defs, fs) = |
361 val (all_f_defs, fs) = |
361 map (fn MutualPart {f_defthm = SOME f_def, f = SOME f, cargTs, ...} => |
362 map (fn MutualPart {f_defthm = SOME f_def, f = SOME f, cargTs, ...} => |
362 (mk_applied_form lthy cargTs (Thm.symmetric f_def), f)) |
363 (mk_applied_form ctxt cargTs (Thm.symmetric f_def), f)) |
363 parts |
364 parts |
364 |> split_list |
365 |> split_list |
365 |
366 |
366 val all_orig_fdefs = |
367 val all_orig_fdefs = |
367 map (fn MutualPart {f_defthm = SOME f_def, ...} => f_def) parts |
368 map (fn MutualPart {f_defthm = SOME f_def, ...} => f_def) parts |
368 |
369 |
369 val cargTss = |
370 val cargTss = |
370 map (fn MutualPart {f = SOME f, cargTs, ...} => cargTs) parts |
371 map (fn MutualPart {f = SOME f, cargTs, ...} => cargTs) parts |
371 |
372 |
372 fun mk_mpsimp fqgar sum_psimp = |
373 fun mk_mpsimp fqgar sum_psimp = |
373 in_context lthy fqgar (recover_mutual_psimp all_orig_fdefs parts) sum_psimp |
374 in_context ctxt fqgar (recover_mutual_psimp all_orig_fdefs parts) sum_psimp |
374 |
375 |
375 fun mk_meqvts fqgar sum_psimp = |
376 fun mk_meqvts fqgar sum_psimp = |
376 in_context lthy fqgar (recover_mutual_eqvt eqvt all_orig_fdefs parts) sum_psimp |
377 in_context ctxt fqgar (recover_mutual_eqvt eqvt all_orig_fdefs parts) sum_psimp |
377 |
378 |
378 val rew_ss = HOL_basic_ss addsimps all_f_defs |
379 val rew_simpset = put_simpset HOL_basic_ss ctxt addsimps all_f_defs |
379 val mpsimps = map2 mk_mpsimp fqgars psimps |
380 val mpsimps = map2 mk_mpsimp fqgars psimps |
380 val minducts = mutual_induct_rules lthy simple_pinduct all_f_defs m |
381 val minducts = mutual_induct_rules ctxt simple_pinduct all_f_defs m |
381 val mtermination = full_simplify rew_ss termination |
382 val mtermination = full_simplify rew_simpset termination |
382 val mdomintros = Option.map (map (full_simplify rew_ss)) domintros |
383 val mdomintros = Option.map (map (full_simplify rew_simpset)) domintros |
383 val meqvts = map2 mk_meqvts fqgars psimps |
384 val meqvts = map2 mk_meqvts fqgars psimps |
384 val meqvt_funs = prove_eqvt lthy fs cargTss meqvts minducts |
385 val meqvt_funs = prove_eqvt ctxt fs cargTss meqvts minducts |
385 in |
386 in |
386 NominalFunctionResult { fs=fs, G=G, R=R, |
387 NominalFunctionResult { fs=fs, G=G, R=R, |
387 psimps=mpsimps, simple_pinducts=minducts, |
388 psimps=mpsimps, simple_pinducts=minducts, |
388 cases=cases, termination=mtermination, |
389 cases=cases, termination=mtermination, |
389 domintros=mdomintros, eqvts=meqvt_funs } |
390 domintros=mdomintros, eqvts=meqvt_funs } |
470 |> all x |> all y |
471 |> all x |> all y |
471 val goal_iff2 = Logic.mk_implies (G_prem, G_aux_prem) |
472 val goal_iff2 = Logic.mk_implies (G_prem, G_aux_prem) |
472 |> all x |> all y |
473 |> all x |> all y |
473 |
474 |
474 val simp_thms = @{thms Projl.simps Projr.simps sum.inject sum.cases sum.distinct o_apply} |
475 val simp_thms = @{thms Projl.simps Projr.simps sum.inject sum.cases sum.distinct o_apply} |
475 val ss0 = HOL_basic_ss addsimps simp_thms |
476 val simpset0 = put_simpset HOL_basic_ss lthy''' addsimps simp_thms |
476 val ss1 = HOL_ss addsimps simp_thms |
477 val simpset1 = put_simpset HOL_ss lthy''' addsimps simp_thms |
477 |
478 |
478 val inj_thm = Goal.prove lthy''' [] [] goal_inj |
479 val inj_thm = Goal.prove lthy''' [] [] goal_inj |
479 (K (HEADGOAL (DETERM o etac G_aux_induct THEN_ALL_NEW asm_simp_tac ss1))) |
480 (K (HEADGOAL (DETERM o etac G_aux_induct THEN_ALL_NEW asm_simp_tac simpset1))) |
480 |
481 |
481 fun aux_tac thm = |
482 fun aux_tac thm = |
482 rtac (Drule.gen_all thm) THEN_ALL_NEW (asm_full_simp_tac (ss1 addsimps [inj_thm])) |
483 rtac (Drule.gen_all thm) THEN_ALL_NEW (asm_full_simp_tac (simpset1 addsimps [inj_thm])) |
483 |
484 |
484 val iff1_thm = Goal.prove lthy''' [] [] goal_iff1 |
485 val iff1_thm = Goal.prove lthy''' [] [] goal_iff1 |
485 (K (HEADGOAL (DETERM o etac G_aux_induct THEN' RANGE (map aux_tac GIntro_thms)))) |
486 (K (HEADGOAL (DETERM o etac G_aux_induct THEN' RANGE (map aux_tac GIntro_thms)))) |
486 |> Drule.gen_all |
487 |> Drule.gen_all |
487 val iff2_thm = Goal.prove lthy''' [] [] goal_iff2 |
488 val iff2_thm = Goal.prove lthy''' [] [] goal_iff2 |
488 (K (HEADGOAL (DETERM o etac G_induct THEN' RANGE (map (aux_tac o simplify ss0) GIntro_aux_thms)))) |
489 (K (HEADGOAL (DETERM o etac G_induct THEN' RANGE |
|
490 (map (aux_tac o simplify simpset0) GIntro_aux_thms)))) |
489 |> Drule.gen_all |
491 |> Drule.gen_all |
490 |
492 |
491 val iff_thm = Goal.prove lthy''' [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (G, G_aux))) |
493 val iff_thm = Goal.prove lthy''' [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (G, G_aux))) |
492 (K (HEADGOAL (EVERY' ((map rtac @{thms ext ext iffI}) @ [etac iff2_thm, etac iff1_thm])))) |
494 (K (HEADGOAL (EVERY' ((map rtac @{thms ext ext iffI}) @ [etac iff2_thm, etac iff1_thm])))) |
493 |
495 |
494 val tac = HEADGOAL (simp_tac (HOL_basic_ss addsimps [iff_thm])) |
496 val tac = HEADGOAL (simp_tac (put_simpset HOL_basic_ss lthy''' addsimps [iff_thm])) |
495 val goalstate' = |
497 val goalstate' = |
496 case (SINGLE tac) goalstate of |
498 case (SINGLE tac) goalstate of |
497 NONE => error "auxiliary equivalence proof failed" |
499 NONE => error "auxiliary equivalence proof failed" |
498 | SOME st => st |
500 | SOME st => st |
499 in |
501 in |