src/HOL/Tools/Sledgehammer/sledgehammer_reconstruct.ML
changeset 50672 ab5b8b5c9cbe
parent 50671 6632cb8df708
child 50673 f1426d48942f
equal deleted inserted replaced
50671:6632cb8df708 50672:ab5b8b5c9cbe
   465       (if member (op =) qs Ultimately then "ultimately " else "") ^
   465       (if member (op =) qs Ultimately then "ultimately " else "") ^
   466       (if member (op =) qs Then then
   466       (if member (op =) qs Then then
   467          if member (op =) qs Show then "thus" else "hence"
   467          if member (op =) qs Show then "thus" else "hence"
   468        else
   468        else
   469          if member (op =) qs Show then "show" else "have")
   469          if member (op =) qs Show then "show" else "have")
       
   470     fun do_obtain qs xs =
       
   471       (if member (op =) qs Then then "then " else "") ^ "obtain " ^
       
   472       (space_implode " " (map fst xs))
   470     val do_term =
   473     val do_term =
   471       annotate_types ctxt
   474       annotate_types ctxt
   472       #> with_vanilla_print_mode (Syntax.string_of_term ctxt)
   475       #> with_vanilla_print_mode (Syntax.string_of_term ctxt)
   473       #> simplify_spaces
   476       #> simplify_spaces
   474       #> maybe_quote
   477       #> maybe_quote
   475     val reconstr = Metis (type_enc, lam_trans)
   478     val reconstr = Metis (type_enc, lam_trans)
   476     fun do_facts ind (ls, ss) =
   479     fun do_metis ind (ls, ss) =
   477       "\n" ^ do_indent (ind + 1) ^
   480       "\n" ^ do_indent (ind + 1) ^
   478       reconstructor_command reconstr 1 1 [] 0
   481       reconstructor_command reconstr 1 1 [] 0
   479           (ls |> sort_distinct (prod_ord string_ord int_ord),
   482           (ls |> sort_distinct (prod_ord string_ord int_ord),
   480            ss |> sort_distinct string_ord)
   483            ss |> sort_distinct string_ord)
   481     and do_step ind (Fix xs) =
   484     and do_step ind (Fix xs) =
   482         do_indent ind ^ "fix " ^ space_implode " and " (map do_free xs) ^ "\n"
   485         do_indent ind ^ "fix " ^ space_implode " and " (map do_free xs) ^ "\n"
   483       | do_step ind (Let (t1, t2)) =
   486       | do_step ind (Let (t1, t2)) =
   484         do_indent ind ^ "let " ^ do_term t1 ^ " = " ^ do_term t2 ^ "\n"
   487         do_indent ind ^ "let " ^ do_term t1 ^ " = " ^ do_term t2 ^ "\n"
   485       | do_step ind (Assume (l, t)) =
   488       | do_step ind (Assume (l, t)) =
   486         do_indent ind ^ "assume " ^ do_label l ^ do_term t ^ "\n"
   489         do_indent ind ^ "assume " ^ do_label l ^ do_term t ^ "\n"
       
   490       | do_step ind (Obtain (qs, xs, l, t, By_Metis facts)) =
       
   491         do_indent ind ^ do_obtain qs xs ^ " " ^
       
   492         do_label l ^ do_term t ^ do_metis ind facts ^ "\n"
   487       | do_step ind (Prove (qs, l, t, By_Metis facts)) =
   493       | do_step ind (Prove (qs, l, t, By_Metis facts)) =
   488         do_indent ind ^ do_have qs ^ " " ^
   494         do_indent ind ^ do_have qs ^ " " ^
   489         do_label l ^ do_term t ^ do_facts ind facts ^ "\n"
   495         do_label l ^ do_term t ^ do_metis ind facts ^ "\n"
   490       | do_step ind (Prove (qs, l, t, Case_Split (proofs, facts))) =
   496       | do_step ind (Prove (qs, l, t, Case_Split (proofs, facts))) =
   491         implode (map (prefix (do_indent ind ^ "moreover\n") o do_block ind)
   497         implode (map (prefix (do_indent ind ^ "moreover\n") o do_block ind)
   492                      proofs) ^
   498                      proofs) ^
   493         do_indent ind ^ do_have qs ^ " " ^ do_label l ^ do_term t ^
   499         do_indent ind ^ do_have qs ^ " " ^ do_label l ^ do_term t ^
   494         do_facts ind facts ^ "\n"
   500         do_metis ind facts ^ "\n"
   495     and do_steps prefix suffix ind steps =
   501     and do_steps prefix suffix ind steps =
   496       let val s = implode (map (do_step ind) steps) in
   502       let val s = implode (map (do_step ind) steps) in
   497         replicate_string (ind * indent_size - size prefix) " " ^ prefix ^
   503         replicate_string (ind * indent_size - size prefix) " " ^ prefix ^
   498         String.extract (s, ind * indent_size,
   504         String.extract (s, ind * indent_size,
   499                         SOME (size s - ind * indent_size - 1)) ^
   505                         SOME (size s - ind * indent_size - 1)) ^
   507         (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   513         (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   508         do_indent 0 ^ "proof -\n" ^ do_steps "" "" 1 proof ^ do_indent 0 ^
   514         do_indent 0 ^ "proof -\n" ^ do_steps "" "" 1 proof ^ do_indent 0 ^
   509         (if n <> 1 then "next" else "qed")
   515         (if n <> 1 then "next" else "qed")
   510   in do_proof end
   516   in do_proof end
   511 
   517 
   512 fun used_labels_of_step (Prove (_, _, _, by)) =
   518 fun used_labels_of_step (Obtain (_, _, _, _, By_Metis (ls, _))) = ls
       
   519   | used_labels_of_step (Prove (_, _, _, by)) =
   513     (case by of
   520     (case by of
   514        By_Metis (ls, _) => ls
   521        By_Metis (ls, _) => ls
   515      | Case_Split (proofs, (ls, _)) =>
   522      | Case_Split (proofs, (ls, _)) =>
   516        fold (union (op =) o used_labels_of) proofs ls)
   523        fold (union (op =) o used_labels_of) proofs ls)
   517   | used_labels_of_step _ = []
   524   | used_labels_of_step _ = []
   520 fun kill_useless_labels_in_proof proof =
   527 fun kill_useless_labels_in_proof proof =
   521   let
   528   let
   522     val used_ls = used_labels_of proof
   529     val used_ls = used_labels_of proof
   523     fun do_label l = if member (op =) used_ls l then l else no_label
   530     fun do_label l = if member (op =) used_ls l then l else no_label
   524     fun do_step (Assume (l, t)) = Assume (do_label l, t)
   531     fun do_step (Assume (l, t)) = Assume (do_label l, t)
       
   532       | do_step (Obtain (qs, xs, l, t, by)) = Obtain (qs, xs, do_label l, t, by)
   525       | do_step (Prove (qs, l, t, by)) =
   533       | do_step (Prove (qs, l, t, by)) =
   526         Prove (qs, do_label l, t,
   534         Prove (qs, do_label l, t,
   527                case by of
   535                case by of
   528                  Case_Split (proofs, facts) =>
   536                  Case_Split (proofs, facts) =>
   529                  Case_Split (map (map do_step) proofs, facts)
   537                  Case_Split (map (map do_step) proofs, facts)
   533 
   541 
   534 fun prefix_for_depth n = replicate_string (n + 1)
   542 fun prefix_for_depth n = replicate_string (n + 1)
   535 
   543 
   536 val relabel_proof =
   544 val relabel_proof =
   537   let
   545   let
   538     fun aux _ _ _ [] = []
   546     fun fresh_label depth (old as (l, subst, next_have)) =
   539       | aux subst depth (next_assum, next_have) (Assume (l, t) :: proof) =
   547       if l = no_label then
       
   548         old
       
   549       else
       
   550         let val l' = (prefix_for_depth depth have_prefix, next_have) in
       
   551           (l', (l, l') :: subst, next_have + 1)
       
   552         end
       
   553     fun do_facts subst =
       
   554       apfst (maps (the_list o AList.lookup (op =) subst))
       
   555     fun do_byline subst depth by =
       
   556       case by of
       
   557         By_Metis facts => By_Metis (do_facts subst facts)
       
   558       | Case_Split (proofs, facts) =>
       
   559         Case_Split (map (do_proof subst (depth + 1) (1, 1)) proofs,
       
   560                     do_facts subst facts)
       
   561     and do_proof _ _ _ [] = []
       
   562       | do_proof subst depth (next_assum, next_have) (Assume (l, t) :: proof) =
   540         if l = no_label then
   563         if l = no_label then
   541           Assume (l, t) :: aux subst depth (next_assum, next_have) proof
   564           Assume (l, t) :: do_proof subst depth (next_assum, next_have) proof
   542         else
   565         else
   543           let val l' = (prefix_for_depth depth assume_prefix, next_assum) in
   566           let val l' = (prefix_for_depth depth assume_prefix, next_assum) in
   544             Assume (l', t) ::
   567             Assume (l', t) ::
   545             aux ((l, l') :: subst) depth (next_assum + 1, next_have) proof
   568             do_proof ((l, l') :: subst) depth (next_assum + 1, next_have) proof
   546           end
   569           end
   547       | aux subst depth (next_assum, next_have)
   570       | do_proof subst depth (next_assum, next_have)
       
   571             (Obtain (qs, xs, l, t, by) :: proof) =
       
   572         let
       
   573           val (l, subst, next_have) = (l, subst, next_have) |> fresh_label depth
       
   574           val by = by |> do_byline subst depth
       
   575         in
       
   576           Obtain (qs, xs, l, t, by) ::
       
   577           do_proof subst depth (next_assum, next_have) proof
       
   578         end
       
   579       | do_proof subst depth (next_assum, next_have)
   548             (Prove (qs, l, t, by) :: proof) =
   580             (Prove (qs, l, t, by) :: proof) =
   549         let
   581         let
   550           val (l', subst, next_have) =
   582           val (l, subst, next_have) = (l, subst, next_have) |> fresh_label depth
   551             if l = no_label then
   583           val by = by |> do_byline subst depth
   552               (l, subst, next_have)
       
   553             else
       
   554               let val l' = (prefix_for_depth depth have_prefix, next_have) in
       
   555                 (l', (l, l') :: subst, next_have + 1)
       
   556               end
       
   557           val relabel_facts =
       
   558             apfst (maps (the_list o AList.lookup (op =) subst))
       
   559           val by =
       
   560             case by of
       
   561               By_Metis facts => By_Metis (relabel_facts facts)
       
   562             | Case_Split (proofs, facts) =>
       
   563               Case_Split (map (aux subst (depth + 1) (1, 1)) proofs,
       
   564                           relabel_facts facts)
       
   565         in
   584         in
   566           Prove (qs, l', t, by) :: aux subst depth (next_assum, next_have) proof
   585           Prove (qs, l, t, by) ::
       
   586           do_proof subst depth (next_assum, next_have) proof
   567         end
   587         end
   568       | aux subst depth nextp (step :: proof) =
   588       | do_proof subst depth nextp (step :: proof) =
   569         step :: aux subst depth nextp proof
   589         step :: do_proof subst depth nextp proof
   570   in aux [] 0 (1, 1) end
   590   in do_proof [] 0 (1, 1) end
   571 
   591 
   572 val chain_direct_proof =
   592 val chain_direct_proof =
   573   let
   593   let
   574     fun succedent_of_step (Prove (_, label, _, _)) = SOME label
   594     fun label_of (Assume (l, _)) = SOME l
   575       | succedent_of_step (Assume (label, _)) = SOME label
   595       | label_of (Obtain (_, _, l, _, _)) = SOME l
   576       | succedent_of_step _ = NONE
   596       | label_of (Prove (_, l, _, _)) = SOME l
   577     fun chain_inf (SOME label0)
   597       | label_of _ = NONE
   578                   (step as Prove (qs, label, t, By_Metis (lfs, gfs))) =
   598     fun chain_step (SOME l0)
   579         if member (op =) lfs label0 then
   599                    (step as Obtain (qs, xs, l, t, By_Metis (lfs, gfs))) =
   580           Prove (Then :: qs, label, t,
   600         if member (op =) lfs l0 then
   581                  By_Metis (filter_out (curry (op =) label0) lfs, gfs))
   601           Obtain (Then :: qs, xs, l, t, By_Metis (lfs |> remove (op =) l0, gfs))
   582         else
   602         else
   583           step
   603           step
   584       | chain_inf _ (Prove (qs, label, t, Case_Split (proofs, facts))) =
   604       | chain_step (SOME l0)
   585         Prove (qs, label, t, Case_Split ((map (chain_proof NONE) proofs), facts))
   605                    (step as Prove (qs, l, t, By_Metis (lfs, gfs))) =
   586       | chain_inf _ step = step
   606         if member (op =) lfs l0 then
       
   607           Prove (Then :: qs, l, t, By_Metis (lfs |> remove (op =) l0, gfs))
       
   608         else
       
   609           step
       
   610       | chain_step _ (Prove (qs, l, t, Case_Split (proofs, facts))) =
       
   611         Prove (qs, l, t, Case_Split ((map (chain_proof NONE) proofs), facts))
       
   612       | chain_step _ step = step
   587     and chain_proof _ [] = []
   613     and chain_proof _ [] = []
   588       | chain_proof (prev as SOME _) (i :: is) =
   614       | chain_proof (prev as SOME _) (i :: is) =
   589         chain_inf prev i :: chain_proof (succedent_of_step i) is
   615         chain_step prev i :: chain_proof (label_of i) is
   590       | chain_proof _ (i :: is) =
   616       | chain_proof _ (i :: is) = i :: chain_proof (label_of i) is
   591         i :: chain_proof (succedent_of_step i) is
       
   592   in chain_proof NONE end
   617   in chain_proof NONE end
   593 
   618 
   594 type isar_params =
   619 type isar_params =
   595   bool * bool * Time.time option * real * string Symtab.table
   620   bool * bool * Time.time option * real * string Symtab.table
   596   * (string * stature) list vector * int Symtab.table * string proof * thm
   621   * (string * stature) list vector * int Symtab.table * string proof * thm