12 struct |
12 struct |
13 |
13 |
14 open Quotient_Info; |
14 open Quotient_Info; |
15 open Quotient_Term; |
15 open Quotient_Term; |
16 |
16 |
|
17 (* various helper fuctions *) |
|
18 |
17 (* Since HOL_basic_ss is too "big" for us, we *) |
19 (* Since HOL_basic_ss is too "big" for us, we *) |
18 (* need to set up our own minimal simpset. *) |
20 (* need to set up our own minimal simpset. *) |
19 fun mk_minimal_ss ctxt = |
21 fun mk_minimal_ss ctxt = |
20 Simplifier.context ctxt empty_ss |
22 Simplifier.context ctxt empty_ss |
21 setsubgoaler asm_simp_tac |
23 setsubgoaler asm_simp_tac |
22 setmksimps (mksimps []) |
24 setmksimps (mksimps []) |
23 |
25 |
24 (* various helper fuctions *) |
|
25 |
|
26 (* composition of two theorems, used in maps *) |
26 (* composition of two theorems, used in maps *) |
27 fun OF1 thm1 thm2 = thm2 RS thm1 |
27 fun OF1 thm1 thm2 = thm2 RS thm1 |
28 |
28 |
29 (* makes sure a subgoal is solved *) |
29 (* makes sure a subgoal is solved *) |
30 fun SOLVES' tac = tac THEN_ALL_NEW (K no_tac) |
30 fun SOLVES' tac = tac THEN_ALL_NEW (K no_tac) |
31 |
31 |
32 (* prints warning, if the subgoal is unsolved *) |
32 (* prints a warning, if the subgoal is not solved *) |
33 fun WARN (tac, msg) i st = |
33 fun WARN (tac, msg) i st = |
34 case Seq.pull ((SOLVES' tac) i st) of |
34 case Seq.pull ((SOLVES' tac) i st) of |
35 NONE => (warning msg; Seq.single st) |
35 NONE => (warning msg; Seq.single st) |
36 | seqcell => Seq.make (fn () => seqcell) |
36 | seqcell => Seq.make (fn () => seqcell) |
37 |
37 |
38 fun RANGE_WARN xs = RANGE (map WARN xs) |
38 fun RANGE_WARN tacs = RANGE (map WARN tacs) |
39 |
39 |
40 fun atomize_thm thm = |
40 fun atomize_thm thm = |
41 let |
41 let |
42 val thm' = Thm.freezeT (forall_intr_vars thm) |
42 val thm' = Thm.freezeT (forall_intr_vars thm) (* TODO: is this proper Isar-technology? *) |
43 val thm'' = ObjectLogic.atomize (cprop_of thm') |
43 val thm'' = ObjectLogic.atomize (cprop_of thm') |
44 in |
44 in |
45 @{thm equal_elim_rule1} OF [thm'', thm'] |
45 @{thm equal_elim_rule1} OF [thm'', thm'] |
46 end |
46 end |
47 |
47 |
49 (*********************) |
49 (*********************) |
50 (* Regularize Tactic *) |
50 (* Regularize Tactic *) |
51 (*********************) |
51 (*********************) |
52 |
52 |
53 (* solvers for equivp and quotient assumptions *) |
53 (* solvers for equivp and quotient assumptions *) |
54 fun equiv_tac ctxt = |
54 (* FIXME / TODO: should this SOLVES' the goal, like with quotient_tac? *) |
|
55 (* FIXME / TODO: none of te examples break if added *) |
|
56 fun equiv_tac ctxt = |
55 REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt)) |
57 REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt)) |
56 |
58 |
57 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss) |
59 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss) |
58 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac |
60 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac |
59 |
61 |
60 (* test whether DETERM makes any difference *) |
62 (* FIXME / TODO: test whether DETERM makes any runtime-difference *) |
|
63 (* FIXME / TODO: reason: it might back-track over the two alternatives in FIRST' *) |
61 fun quotient_tac ctxt = SOLVES' |
64 fun quotient_tac ctxt = SOLVES' |
62 (REPEAT_ALL_NEW (FIRST' |
65 (REPEAT_ALL_NEW (FIRST' |
63 [rtac @{thm identity_quotient}, |
66 [rtac @{thm identity_quotient}, |
64 resolve_tac (quotient_rules_get ctxt)])) |
67 resolve_tac (quotient_rules_get ctxt)])) |
65 |
68 |
67 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
70 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |
68 |
71 |
69 fun solve_quotient_assm ctxt thm = |
72 fun solve_quotient_assm ctxt thm = |
70 case Seq.pull (quotient_tac ctxt 1 thm) of |
73 case Seq.pull (quotient_tac ctxt 1 thm) of |
71 SOME (t, _) => t |
74 SOME (t, _) => t |
72 | _ => error "solve_quotient_assm failed. Maybe a quotient_thm is missing" |
75 | _ => error "Solve_quotient_assm failed. Possibly a quotient theorem is missing." |
73 |
76 |
74 |
77 |
75 fun prep_trm thy (x, (T, t)) = |
78 fun prep_trm thy (x, (T, t)) = |
76 (cterm_of thy (Var (x, T)), cterm_of thy t) |
79 (cterm_of thy (Var (x, T)), cterm_of thy t) |
77 |
80 |
264 val thm = Drule.instantiate' |
267 val thm = Drule.instantiate' |
265 [SOME (ctyp_of thy ty)] [SOME (cterm_of thy R)] @{thm equals_rsp} |
268 [SOME (ctyp_of thy ty)] [SOME (cterm_of thy R)] @{thm equals_rsp} |
266 in |
269 in |
267 rtac thm THEN' quotient_tac ctxt |
270 rtac thm THEN' quotient_tac ctxt |
268 end |
271 end |
269 (* Are they raised by instantiate'? *) |
272 (* TODO: Are they raised by instantiate'? *) |
|
273 (* TODO: Again, can one specify more concretely when no_tac should be returned? *) |
270 handle THM _ => K no_tac |
274 handle THM _ => K no_tac |
271 | TYPE _ => K no_tac |
275 | TYPE _ => K no_tac |
272 | TERM _ => K no_tac |
276 | TERM _ => K no_tac |
273 |
277 |
274 |
278 |
283 val t_inst = map (SOME o (cterm_of thy)) [rel, abs, rep]; |
287 val t_inst = map (SOME o (cterm_of thy)) [rel, abs, rep]; |
284 val inst_thm = Drule.instantiate' ty_inst t_inst @{thm rep_abs_rsp} |
288 val inst_thm = Drule.instantiate' ty_inst t_inst @{thm rep_abs_rsp} |
285 in |
289 in |
286 (rtac inst_thm THEN' quotient_tac ctxt) i |
290 (rtac inst_thm THEN' quotient_tac ctxt) i |
287 end |
291 end |
288 handle THM _ => no_tac | TYPE _ => no_tac) |
292 handle THM _ => no_tac | TYPE _ => no_tac) (* TODO: same here *) |
289 | _ => no_tac) |
293 | _ => no_tac) |
290 |
294 |
291 |
295 |
292 (* FIXME /TODO needs to be adapted *) |
296 (* FIXME / TODO needs to be adapted *) |
293 (* |
297 (* |
294 To prove that the regularised theorem implies the abs/rep injected, |
298 To prove that the regularised theorem implies the abs/rep injected, |
295 we try: |
299 we try: |
296 |
300 |
297 1) theorems 'trans2' from the appropriate Quot_Type |
301 1) theorems 'trans2' from the appropriate Quot_Type |
406 |
410 |
407 (***************************) |
411 (***************************) |
408 (* Cleaning of the Theorem *) |
412 (* Cleaning of the Theorem *) |
409 (***************************) |
413 (***************************) |
410 |
414 |
411 (* expands all fun_maps, except in front of bound variables *) |
415 (* expands all fun_maps, except in front of the bound *) |
|
416 (* variables listed in xs *) |
412 fun fun_map_simple_conv xs ctrm = |
417 fun fun_map_simple_conv xs ctrm = |
413 case (term_of ctrm) of |
418 case (term_of ctrm) of |
414 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
419 ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) => |
415 if (member (op=) xs h) |
420 if (member (op=) xs h) |
416 then Conv.all_conv ctrm |
421 then Conv.all_conv ctrm |
475 else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm) |
480 else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm) |
476 val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts |
481 val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts |
477 in |
482 in |
478 Conv.rewr_conv ti ctrm |
483 Conv.rewr_conv ti ctrm |
479 end |
484 end |
480 handle _ => Conv.all_conv ctrm) |
485 handle _ => Conv.all_conv ctrm) (* TODO: another catch all - can this be improved? *) |
481 | _ => Conv.all_conv ctrm |
486 | _ => Conv.all_conv ctrm |
482 |
487 |
483 |
488 |
484 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
489 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt |
485 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
490 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt) |
502 (* *) |
507 (* *) |
503 (* 5. test for refl *) |
508 (* 5. test for refl *) |
504 |
509 |
505 fun clean_tac_aux lthy = |
510 fun clean_tac_aux lthy = |
506 let |
511 let |
507 (*FIXME produce defs with lthy, like prs and ids *) |
512 (* FIXME/TODO produce defs with lthy, like prs and ids *) |
508 val thy = ProofContext.theory_of lthy; |
513 val thy = ProofContext.theory_of lthy; |
509 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
514 val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy) |
510 (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) |
515 (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) |
511 val prs = prs_rules_get lthy |
516 val prs = prs_rules_get lthy |
512 val ids = id_simps_get lthy |
517 val ids = id_simps_get lthy |
513 |
518 |
514 fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver |
519 fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver |
515 val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs}) |
520 val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs}) |
568 (* - 2nd prem is the rep/abs injection step *) |
573 (* - 2nd prem is the rep/abs injection step *) |
569 (* - 3rd prem is the cleaning part *) |
574 (* - 3rd prem is the cleaning part *) |
570 (* *) |
575 (* *) |
571 (* the Quot_True premise in 2 records the lifted theorem *) |
576 (* the Quot_True premise in 2 records the lifted theorem *) |
572 |
577 |
573 val lifting_procedure = |
578 val lifting_procedure_thm = |
574 @{lemma "[|A; |
579 @{lemma "[|A; |
575 A --> B; |
580 A --> B; |
576 Quot_True D ==> B = C; |
581 Quot_True D ==> B = C; |
577 C = D|] ==> D" |
582 C = D|] ==> D" |
578 by (simp add: Quot_True_def)} |
583 by (simp add: Quot_True_def)} |
599 in |
604 in |
600 Drule.instantiate' [] |
605 Drule.instantiate' [] |
601 [SOME (cterm_of thy rtrm'), |
606 [SOME (cterm_of thy rtrm'), |
602 SOME (cterm_of thy reg_goal), |
607 SOME (cterm_of thy reg_goal), |
603 NONE, |
608 NONE, |
604 SOME (cterm_of thy inj_goal)] lifting_procedure |
609 SOME (cterm_of thy inj_goal)] lifting_procedure_thm |
605 end |
610 end |
606 |
|
607 |
611 |
608 (* the tactic leaves three subgoals to be proved *) |
612 (* the tactic leaves three subgoals to be proved *) |
609 fun procedure_tac ctxt rthm = |
613 fun procedure_tac ctxt rthm = |
610 ObjectLogic.full_atomize_tac |
614 ObjectLogic.full_atomize_tac |
611 THEN' gen_frees_tac ctxt |
615 THEN' gen_frees_tac ctxt |