src/Pure/Isar/proof.ML
changeset 8617 33e2bd53aec3
parent 8582 3051aa8aa412
child 8670 d69616c74211
equal deleted inserted replaced
8616:90d2fed59be1 8617:33e2bd53aec3
    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 ***)
   503   state
   457   state
   504   |> assert_forward
   458   |> assert_forward
   505   |> map_context (f x)
   459   |> map_context (f x)
   506   |> reset_facts;
   460   |> reset_facts;
   507 
   461 
   508 val match_bind = gen_bind ProofContext.match_bind;
   462 val match_bind = gen_bind (ProofContext.match_bind false);
   509 val match_bind_i = gen_bind ProofContext.match_bind_i;
   463 val match_bind_i = gen_bind (ProofContext.match_bind_i false);
       
   464 val let_bind = gen_bind (ProofContext.match_bind true);
       
   465 val let_bind_i = gen_bind (ProofContext.match_bind_i true);
   510 
   466 
   511 
   467 
   512 (* have_thmss *)
   468 (* have_thmss *)
   513 
   469 
   514 fun have_thmss ths name atts ths_atts state =
   470 fun have_thmss ths name atts ths_atts state =
   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 =