src/HOL/Tools/Sledgehammer/sledgehammer_reconstruct.ML
changeset 51179 0d5f8812856f
parent 51178 06689dbfe072
child 51187 c344cf148e8f
equal deleted inserted replaced
51178:06689dbfe072 51179:0d5f8812856f
   455      else
   455      else
   456        map (replace_dependencies_in_line (name, deps)) lines)  (* drop line *)
   456        map (replace_dependencies_in_line (name, deps)) lines)  (* drop line *)
   457 
   457 
   458 val indent_size = 2
   458 val indent_size = 2
   459 
   459 
   460 fun string_for_proof ctxt type_enc lam_trans i n =
   460 fun string_for_proof ctxt type_enc lam_trans i n proof =
   461   let
   461   let
   462     fun maybe_show qs = if member (op =) qs Show then "show" else "have"
   462     val register_fixes = map Free #> fold Variable.auto_fixes
       
   463     fun add_suffix suffix (s, ctxt) = (s ^ suffix, ctxt)
   463     fun of_indent ind = replicate_string (ind * indent_size) " "
   464     fun of_indent ind = replicate_string (ind * indent_size) " "
   464     fun of_free (s, T) =
   465     fun of_moreover ind = of_indent ind ^ "moreover\n"
   465       maybe_quote s ^ " :: " ^
       
   466       maybe_quote (simplify_spaces (with_vanilla_print_mode
       
   467         (Syntax.string_of_typ ctxt) T))
       
   468     val of_frees = space_implode " and " o map of_free
       
   469     fun maybe_moreover ind qs nr_subproofs =
       
   470         if member (op =) qs Then andalso nr_subproofs > 0
       
   471           then of_indent ind ^ "moreover\n"
       
   472           else ""
       
   473     fun of_label l = if l = no_label then "" else string_for_label l ^ ": "
   466     fun of_label l = if l = no_label then "" else string_for_label l ^ ": "
   474     fun of_have qs nr_subproofs =
   467     fun of_obtain qs nr =
   475       if (member (op =) qs Then andalso nr_subproofs>0) orelse (nr_subproofs>1)
   468       (if nr>1 orelse (nr=1 andalso member (op=) qs Then)
   476         then "ultimately " ^ maybe_show qs
   469         then "ultimately "
   477         else
   470       else if nr=1 orelse member (op=) qs Then
   478           (if member (op =) qs Then orelse nr_subproofs>0 then
   471         then "then "
   479              if member (op =) qs Show then "thus" else "hence"
   472         else "") ^ "obtain"
   480            else
   473     fun of_show_have qs = if member (op=) qs Show then "show" else "have"
   481              maybe_show qs)
   474     fun of_thus_hence qs = if member (op=) qs Show then "thus" else "hence"
   482     fun of_obtain qs xs =
   475     fun of_prove qs nr =
   483       (if member (op =) qs Then then "then " else "") ^ "obtain " ^
   476       if nr>1 orelse (nr=1 andalso member (op=) qs Then)
   484       of_frees xs ^ " where"
   477         then "ultimately " ^ of_show_have qs
   485     val of_term =
   478       else if nr=1 orelse member (op=) qs Then
   486       annotate_types ctxt
   479         then of_thus_hence qs
   487       #> with_vanilla_print_mode (Syntax.string_of_term ctxt)
   480         else of_show_have qs
   488       #> simplify_spaces
   481     fun add_term term (s, ctxt)=
   489       #> maybe_quote
   482       (s ^ (annotate_types ctxt term
       
   483             |> with_vanilla_print_mode (Syntax.string_of_term ctxt)
       
   484             |> simplify_spaces
       
   485             |> maybe_quote),
       
   486        ctxt |> Variable.auto_fixes term)
   490     val reconstr = Metis (type_enc, lam_trans)
   487     val reconstr = Metis (type_enc, lam_trans)
   491     fun of_metis ind options (ls, ss) =
   488     fun of_metis ind options (ls, ss) =
   492       "\n" ^ of_indent (ind + 1) ^ options ^
   489       "\n" ^ of_indent (ind + 1) ^ options ^
   493       reconstructor_command reconstr 1 1 [] 0
   490       reconstructor_command reconstr 1 1 [] 0
   494           (ls |> sort_distinct (prod_ord string_ord int_ord),
   491           (ls |> sort_distinct (prod_ord string_ord int_ord),
   495            ss |> sort_distinct string_ord)
   492            ss |> sort_distinct string_ord)
   496     and of_step ind (Fix xs) = of_indent ind ^ "fix " ^ of_frees xs ^ "\n"
   493     fun of_free (s, T) =
   497       | of_step ind (Let (t1, t2)) =
   494       maybe_quote s ^ " :: " ^
   498         of_indent ind ^ "let " ^ of_term t1 ^ " = " ^ of_term t2 ^ "\n"
   495       maybe_quote (simplify_spaces (with_vanilla_print_mode
   499       | of_step ind (Assume (l, t)) =
   496         (Syntax.string_of_typ ctxt) T))
   500         of_indent ind ^ "assume " ^ of_label l ^ of_term t ^ "\n"
   497     fun add_frees xs (s, ctxt) =
   501       | of_step ind (Obtain (qs, xs, l, t, By_Metis (subproofs, facts))) =      (* FIXME *)
   498       (s ^ space_implode " and " (map of_free xs), ctxt |> register_fixes xs)
   502         maybe_moreover ind qs (length subproofs) ^
   499     fun add_fix _ [] = I
   503         of_subproofs ind subproofs ^
   500       | add_fix ind xs = add_suffix (of_indent ind ^ "fix ")
   504         of_indent ind ^ of_obtain qs xs ^ " " ^
   501                         #> add_frees xs
   505         of_label l ^ of_term t ^
   502                         #> add_suffix "\n"
   506         (* The new skolemizer puts the arguments in the same order as the ATPs
   503     fun add_assm ind (l, t) =
   507            (E and Vampire -- but see also "atp_proof_reconstruct.ML" regarding
   504       add_suffix (of_indent ind ^ "assume " ^ of_label l)
   508            Vampire). *)
   505       #> add_term t
   509         of_metis ind "using [[metis_new_skolem]] " facts ^ "\n"
   506       #> add_suffix "\n"
   510       | of_step ind (Prove (qs, l, t, By_Metis (subproofs, facts))) =
   507     fun add_assms ind assms = fold (add_assm ind) assms
   511         maybe_moreover ind qs (length subproofs) ^
   508     fun add_step_post ind l t facts options =
   512         of_subproofs ind subproofs ^
   509       add_suffix (of_label l)
   513         of_prove ind qs (length subproofs) l t facts
   510       #> add_term t
   514     and of_steps prefix suffix ind steps =
   511       #> add_suffix (of_metis ind options facts ^ "\n")
   515       let val s = implode (map (of_step ind) steps) in
   512     fun of_subproof ind ctxt proof =
       
   513       let
       
   514         val ind = ind + 1
       
   515         val s = of_proof ind ctxt proof
       
   516         val prefix = "{ "
       
   517         val suffix = " }"
       
   518       in
   516         replicate_string (ind * indent_size - size prefix) " " ^ prefix ^
   519         replicate_string (ind * indent_size - size prefix) " " ^ prefix ^
   517         String.extract (s, ind * indent_size,
   520         String.extract (s, ind * indent_size,
   518                         SOME (size s - ind * indent_size - 1)) ^
   521                         SOME (size s - ind * indent_size - 1)) ^
   519         suffix ^ "\n"
   522         suffix ^ "\n"
   520       end
   523       end
   521     and of_block ind proof = of_steps "{ " " }" (ind + 1) proof
   524     and of_subproofs _ _ _ [] = ""
   522     and of_subproofs ind subproofs =
   525       | of_subproofs ind ctxt qs subproofs =
   523         subproofs
   526         (if member (op=) qs Then then of_moreover ind else "") ^
   524           |> map (of_block ind)
   527         space_implode (of_moreover ind) (map (of_subproof ind ctxt) subproofs)
   525           |> space_implode (of_indent ind ^ "moreover\n")
   528     and add_step_pre ind qs subproofs (s, ctxt) =
   526     and of_prove ind qs nr_subproofs l t facts =
   529       (s ^ of_subproofs ind ctxt qs subproofs ^ of_indent ind, ctxt)
   527       of_indent ind ^ of_have qs nr_subproofs ^ " " ^ of_label l ^ of_term t ^
   530     and add_step ind (Let (t1, t2)) =
   528       of_metis ind "" facts ^ "\n"
   531         add_suffix (of_indent ind ^ "let ")
       
   532         #> add_term t1
       
   533         #> add_suffix " = "
       
   534         #> add_term t2
       
   535         #> add_suffix "\n"
       
   536       | add_step ind (Prove (qs, l, t, By_Metis (subproofs, facts))) =
       
   537         add_step_pre ind qs subproofs
       
   538         #> add_suffix (of_prove qs (length subproofs) ^ " ")
       
   539         #> add_step_post ind l t facts ""
       
   540       | add_step ind (Obtain (qs, Fix xs, l, t,
       
   541                       By_Metis (subproofs, facts))) =
       
   542         add_step_pre ind qs subproofs
       
   543         #> add_suffix (of_obtain qs (length subproofs) ^ " ")
       
   544         #> add_frees xs
       
   545         #> add_suffix " where "
       
   546         (* The new skolemizer puts the arguments in the same order as the ATPs
       
   547          (E and Vampire -- but see also "atp_proof_reconstruct.ML" regarding
       
   548          Vampire). *)
       
   549         #> add_step_post ind l t facts "using [[metis_new_skolem]] "
       
   550     and add_steps ind steps =
       
   551       fold (add_step ind) steps
       
   552     and of_proof ind ctxt (Proof (Fix xs, Assume assms, steps)) =
       
   553       ("", ctxt)
       
   554       |> add_fix ind xs
       
   555       |> add_assms ind assms
       
   556       |> add_steps ind steps
       
   557       |> fst
       
   558   in
   529     (* One-step proofs are pointless; better use the Metis one-liner
   559     (* One-step proofs are pointless; better use the Metis one-liner
   530        directly. *)
   560        directly. *)
   531     and of_proof [Prove (_, _, _, By_Metis ([], _))] = ""
   561     case proof of
   532       | of_proof proof =
   562       Proof (Fix [], Assume [], [Prove (_, _, _, By_Metis ([], _))]) => ""
   533         (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   563     | _ => (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   534         of_indent 0 ^ "proof -\n" ^ of_steps "" "" 1 proof ^ of_indent 0 ^
   564             of_indent 0 ^ "proof -\n" ^ of_proof 1 ctxt proof ^
   535         (if n <> 1 then "next" else "qed")
   565             of_indent 0 ^ (if n <> 1 then "next" else "qed")
   536   in of_proof end
   566   end
   537 
   567 
   538 fun add_labels_of_step (Obtain (_, _, _, _, By_Metis (subproofs, (ls, _)))) =
   568 fun add_labels_of_step step =
   539       union (op =) (add_labels_of_proofs subproofs ls)
   569   (case byline_of_step step of
   540   | add_labels_of_step (Prove (_, _, _, By_Metis (subproofs, (ls, _)))) =
   570      NONE => I
   541       union (op =) (add_labels_of_proofs subproofs ls)
   571   |  SOME (By_Metis (subproofs, (ls, _))) =>
   542   | add_labels_of_step _ = I
   572       union (op =) (add_labels_of_proofs subproofs ls))
   543 and add_labels_of_proof proof = fold add_labels_of_step proof
   573 and add_labels_of_proof proof = fold add_labels_of_step (steps_of_proof proof)
   544 and add_labels_of_proofs proofs = fold add_labels_of_proof proofs
   574 and add_labels_of_proofs proofs = fold add_labels_of_proof proofs
   545 
   575 
   546 fun kill_useless_labels_in_proof proof =
   576 fun kill_useless_labels_in_proof proof =
   547   let
   577   let
   548     val used_ls = add_labels_of_proof proof []
   578     val used_ls = add_labels_of_proof proof []
   549     fun do_label l = if member (op =) used_ls l then l else no_label
   579     fun do_label l = if member (op =) used_ls l then l else no_label
   550     fun do_step (Assume (l, t)) = Assume (do_label l, t)
   580     fun do_assms (Assume assms) = Assume (map (apfst do_label) assms)
   551       | do_step (Obtain (qs, xs, l, t, By_Metis (subproofs, facts))) =
   581     fun do_step (Obtain (qs, xs, l, t, By_Metis (subproofs, facts))) =
   552           Obtain (qs, xs, do_label l, t, By_Metis (map do_proof subproofs, facts))
   582           Obtain (qs, xs, do_label l, t, By_Metis (map do_proof subproofs, facts))
   553       | do_step (Prove (qs, l, t, By_Metis (subproofs, facts))) =
   583       | do_step (Prove (qs, l, t, By_Metis (subproofs, facts))) =
   554           Prove (qs, do_label l, t, By_Metis (map do_proof subproofs, facts))
   584           Prove (qs, do_label l, t, By_Metis (map do_proof subproofs, facts))
   555       | do_step step = step
   585       | do_step step = step
   556     and do_proof proof = map do_step proof
   586     and do_proof (Proof (fix, assms, steps)) =
       
   587           Proof (fix, do_assms assms, map do_step steps)
   557   in do_proof proof end
   588   in do_proof proof end
   558 
   589 
   559 fun prefix_for_depth n = replicate_string (n + 1)
   590 fun prefix_for_depth n = replicate_string (n + 1)
   560 
   591 
   561 val relabel_proof =
   592 val relabel_proof =
   562   let
   593   let
   563     fun fresh_label depth (old as (l, subst, next_have)) =
   594     fun fresh_label depth prefix (old as (l, subst, next)) =
   564       if l = no_label then
   595       if l = no_label then
   565         old
   596         old
   566       else
   597       else
   567         let val l' = (prefix_for_depth depth have_prefix, next_have) in
   598         let val l' = (prefix_for_depth depth prefix, next) in
   568           (l', (l, l') :: subst, next_have + 1)
   599           (l', (l, l') :: subst, next + 1)
   569         end
   600         end
   570     fun do_facts subst =
   601     fun do_facts subst =
   571       apfst (maps (the_list o AList.lookup (op =) subst))
   602       apfst (maps (the_list o AList.lookup (op =) subst))
   572     fun do_byline subst depth nexts (By_Metis (subproofs, facts)) =
   603     fun do_assm depth (l, t) (subst, next) =
   573       By_Metis
   604       let
   574         (map (do_proof subst (depth + 1) (1, 1)) subproofs, do_facts subst facts)
   605         val (l, subst, next) =
   575     and do_proof _ _ _ [] = []
   606           (l, subst, next) |> fresh_label depth assume_prefix
   576       | do_proof subst depth (next_assum, next_have) (Assume (l, t) :: proof) =
   607       in
   577         if l = no_label then
   608         ((l, t), (subst, next))
   578           Assume (l, t) :: do_proof subst depth (next_assum, next_have) proof
   609       end
   579         else
   610     fun do_assms subst depth (Assume assms) =
   580           let val l' = (prefix_for_depth depth assume_prefix, next_assum) in
   611       fold_map (do_assm depth) assms (subst, 1)
   581             Assume (l', t) ::
   612       |> apfst Assume
   582             do_proof ((l, l') :: subst) depth (next_assum + 1, next_have) proof
   613       |> apsnd fst
   583           end
   614     fun do_steps _ _ _ [] = []
   584       | do_proof subst depth (nexts as (next_assum, next_have))
   615       | do_steps subst depth next (Obtain (qs, xs, l, t, by) :: steps) =
   585             (Obtain (qs, xs, l, t, by) :: proof) =
       
   586         let
   616         let
   587           val (l, subst, next_have) = (l, subst, next_have) |> fresh_label depth
   617           val (l, subst, next) =
   588           val by = by |> do_byline subst depth nexts
   618             (l, subst, next) |> fresh_label depth have_prefix
       
   619           val by = by |> do_byline subst depth
   589         in
   620         in
   590           Obtain (qs, xs, l, t, by) ::
   621           Obtain (qs, xs, l, t, by) :: do_steps subst depth next steps
   591           do_proof subst depth (next_assum, next_have) proof
       
   592         end
   622         end
   593       | do_proof subst depth (nexts as (next_assum, next_have))
   623       | do_steps subst depth next (Prove (qs, l, t, by) :: steps) =
   594             (Prove (qs, l, t, by) :: proof) =
       
   595         let
   624         let
   596           val (l, subst, next_have) = (l, subst, next_have) |> fresh_label depth
   625           val (l, subst, next) =
   597           val by = by |> do_byline subst depth nexts
   626             (l, subst, next) |> fresh_label depth have_prefix
       
   627           val by = by |> do_byline subst depth
   598         in
   628         in
   599           Prove (qs, l, t, by) ::
   629           Prove (qs, l, t, by) :: do_steps subst depth next steps
   600           do_proof subst depth (next_assum, next_have) proof
       
   601         end
   630         end
   602       | do_proof subst depth nexts (step :: proof) =
   631       | do_steps subst depth next (step :: steps) =
   603         step :: do_proof subst depth nexts proof
   632         step :: do_steps subst depth next steps
   604   in do_proof [] 0 (1, 1) end
   633     and do_proof subst depth (Proof (fix, assms, steps)) =
       
   634       let val (assms, subst) = do_assms subst depth assms in
       
   635         Proof (fix, assms, do_steps subst depth 1 steps)
       
   636       end
       
   637     and do_byline subst depth (By_Metis (subproofs, facts)) =
       
   638       By_Metis (do_proofs subst depth subproofs, do_facts subst facts)
       
   639     and do_proofs subst depth = map (do_proof subst (depth + 1))
       
   640   in do_proof [] 0 end
   605 
   641 
   606 val chain_direct_proof =
   642 val chain_direct_proof =
   607   let
   643   let
   608     fun label_of (Assume (l, _)) = SOME l
       
   609       | label_of (Obtain (_, _, l, _, _)) = SOME l
       
   610       | label_of (Prove (_, l, _, _)) = SOME l
       
   611       | label_of _ = NONE
       
   612     fun do_qs_lfs NONE lfs = ([], lfs)
   644     fun do_qs_lfs NONE lfs = ([], lfs)
   613       | do_qs_lfs (SOME l0) lfs =
   645       | do_qs_lfs (SOME l0) lfs =
   614         if member (op =) lfs l0 then ([Then], lfs |> remove (op =) l0)
   646         if member (op =) lfs l0 then ([Then], lfs |> remove (op =) l0)
   615         else ([], lfs)
   647         else ([], lfs)
   616     fun chain_step lbl (Obtain (qs, xs, l, t,
   648     fun chain_step lbl (Obtain (qs, xs, l, t,
   619           Obtain (qs' @ qs, xs, l, t,
   651           Obtain (qs' @ qs, xs, l, t,
   620             By_Metis (chain_proofs subproofs, (lfs, gfs)))
   652             By_Metis (chain_proofs subproofs, (lfs, gfs)))
   621         end
   653         end
   622       | chain_step lbl (Prove (qs, l, t, By_Metis (subproofs, (lfs, gfs)))) =
   654       | chain_step lbl (Prove (qs, l, t, By_Metis (subproofs, (lfs, gfs)))) =
   623         let val (qs', lfs) = do_qs_lfs lbl lfs in
   655         let val (qs', lfs) = do_qs_lfs lbl lfs in
   624           Prove (qs' @ qs, l, t,
   656           Prove (qs' @ qs, l, t, By_Metis (chain_proofs subproofs, (lfs, gfs)))
   625             By_Metis (chain_proofs subproofs, (lfs, gfs)))
       
   626         end
   657         end
   627       | chain_step _ step = step
   658       | chain_step _ step = step
   628     and chain_proof _ [] = []
   659     and chain_steps _ [] = []
   629       | chain_proof (prev as SOME _) (i :: is) =
   660       | chain_steps (prev as SOME _) (i :: is) =
   630         chain_step prev i :: chain_proof (label_of i) is
   661         chain_step prev i :: chain_steps (label_of_step i) is
   631       | chain_proof _ (i :: is) = i :: chain_proof (label_of i) is
   662       | chain_steps _ (i :: is) = i :: chain_steps (label_of_step i) is
   632     and chain_proofs proofs = map (chain_proof NONE) proofs
   663     and chain_proof (Proof (fix, Assume assms, steps)) =
   633   in chain_proof NONE end
   664       Proof (fix, Assume assms,
       
   665              chain_steps (try (List.last #> fst) assms) steps)
       
   666     and chain_proofs proofs = map (chain_proof) proofs
       
   667   in chain_proof end
   634 
   668 
   635 type isar_params =
   669 type isar_params =
   636   bool * bool * Time.time option * real * string Symtab.table
   670   bool * bool * Time.time option * real * string Symtab.table
   637   * (string * stature) list vector * int Symtab.table * string proof * thm
   671   * (string * stature) list vector * int Symtab.table * string proof * thm
   638 
   672 
   674           atp_proof |> map_filter
   708           atp_proof |> map_filter
   675             (fn Inference_Step (name as (_, ss), _, _, _, []) =>
   709             (fn Inference_Step (name as (_, ss), _, _, _, []) =>
   676                 (case resolve_conjecture ss of
   710                 (case resolve_conjecture ss of
   677                    [j] =>
   711                    [j] =>
   678                    if j = length hyp_ts then NONE
   712                    if j = length hyp_ts then NONE
   679                    else SOME (Assume (raw_label_for_name name, nth hyp_ts j))
   713                    else SOME (raw_label_for_name name, nth hyp_ts j)
   680                  | _ => NONE)
   714                  | _ => NONE)
   681               | _ => NONE)
   715               | _ => NONE)
   682         fun dep_of_step (Definition_Step _) = NONE
   716         fun dep_of_step (Definition_Step _) = NONE
   683           | dep_of_step (Inference_Step (name, _, _, _, from)) =
   717           | dep_of_step (Inference_Step (name, _, _, _, from)) =
   684             SOME (from, name)
   718             SOME (from, name)
   689         val is_clause_tainted = exists (member (op =) tainted)
   723         val is_clause_tainted = exists (member (op =) tainted)
   690         val bot = atp_proof |> List.last |> dep_of_step |> the |> snd
   724         val bot = atp_proof |> List.last |> dep_of_step |> the |> snd
   691         val steps =
   725         val steps =
   692           Symtab.empty
   726           Symtab.empty
   693           |> fold (fn Definition_Step _ => I (* FIXME *)
   727           |> fold (fn Definition_Step _ => I (* FIXME *)
   694                     | Inference_Step (name as (s, ss), role, t, rule, _) =>
   728                     | Inference_Step (name as (s, _), role, t, rule, _) =>
   695                       Symtab.update_new (s, (rule,
   729                       Symtab.update_new (s, (rule,
   696                         t |> (if is_clause_tainted [name] then
   730                         t |> (if is_clause_tainted [name] then
   697                                 s_maybe_not role
   731                                 s_maybe_not role
   698                                 #> fold exists_of (map Var (Term.add_vars t []))
   732                                 #> fold exists_of (map Var (Term.add_vars t []))
   699                               else
   733                               else
   703             Option.map (is_skolemize_rule o fst) (Symtab.lookup steps s) =
   737             Option.map (is_skolemize_rule o fst) (Symtab.lookup steps s) =
   704             SOME true
   738             SOME true
   705           | is_clause_skolemize_rule _ = false
   739           | is_clause_skolemize_rule _ = false
   706         (* The assumptions and conjecture are "prop"s; the other formulas are
   740         (* The assumptions and conjecture are "prop"s; the other formulas are
   707            "bool"s. *)
   741            "bool"s. *)
   708         fun prop_of_clause [name as (s, ss)] =
   742         fun prop_of_clause [(s, ss)] =
   709             (case resolve_conjecture ss of
   743             (case resolve_conjecture ss of
   710                [j] => if j = length hyp_ts then concl_t else nth hyp_ts j
   744                [j] => if j = length hyp_ts then concl_t else nth hyp_ts j
   711              | _ => the_default ("", @{term False}) (Symtab.lookup steps s)
   745              | _ => the_default ("", @{term False}) (Symtab.lookup steps s)
   712                     |> snd |> HOLogic.mk_Trueprop |> close_form)
   746                     |> snd |> HOLogic.mk_Trueprop |> close_form)
   713           | prop_of_clause names =
   747           | prop_of_clause names =
   720                   (Library.foldr1 s_conj (map HOLogic.dest_not negs),
   754                   (Library.foldr1 s_conj (map HOLogic.dest_not negs),
   721                    Library.foldr1 s_disj pos)
   755                    Library.foldr1 s_disj pos)
   722               | _ => fold (curry s_disj) lits @{term False}
   756               | _ => fold (curry s_disj) lits @{term False}
   723             end
   757             end
   724             |> HOLogic.mk_Trueprop |> close_form
   758             |> HOLogic.mk_Trueprop |> close_form
   725         fun isar_proof_of_direct_proof outer predecessor accum [] =
   759         fun isar_proof_of_direct_proof infs =
   726             rev accum |> outer ? (append assms
   760           let
   727                                   #> not (null params) ? cons (Fix params))
   761             fun maybe_show outer c =
   728           | isar_proof_of_direct_proof outer predecessor accum (inf :: infs) =
   762               (outer andalso length c = 1 andalso subset (op =) (c, conjs))
   729             let
   763               ? cons Show
   730               fun maybe_show outer c =
   764             val is_fixed = Variable.is_declared ctxt orf can Name.dest_skolem
   731                 (outer andalso length c = 1 andalso subset (op =) (c, conjs))
   765             fun skolems_of t =
   732                 ? cons Show
   766               Term.add_frees t [] |> filter_out (is_fixed o fst) |> rev
   733               fun do_rest lbl step =
   767             fun do_steps _ _ accum [] = rev accum
   734                 isar_proof_of_direct_proof outer lbl (step :: accum) infs
   768               | do_steps outer _ accum (Have (gamma, c) :: infs) =
   735               val is_fixed = Variable.is_declared ctxt orf can Name.dest_skolem
       
   736               fun skolems_of t =
       
   737                 Term.add_frees t [] |> filter_out (is_fixed o fst) |> rev
       
   738             in
       
   739               case inf of
       
   740                 Have (gamma, c) =>
       
   741                 let
   769                 let
   742                   val l = label_of_clause c
   770                   val l = label_of_clause c
   743                   val t = prop_of_clause c
   771                   val t = prop_of_clause c
   744                   val by =
   772                   val by =
   745                     By_Metis ([],
   773                     By_Metis ([],
   746                       (fold (add_fact_from_dependencies fact_names)
   774                       (fold (add_fact_from_dependencies fact_names)
   747                             gamma no_facts))
   775                             gamma no_facts))
   748                   fun prove outer = Prove (maybe_show outer c [], l, t, by)
   776                   fun prove by = Prove (maybe_show outer c [], l, t, by)
       
   777                   fun do_rest lbl step =
       
   778                     do_steps outer (SOME lbl) (step :: accum) infs
   749                 in
   779                 in
   750                   if is_clause_tainted c then
   780                   if is_clause_tainted c then
   751                     case gamma of
   781                     case gamma of
   752                       [g] =>
   782                       [g] =>
   753                       if is_clause_skolemize_rule g andalso
   783                       if is_clause_skolemize_rule g andalso
   754                          is_clause_tainted g then
   784                          is_clause_tainted g then
   755                         let
   785                         let
   756                           val subproof =
   786                           val subproof =
   757                             Fix (skolems_of (prop_of_clause g)) :: rev accum
   787                             Proof (Fix (skolems_of (prop_of_clause g)),
       
   788                                    Assume [], rev accum)
   758                         in
   789                         in
   759                           isar_proof_of_direct_proof outer l
   790                           do_steps outer (SOME l)
   760                               [Prove (maybe_show outer c [],
   791                               [prove (By_Metis ([subproof], no_facts))] []
   761                                       label_of_clause c, prop_of_clause c,
       
   762                                       By_Metis ([subproof], no_facts))] []
       
   763                         end
   792                         end
   764                       else
   793                       else
   765                         do_rest l (prove outer)
   794                         do_rest l (prove by)
   766                     | _ => do_rest l (prove outer)
   795                     | _ => do_rest l (prove by)
   767                   else
   796                   else
   768                     if is_clause_skolemize_rule c then
   797                     if is_clause_skolemize_rule c then
   769                       do_rest l (Obtain ([], skolems_of t, l, t, by))
   798                       do_rest l (Obtain ([], Fix (skolems_of t), l, t, by))
   770                     else
   799                     else
   771                       do_rest l (prove outer)
   800                       do_rest l (prove by)
   772                 end
   801                 end
   773               | Cases cases =>
   802               | do_steps outer predecessor accum (Cases cases :: infs) =
   774                 let
   803                 let
   775                   fun do_case (c, infs) =
   804                   fun do_case (c, infs) =
   776                     Assume (label_of_clause c, prop_of_clause c) ::
   805                     do_proof false [] [(label_of_clause c, prop_of_clause c)] infs
   777                     isar_proof_of_direct_proof false no_label [] infs
       
   778                   val c = succedent_of_cases cases
   806                   val c = succedent_of_cases cases
   779                   val l = label_of_clause c
   807                   val l = label_of_clause c
       
   808                   val t = prop_of_clause c
       
   809                   val step =
       
   810                     (Prove (maybe_show outer c [], l, t, By_Metis
       
   811                       (map do_case cases, (the_list predecessor, []))))
   780                 in
   812                 in
   781                   do_rest l
   813                   do_steps outer (SOME l) (step :: accum) infs
   782                     (Prove (maybe_show outer c [],
       
   783                             l, prop_of_clause c,
       
   784                             By_Metis (map do_case cases, ([predecessor], []))))
       
   785                 end
   814                 end
   786             end
   815             and do_proof outer fix assms infs =
       
   816               Proof (Fix fix, Assume assms, do_steps outer NONE [] infs)
       
   817           in
       
   818             do_proof true params assms infs
       
   819           end
       
   820 
   787         val cleanup_labels_in_proof =
   821         val cleanup_labels_in_proof =
   788           chain_direct_proof
   822           chain_direct_proof
   789           #> kill_useless_labels_in_proof
   823           #> kill_useless_labels_in_proof
   790           #> relabel_proof
   824           #> relabel_proof
   791         val (isar_proof, (preplay_fail, preplay_time)) =
   825         val (isar_proof, (preplay_fail, preplay_time)) =
   792           refute_graph
   826           refute_graph
   793           |> redirect_graph axioms tainted bot
   827           |> redirect_graph axioms tainted bot
   794           |> isar_proof_of_direct_proof true no_label []
   828           |> isar_proof_of_direct_proof
   795           |> (if not preplay andalso isar_compress <= 1.0 then
   829           |> (if not preplay andalso isar_compress <= 1.0 then
   796                 rpair (false, (true, seconds 0.0))
   830                 rpair (false, (true, seconds 0.0))
   797               else
   831               else
   798                 compress_proof debug ctxt type_enc lam_trans preplay
   832                 compress_proof debug ctxt type_enc lam_trans preplay
   799                   preplay_timeout
   833                   preplay_timeout
   816                 [(if preplay_fail then "may fail, " else "") ^
   850                 [(if preplay_fail then "may fail, " else "") ^
   817                    Sledgehammer_Preplay.string_of_preplay_time preplay_time]
   851                    Sledgehammer_Preplay.string_of_preplay_time preplay_time]
   818                else
   852                else
   819                  []) @
   853                  []) @
   820               (if verbose then
   854               (if verbose then
   821                  let val num_steps = metis_steps_total isar_proof in
   855                 let
   822                    [string_of_int num_steps ^ " step" ^ plural_s num_steps]
   856                   val num_steps = add_metis_steps (steps_of_proof isar_proof) 0
   823                  end
   857                 in
       
   858                   [string_of_int num_steps ^ " step" ^ plural_s num_steps]
       
   859                 end
   824                else
   860                else
   825                  [])
   861                  [])
   826           in
   862           in
   827             "\n\nStructured proof "
   863             "\n\nStructured proof "
   828               ^ (commas msg |> not (null msg) ? enclose "(" ")")
   864               ^ (commas msg |> not (null msg) ? enclose "(" ")")