src/HOL/Tools/Sledgehammer/sledgehammer_isar_compress.ML
changeset 55325 462ffd3b7065
parent 55323 253a029335a2
child 55328 0e17e92248ac
equal deleted inserted replaced
55324:e04b75bd18e0 55325:462ffd3b7065
    23 open Sledgehammer_Isar_Proof
    23 open Sledgehammer_Isar_Proof
    24 open Sledgehammer_Isar_Preplay
    24 open Sledgehammer_Isar_Preplay
    25 
    25 
    26 val dummy_isar_step = Let (Term.dummy, Term.dummy)
    26 val dummy_isar_step = Let (Term.dummy, Term.dummy)
    27 
    27 
    28 (* traverses steps in post-order and collects the steps with the given labels *)
       
    29 fun collect_successors steps lbls =
    28 fun collect_successors steps lbls =
    30   let
    29   let
    31     fun collect_steps _ ([], accu) = ([], accu)
    30     fun collect_steps _ ([], accu) = ([], accu)
    32       | collect_steps [] accum = accum
    31       | collect_steps [] accum = accum
    33       | collect_steps (step :: steps) accum = collect_steps steps (collect_step step accum)
    32       | collect_steps (step :: steps) accum = collect_steps steps (collect_step step accum)
    43         | accum => collect_subproofs subproofs accum)
    42         | accum => collect_subproofs subproofs accum)
    44   in
    43   in
    45     rev (snd (collect_steps steps (lbls, [])))
    44     rev (snd (collect_steps steps (lbls, [])))
    46   end
    45   end
    47 
    46 
    48 (* traverses steps in reverse post-order and inserts the given updates *)
       
    49 fun update_steps steps updates =
    47 fun update_steps steps updates =
    50   let
    48   let
    51     fun update_steps [] updates = ([], updates)
    49     fun update_steps [] updates = ([], updates)
    52       | update_steps steps [] = (steps, [])
    50       | update_steps steps [] = (steps, [])
    53       | update_steps (step :: steps) updates = update_step step (update_steps steps updates)
    51       | update_steps (step :: steps) updates = update_step step (update_steps steps updates)
    83         not (Lazy.is_finished outcome) orelse
    81         not (Lazy.is_finished outcome) orelse
    84         (case Lazy.force outcome of Played _ => true | _ => false)
    82         (case Lazy.force outcome of Played _ => true | _ => false)
    85       end
    83       end
    86   in
    84   in
    87     meths2 @ subtract (op =) meths2 meths1
    85     meths2 @ subtract (op =) meths2 meths1
    88     |> filter (is_method_hopeful l1 andf is_method_hopeful l2)
    86     |> List.partition (is_method_hopeful l1 andf is_method_hopeful l2)
       
    87     |> op @
    89   end
    88   end
    90 
    89 
    91 fun try_merge preplay_data (Prove (_, [], l1, _, subproofs1, (lfs1, gfs1), meths1, comment1))
    90 fun try_merge preplay_data (Prove (_, [], l1, _, subproofs1, (lfs1, gfs1), meths1, comment1))
    92       (Prove (qs2, fix, l2, t, subproofs2, (lfs2, gfs2), meths2, comment2)) =
    91       (Prove (qs2, fix, l2, t, subproofs2, (lfs2, gfs2), meths2, comment2)) =
    93     (case merge_methods preplay_data (l1, meths1) (l2, meths2) of
    92     (case merge_methods preplay_data (l1, meths1) (l2, meths2) of
   102       end)
   101       end)
   103   | try_merge _ _ _ = NONE
   102   | try_merge _ _ _ = NONE
   104 
   103 
   105 val compress_degree = 2
   104 val compress_degree = 2
   106 val merge_timeout_slack_time = seconds 0.005
   105 val merge_timeout_slack_time = seconds 0.005
   107 val merge_timeout_slack_factor = 1.25
   106 val merge_timeout_slack_factor = 1.5
   108 
   107 
   109 fun slackify_merge_timeout time =
   108 fun slackify_merge_timeout time =
   110   time_mult merge_timeout_slack_factor (Time.+ (merge_timeout_slack_time, time))
   109   time_mult merge_timeout_slack_factor (Time.+ (merge_timeout_slack_time, time))
   111 
   110 
   112 (* Precondition: The proof must be labeled canonically. *)
   111 (* Precondition: The proof must be labeled canonically. *)
   203         let
   202         let
   204           (* (#successors, (size_of_term t, position)) *)
   203           (* (#successors, (size_of_term t, position)) *)
   205           fun cand_key (i, l, t_size) = (length (get_successors l), (t_size, i))
   204           fun cand_key (i, l, t_size) = (length (get_successors l), (t_size, i))
   206 
   205 
   207           val compression_ord =
   206           val compression_ord =
   208             prod_ord int_ord (prod_ord (int_ord #> rev_order) int_ord)
   207             prod_ord int_ord (prod_ord (int_ord #> rev_order) int_ord) #> rev_order
   209             #> rev_order
       
   210 
   208 
   211           val cand_ord = pairself cand_key #> compression_ord
   209           val cand_ord = pairself cand_key #> compression_ord
   212 
   210 
   213           fun pop_next_candidate [] = (NONE, [])
   211           fun pop_next_candidate [] = (NONE, [])
   214             | pop_next_candidate (cands as (cand :: cands')) =
   212             | pop_next_candidate (cands as (cand :: cands')) =
   215               let
   213               fold (fn x => fn y => if cand_ord (x, y) = GREATER then x else y) cands' cand
   216                 val best as (i, _, _) =
   214               |> (fn best => (SOME best, remove (op =) best cands))
   217                   fold (fn x => fn y => if cand_ord (x, y) = GREATER then x else y) cands' cand
       
   218               in (SOME best, filter_out (fn (j, _, _) => j = i) cands) end
       
   219 
   215 
   220           val candidates =
   216           val candidates =
   221             let
   217             let
   222               fun add_cand (i, Prove (_, _, l, t, _, _, _, _)) = cons (i, l, size_of_term t)
   218               fun add_cand (i, Prove (_, _, l, t, _, _, _, _)) = cons (i, l, size_of_term t)
   223                 | add_cand _ = I
   219                 | add_cand _ = I
   224             in
   220             in
   225               (steps
   221               (* the very last step is not a candidate *)
   226                |> split_last |> fst (* keep last step *)
   222               (steps |> split_last |> fst |> fold_index add_cand) []
   227                |> fold_index add_cand) []
       
   228             end
   223             end
   229 
   224 
   230           fun try_eliminate (i, l, _) labels steps =
   225           fun try_eliminate (i, l, _) labels steps =
   231             let
   226             let
   232               val ((cand as Prove (_, _, _, _, _, (lfs, _), _, _)) :: steps') = drop i steps
   227               val ((cand as Prove (_, _, _, _, _, (lfs, _), _, _)) :: steps') = drop i steps
   269             if not (compress_further ()) then
   264             if not (compress_further ()) then
   270               steps
   265               steps
   271             else
   266             else
   272               (case pop_next_candidate candidates of
   267               (case pop_next_candidate candidates of
   273                 (NONE, _) => steps (* no more candidates for elimination *)
   268                 (NONE, _) => steps (* no more candidates for elimination *)
   274               | (SOME (cand as (_, l, _)), candidates) =>
   269               | (SOME (cand as (i, l, _)), candidates') =>
   275                 let val successors = get_successors l in
   270                 let val successors = get_successors l in
   276                   if length successors > compress_degree then steps
   271                   if length successors > compress_degree then steps
   277                   else compression_loop candidates (try_eliminate cand successors steps)
   272                   else compression_loop candidates' (try_eliminate cand successors steps)
   278                 end)
   273                 end)
   279         in
   274         in
   280           compression_loop candidates steps
   275           compression_loop candidates steps
   281           |> remove (op =) dummy_isar_step
   276           |> remove (op =) dummy_isar_step
   282         end
   277         end