42 type method |
42 type method |
43 val method: (thm list -> tactic) -> method |
43 val method: (thm list -> tactic) -> method |
44 val method_cases: (thm list -> thm -> (thm * (string * RuleCases.T) list) Seq.seq) -> method |
44 val method_cases: (thm list -> thm -> (thm * (string * RuleCases.T) list) Seq.seq) -> method |
45 val refine: (context -> method) -> state -> state Seq.seq |
45 val refine: (context -> method) -> state -> state Seq.seq |
46 val refine_end: (context -> method) -> state -> state Seq.seq |
46 val refine_end: (context -> method) -> state -> state Seq.seq |
47 val find_free: term -> string -> term option |
|
48 val export_thm: context -> thm -> thm |
47 val export_thm: context -> thm -> thm |
49 val match_bind: (string list * string) list -> state -> state |
48 val match_bind: (string list * string) list -> state -> state |
50 val match_bind_i: (term list * term) list -> state -> state |
49 val match_bind_i: (term list * term) list -> state -> state |
|
50 val let_bind: (string list * string) list -> state -> state |
|
51 val let_bind_i: (term list * term) list -> state -> state |
51 val have_thmss: thm list -> string -> context attribute list -> |
52 val have_thmss: thm list -> string -> context attribute list -> |
52 (thm list * context attribute list) list -> state -> state |
53 (thm list * context attribute list) list -> state -> state |
53 val simple_have_thms: string -> thm list -> state -> state |
54 val simple_have_thms: string -> thm list -> state -> state |
54 val fix: (string list * string option) list -> state -> state |
55 val fix: (string list * string option) list -> state -> state |
55 val fix_i: (string list * typ option) list -> state -> state |
56 val fix_i: (string list * typ option) list -> state -> state |
75 val lemma: bstring -> theory attribute list -> string * (string list * string list) |
76 val lemma: bstring -> theory attribute list -> string * (string list * string list) |
76 -> theory -> state |
77 -> theory -> state |
77 val lemma_i: bstring -> theory attribute list -> term * (term list * term list) |
78 val lemma_i: bstring -> theory attribute list -> term * (term list * term list) |
78 -> theory -> state |
79 -> theory -> state |
79 val chain: state -> state |
80 val chain: state -> state |
80 val export_chain: state -> state Seq.seq |
|
81 val from_facts: thm list -> state -> state |
81 val from_facts: thm list -> state -> state |
82 val show: (state -> state Seq.seq) -> string -> context attribute list |
82 val show: (state -> state Seq.seq) -> string -> context attribute list |
83 -> string * (string list * string list) -> state -> state |
83 -> string * (string list * string list) -> state -> state |
84 val show_i: (state -> state Seq.seq) -> string -> context attribute list |
84 val show_i: (state -> state Seq.seq) -> string -> context attribute list |
85 -> term * (term list * term list) -> state -> state |
85 -> term * (term list * term list) -> state -> state |
377 val refine_end = gen_refine false; |
377 val refine_end = gen_refine false; |
378 |
378 |
379 end; |
379 end; |
380 |
380 |
381 |
381 |
382 (* export *) |
|
383 |
|
384 fun get_free x (None, t as Free (y, _)) = if x = y then Some t else None |
|
385 | get_free _ (opt, _) = opt; |
|
386 |
|
387 fun find_free t x = foldl_aterms (get_free x) (None, t); |
|
388 |
|
389 |
|
390 local |
|
391 |
|
392 fun varify_frees fixes thm = |
|
393 let |
|
394 val {sign, prop, ...} = Thm.rep_thm thm; |
|
395 val frees = map (Thm.cterm_of sign) (mapfilter (find_free prop) fixes); |
|
396 in |
|
397 thm |
|
398 |> Drule.forall_intr_list frees |
|
399 |> Drule.forall_elim_vars 0 |
|
400 end; |
|
401 |
|
402 fun export fixes casms thm = |
|
403 thm |
|
404 |> Drule.implies_intr_list casms |
|
405 |> varify_frees fixes |
|
406 |> ProofContext.most_general_varify_tfrees; |
|
407 |
|
408 fun diff_context inner None = (ProofContext.fixed_names inner, ProofContext.assumptions inner) |
|
409 | diff_context inner (Some outer) = |
|
410 (ProofContext.fixed_names inner \\ ProofContext.fixed_names outer, |
|
411 Library.drop (length (ProofContext.assumptions outer), ProofContext.assumptions inner)); |
|
412 |
|
413 in |
|
414 |
|
415 fun export_wrt inner opt_outer = |
|
416 let |
|
417 val (fixes, asms) = diff_context inner opt_outer; |
|
418 val casms = map (Drule.mk_cgoal o #1) asms; |
|
419 val tacs = map #2 asms; |
|
420 in (export fixes casms, tacs) end; |
|
421 |
|
422 end; |
|
423 |
|
424 |
|
425 (* export results *) |
382 (* export results *) |
426 |
383 |
427 fun RANGE [] _ = all_tac |
384 fun RANGE [] _ = all_tac |
428 | RANGE (tac :: tacs) i = RANGE tacs (i + 1) THEN tac i; |
385 | RANGE (tac :: tacs) i = RANGE tacs (i + 1) THEN tac i; |
429 |
386 |
434 fun HEADGOAL tac = tac 1; |
391 fun HEADGOAL tac = tac 1; |
435 |
392 |
436 fun export_goal print_rule raw_rule inner state = |
393 fun export_goal print_rule raw_rule inner state = |
437 let |
394 let |
438 val (outer, (_, ((result, (facts, thm)), f))) = find_goal 0 state; |
395 val (outer, (_, ((result, (facts, thm)), f))) = find_goal 0 state; |
439 val (exp, tacs) = export_wrt inner (Some outer); |
396 val (exp, tacs) = ProofContext.export_wrt inner (Some outer); |
440 val rule = exp raw_rule; |
397 val rule = exp raw_rule; |
441 val _ = print_rule rule; |
398 val _ = print_rule rule; |
442 val thmq = FINDGOAL (Tactic.rtac rule THEN' RANGE (map #1 tacs)) thm; |
399 val thmq = FINDGOAL (Tactic.rtac rule THEN' RANGE (map #1 tacs)) thm; |
443 in Seq.map (fn th => map_goal I (K ((result, (facts, th)), f)) state) thmq end; |
400 in Seq.map (fn th => map_goal I (K ((result, (facts, th)), f)) state) thmq end; |
444 |
401 |
445 |
402 |
446 fun export_thm inner thm = |
403 fun export_thm inner thm = |
447 let val (exp, tacs) = export_wrt inner None in |
404 let val (exp, tacs) = ProofContext.export_wrt inner None in |
448 (case Seq.chop (2, RANGE (map #2 tacs) 1 (exp thm)) of |
405 (case Seq.chop (2, RANGE (map #2 tacs) 1 (exp thm)) of |
449 ([thm'], _) => thm' |
406 ([thm'], _) => thm' |
450 | ([], _) => raise THM ("export: failed", 0, [thm]) |
407 | ([], _) => raise THM ("export: failed", 0, [thm]) |
451 | _ => raise THM ("export: more than one result", 0, [thm])) |
408 | _ => raise THM ("export: more than one result", 0, [thm])) |
452 end; |
409 end; |
453 |
410 |
454 |
|
455 fun export_facts inner_state opt_outer_state state = |
|
456 let |
|
457 val thms = the_facts inner_state; |
|
458 val (exp, tacs) = export_wrt (context_of inner_state) (apsome context_of opt_outer_state); |
|
459 val thmqs = map (RANGE (map #2 tacs) 1 o exp) thms; |
|
460 in Seq.map (fn ths => put_facts (Some ths) state) (Seq.commute thmqs) end; |
|
461 |
|
462 fun transfer_facts inner_state state = |
411 fun transfer_facts inner_state state = |
463 (case get_facts inner_state of |
412 (case get_facts inner_state of |
464 None => Seq.single (reset_facts state) |
413 None => Seq.single (reset_facts state) |
465 | Some ths => export_facts inner_state (Some state) state); |
414 | Some thms => |
|
415 let |
|
416 val (exp, tacs) = |
|
417 ProofContext.export_wrt (context_of inner_state) (Some (context_of state)); |
|
418 val thmqs = map (RANGE (map #2 tacs) 1 o exp) thms; |
|
419 in Seq.map (fn ths => put_facts (Some ths) state) (Seq.commute thmqs) end); |
466 |
420 |
467 |
421 |
468 (* prepare result *) |
422 (* prepare result *) |
469 |
423 |
470 fun prep_result state t raw_thm = |
424 fun prep_result state t raw_thm = |
476 val _ = |
430 val _ = |
477 if ngoals = 0 then () |
431 if ngoals = 0 then () |
478 else (Locale.print_goals ngoals raw_thm; err (string_of_int ngoals ^ " unsolved goal(s)!")); |
432 else (Locale.print_goals ngoals raw_thm; err (string_of_int ngoals ^ " unsolved goal(s)!")); |
479 |
433 |
480 val thm = raw_thm RS Drule.rev_triv_goal; |
434 val thm = raw_thm RS Drule.rev_triv_goal; |
481 val {hyps, prop, sign, maxidx, ...} = Thm.rep_thm thm; |
435 val {hyps, prop, sign, ...} = Thm.rep_thm thm; |
482 val tsig = Sign.tsig_of sign; |
436 val tsig = Sign.tsig_of sign; |
483 |
437 |
484 val casms = map #1 (assumptions state); |
438 val casms = map #1 (assumptions state); |
485 val bad_hyps = Library.gen_rems Term.aconv (hyps, map (Thm.term_of o Drule.mk_cgoal) casms); |
439 val bad_hyps = Library.gen_rems Term.aconv (hyps, map (Thm.term_of o Drule.mk_cgoal) casms); |
486 in |
440 in |
487 if not (null bad_hyps) then |
441 if not (null bad_hyps) then |
488 err ("Additional hypotheses:\n" ^ cat_lines (map (Sign.string_of_term sign) bad_hyps)) |
442 err ("Additional hypotheses:\n" ^ cat_lines (map (Sign.string_of_term sign) bad_hyps)) |
489 else if not (t aconv prop) then |
443 else if not (t aconv prop) then |
490 err ("Proved a different theorem: " ^ Sign.string_of_term sign prop) |
444 err ("Proved a different theorem: " ^ Sign.string_of_term sign prop) |
491 else thm |> Drule.forall_elim_vars (maxidx + 1) |> ProofContext.most_general_varify_tfrees |
445 else thm |
492 end; |
446 end; |
493 |
447 |
494 |
448 |
495 |
449 |
496 (*** structured proof commands ***) |
450 (*** structured proof commands ***) |
545 |> put_thms ("prems", prems) |
501 |> put_thms ("prems", prems) |
546 |> put_facts (Some (flat (map #2 factss)))); |
502 |> put_facts (Some (flat (map #2 factss)))); |
547 |
503 |
548 val hard_asm_tac = Tactic.etac Drule.triv_goal; |
504 val hard_asm_tac = Tactic.etac Drule.triv_goal; |
549 val soft_asm_tac = Tactic.rtac Drule.triv_goal |
505 val soft_asm_tac = Tactic.rtac Drule.triv_goal |
550 THEN' Tactic.rtac asm_rl; (* FIXME hack to norm goal *) |
506 THEN' Tactic.rtac asm_rl; (* FIXME hack to norm goal *) |
551 |
507 |
552 in |
508 in |
553 |
509 |
554 val assm = gen_assume ProofContext.assume; |
510 val assm = gen_assume ProofContext.assume; |
555 val assm_i = gen_assume ProofContext.assume_i; |
511 val assm_i = gen_assume ProofContext.assume_i; |
580 state |
536 state |
581 |> assert_forward |
537 |> assert_forward |
582 |> assert_facts |
538 |> assert_facts |
583 |> enter_forward_chain; |
539 |> enter_forward_chain; |
584 |
540 |
585 fun export_chain state = |
|
586 state |
|
587 |> assert_forward |
|
588 |> export_facts state None |
|
589 |> Seq.map chain; |
|
590 |
|
591 fun from_facts facts state = |
541 fun from_facts facts state = |
592 state |
542 state |
593 |> put_facts (Some facts) |
543 |> put_facts (Some facts) |
594 |> chain; |
544 |> chain; |
595 |
545 |
596 |
546 |
597 (* setup goals *) |
547 (* setup goals *) |
598 |
548 |
599 fun setup_goal opt_block prepp kind after_qed name atts raw_propp state = |
549 fun setup_goal opt_block prepp kind after_qed name atts raw_propp state = |
600 let |
550 let |
601 val (state', prop) = |
551 val (state', (prop, gen_binds)) = |
602 state |
552 state |
603 |> assert_forward_or_chain |
553 |> assert_forward_or_chain |
604 |> enter_forward |
554 |> enter_forward |
|
555 |> opt_block |
605 |> map_context_result (fn ct => prepp (ct, raw_propp)); |
556 |> map_context_result (fn ct => prepp (ct, raw_propp)); |
606 val cprop = Thm.cterm_of (sign_of state') prop; |
557 val cprop = Thm.cterm_of (sign_of state') prop; |
607 val goal = Drule.mk_triv_goal cprop; |
558 val goal = Drule.mk_triv_goal cprop; |
608 in |
559 in |
609 state' |
560 state' |
610 |> opt_block |
561 |> put_goal (Some (((kind atts, name, prop), ([], goal)), after_qed o map_context gen_binds)) |
611 |> put_goal (Some (((kind atts, name, prop), ([], goal)), after_qed)) |
|
612 |> auto_bind_goal prop |
562 |> auto_bind_goal prop |
613 |> (if is_chain state then use_facts else reset_facts) |
563 |> (if is_chain state then use_facts else reset_facts) |
614 |> new_block |
564 |> new_block |
615 |> enter_backward |
565 |> enter_backward |
616 end; |
566 end; |
671 |
621 |
672 (* local_qed *) |
622 (* local_qed *) |
673 |
623 |
674 fun finish_local (print_result, print_rule) state = |
624 fun finish_local (print_result, print_rule) state = |
675 let |
625 let |
676 val (ctxt, (((kind, name, t), (_, raw_thm)), after_qed)) = current_goal state; |
626 val (goal_ctxt, (((kind, name, t), (_, raw_thm)), after_qed)) = current_goal state; |
|
627 val outer_state = state |> close_block; |
|
628 val outer_ctxt = context_of outer_state; |
|
629 |
677 val result = prep_result state t raw_thm; |
630 val result = prep_result state t raw_thm; |
678 val (atts, opt_solve) = |
631 val (atts, opt_solve) = |
679 (case kind of |
632 (case kind of |
680 Goal atts => (atts, export_goal print_rule result ctxt) |
633 Goal atts => (atts, export_goal print_rule result goal_ctxt) |
681 | Aux atts => (atts, Seq.single) |
634 | Aux atts => (atts, Seq.single) |
682 | _ => err_malformed "finish_local" state); |
635 | _ => err_malformed "finish_local" state); |
683 in |
636 in |
684 print_result {kind = kind_name kind, name = name, thm = result}; |
637 print_result {kind = kind_name kind, name = name, thm = result}; |
685 state |
638 outer_state |
686 |> close_block |
639 |> auto_bind_facts name [ProofContext.generalize goal_ctxt outer_ctxt t] |
687 |> auto_bind_facts name [t] |
640 |> have_thmss [] name atts [Thm.no_attributes |
688 |> have_thmss [] name atts [Thm.no_attributes [result]] |
641 [#1 (ProofContext.export_wrt goal_ctxt (Some outer_ctxt)) result]] |
689 |> opt_solve |
642 |> opt_solve |
690 |> (Seq.flat o Seq.map after_qed) |
643 |> (Seq.flat o Seq.map after_qed) |
691 end; |
644 end; |
692 |
645 |
693 fun local_qed finalize print state = |
646 fun local_qed finalize print state = |