src/HOL/Tools/Sledgehammer/sledgehammer_isar_compress.ML
changeset 55223 3c593bad6b31
parent 55221 ee90eebb8b73
child 55243 66709d41601e
equal deleted inserted replaced
55222:a4ef6eb1fc20 55223:3c593bad6b31
    77     (case do_steps steps (rev updates) of
    77     (case do_steps steps (rev updates) of
    78       (steps, []) => steps
    78       (steps, []) => steps
    79     | _ => raise Fail "Sledgehammer_Isar_Compress: update_steps")
    79     | _ => raise Fail "Sledgehammer_Isar_Compress: update_steps")
    80   end
    80   end
    81 
    81 
    82 (* Tries merging the first step into the second step. Arbitrarily picks the second step's method. *)
    82 (* Tries merging the first step into the second step.
       
    83    FIXME: Arbitrarily picks the second step's method. *)
    83 fun try_merge (Prove (_, [], lbl1, _, [], ((lfs1, gfs1), _)))
    84 fun try_merge (Prove (_, [], lbl1, _, [], ((lfs1, gfs1), _)))
    84       (Prove (qs2, fix, lbl2, t, subproofs, ((lfs2, gfs2), meth2))) =
    85       (Prove (qs2, fix, lbl2, t, subproofs, ((lfs2, gfs2), methss2))) =
    85     let
    86     let
    86       val lfs = remove (op =) lbl1 lfs2 |> union (op =) lfs1
    87       val lfs = remove (op =) lbl1 lfs2 |> union (op =) lfs1
    87       val gfs = union (op =) gfs1 gfs2
    88       val gfs = union (op =) gfs1 gfs2
    88     in
    89     in
    89       SOME (Prove (qs2, fix, lbl2, t, subproofs, ((lfs, gfs), meth2)))
    90       SOME (Prove (qs2, fix, lbl2, t, subproofs, ((lfs, gfs), methss2)))
    90     end
    91     end
    91   | try_merge _ _ = NONE
    92   | try_merge _ _ = NONE
    92 
    93 
    93 val compress_degree = 2
    94 val compress_degree = 2
    94 val merge_timeout_slack = 1.2
    95 val merge_timeout_slack = 1.2
   134           (get_successors, replace_successor)
   135           (get_successors, replace_successor)
   135         end
   136         end
   136 
   137 
   137       (** elimination of trivial, one-step subproofs **)
   138       (** elimination of trivial, one-step subproofs **)
   138 
   139 
   139       fun elim_subproofs' time qs fix l t lfs gfs meth subs nontriv_subs =
   140       fun elim_subproofs' time qs fix l t lfs gfs (methss as (meth :: _) :: _) subs nontriv_subs =
   140         if null subs orelse not (compress_further ()) then
   141         if null subs orelse not (compress_further ()) then
   141           (set_preplay_outcome l (Played time);
   142           (set_preplay_outcome l meth (Played time);
   142            Prove (qs, fix, l, t, List.revAppend (nontriv_subs, subs), ((lfs, gfs), meth)))
   143            Prove (qs, fix, l, t, List.revAppend (nontriv_subs, subs), ((lfs, gfs), methss)))
   143         else
   144         else
   144           (case subs of
   145           (case subs of
   145             (sub as Proof (_, assms, sub_steps)) :: subs =>
   146             (sub as Proof (_, assms, sub_steps)) :: subs =>
   146             (let
   147             (let
   147               (* trivial subproofs have exactly one Prove step *)
   148               (* trivial subproofs have exactly one "Prove" step *)
   148               val SOME (Prove (_, [], l', _, [], ((lfs', gfs'), _))) = try the_single sub_steps
   149               val SOME (Prove (_, [], l', _, [], ((lfs', gfs'), (meth' :: _) :: _))) =
       
   150                 try the_single sub_steps
   149 
   151 
   150               (* only touch proofs that can be preplayed sucessfully *)
   152               (* only touch proofs that can be preplayed sucessfully *)
   151               val Played time' = preplay_outcome l'
   153               val Played time' = Lazy.force (preplay_outcome l' meth')
   152 
   154 
   153               (* merge steps *)
   155               (* merge steps *)
   154               val subs'' = subs @ nontriv_subs
   156               val subs'' = subs @ nontriv_subs
   155               val lfs'' =
   157               val lfs'' = union (op =) lfs (subtract (op =) (map fst assms) lfs')
   156                 subtract (op =) (map fst assms) lfs'
       
   157                 |> union (op =) lfs
       
   158               val gfs'' = union (op =) gfs' gfs
   158               val gfs'' = union (op =) gfs' gfs
   159               val by = ((lfs'', gfs''), meth)
   159               val by = ((lfs'', gfs''), methss(*FIXME*))
   160               val step'' = Prove (qs, fix, l, t, subs'', by)
   160               val step'' = Prove (qs, fix, l, t, subs'', by)
   161 
   161 
   162               (* check if the modified step can be preplayed fast enough *)
   162               (* check if the modified step can be preplayed fast enough *)
   163               val timeout = time_mult merge_timeout_slack (Time.+(time, time'))
   163               val timeout = time_mult merge_timeout_slack (Time.+(time, time'))
   164               val Played time'' = preplay_quietly timeout step''
   164               val Played time'' = preplay_quietly timeout step''
   165 
       
   166             in
   165             in
   167               decrement_step_count (); (* l' successfully eliminated! *)
   166               decrement_step_count (); (* l' successfully eliminated! *)
   168               map (replace_successor l' [l]) lfs';
   167               map (replace_successor l' [l]) lfs';
   169               elim_subproofs' time'' qs fix l t lfs'' gfs'' meth subs nontriv_subs
   168               elim_subproofs' time'' qs fix l t lfs'' gfs'' methss subs nontriv_subs
   170             end
   169             end
   171             handle Bind =>
   170             handle Bind =>
   172               elim_subproofs' time qs fix l t lfs gfs meth subs (sub :: nontriv_subs))
   171             elim_subproofs' time qs fix l t lfs gfs methss subs (sub :: nontriv_subs))
   173           | _ => raise Fail "Sledgehammer_Isar_Compress: elim_subproofs'")
   172           | _ => raise Fail "Sledgehammer_Isar_Compress: elim_subproofs'")
   174 
   173 
   175       fun elim_subproofs (step as Let _) = step
   174       fun elim_subproofs (step as Let _) = step
   176         | elim_subproofs (step as Prove (qs, fix, l, t, subproofs, ((lfs, gfs), meth))) =
   175         | elim_subproofs (step as Prove (qs, fix, l, t, subproofs,
       
   176             ((lfs, gfs), methss as (meth :: _) :: _))) =
   177           if subproofs = [] then
   177           if subproofs = [] then
   178             step
   178             step
   179           else
   179           else
   180             (case preplay_outcome l of
   180             (case Lazy.force (preplay_outcome l meth) of
   181               Played time => elim_subproofs' time qs fix l t lfs gfs meth subproofs []
   181               Played time => elim_subproofs' time qs fix l t lfs gfs methss subproofs []
   182             | _ => step)
   182             | _ => step)
   183 
   183 
   184       (** top_level compression: eliminate steps by merging them into their successors **)
   184       (** top_level compression: eliminate steps by merging them into their successors **)
   185 
       
   186       fun compress_top_level steps =
   185       fun compress_top_level steps =
   187         let
   186         let
   188           (* (#successors, (size_of_term t, position)) *)
   187           (* (#successors, (size_of_term t, position)) *)
   189           fun cand_key (i, l, t_size) = (get_successors l |> length, (t_size, i))
   188           fun cand_key (i, l, t_size) = (length (get_successors l), (t_size, i))
   190 
   189 
   191           val compression_ord =
   190           val compression_ord =
   192             prod_ord int_ord (prod_ord (int_ord #> rev_order) int_ord)
   191             prod_ord int_ord (prod_ord (int_ord #> rev_order) int_ord)
   193             #> rev_order
   192             #> rev_order
   194 
   193 
   205             let
   204             let
   206               fun add_cand (_, Let _) = I
   205               fun add_cand (_, Let _) = I
   207                 | add_cand (i, Prove (_, _, l, t, _, _)) = cons (i, l, size_of_term t)
   206                 | add_cand (i, Prove (_, _, l, t, _, _)) = cons (i, l, size_of_term t)
   208             in
   207             in
   209               (steps
   208               (steps
   210               |> split_last |> fst (* keep last step *)
   209                |> split_last |> fst (* keep last step *)
   211               |> fold_index add_cand) []
   210                |> fold_index add_cand) []
   212             end
   211             end
   213 
   212 
   214           fun try_eliminate (i, l, _) succ_lbls steps =
   213           fun try_eliminate (i, l, _) succ_lbls steps =
   215             let
   214             let
       
   215               val ((cand as Prove (_, _, l, _, _, ((lfs, _), (meth :: _) :: _))) :: steps') =
       
   216                 drop i steps
       
   217 
       
   218               val succs = collect_successors steps' succ_lbls
       
   219               val succ_meths = map (hd o hd o snd o the o byline_of_isar_step) succs
       
   220 
   216               (* only touch steps that can be preplayed successfully *)
   221               (* only touch steps that can be preplayed successfully *)
   217               val Played time = preplay_outcome l
   222               val Played time = Lazy.force (preplay_outcome l meth)
   218 
   223 
   219               val succ_times = map (preplay_outcome #> (fn Played t => t)) succ_lbls
   224               val succs' = map (try_merge cand #> the) succs
       
   225 
       
   226               val succ_times =
       
   227                 map2 ((fn Played t => t) o Lazy.force oo preplay_outcome) succ_lbls succ_meths
   220               val timeslice = time_mult (1.0 / (Real.fromInt (length succ_lbls))) time
   228               val timeslice = time_mult (1.0 / (Real.fromInt (length succ_lbls))) time
   221               val timeouts =
   229               val timeouts =
   222                 map (curry Time.+ timeslice #> time_mult merge_timeout_slack) succ_times
   230                 map (curry Time.+ timeslice #> time_mult merge_timeout_slack) succ_times
   223 
   231 
   224               val ((cand as Prove (_, _, l, _, _, ((lfs, _), _))) :: steps') = drop i steps
       
   225 
       
   226               (* FIXME: debugging *)
   232               (* FIXME: debugging *)
   227               val _ =
   233               val _ =
   228                 if the (label_of_step cand) <> l then
   234                 if the (label_of_isar_step cand) <> l then
   229                   raise Fail "Sledgehammer_Isar_Compress: try_eliminate"
   235                   raise Fail "Sledgehammer_Isar_Compress: try_eliminate"
   230                 else
   236                 else
   231                   ()
   237                   ()
   232 
       
   233               val succs = collect_successors steps' succ_lbls
       
   234               val succs' = map (try_merge cand #> the) succs
       
   235 
   238 
   236               (* TODO: should be lazy: stop preplaying as soon as one step fails/times out *)
   239               (* TODO: should be lazy: stop preplaying as soon as one step fails/times out *)
   237               val play_outcomes = map2 preplay_quietly timeouts succs'
   240               val play_outcomes = map2 preplay_quietly timeouts succs'
   238 
   241 
   239               (* ensure none of the modified successors timed out *)
   242               (* ensure none of the modified successors timed out *)
   242               val (steps1, _ :: steps2) = chop i steps
   245               val (steps1, _ :: steps2) = chop i steps
   243               (* replace successors with their modified versions *)
   246               (* replace successors with their modified versions *)
   244               val steps2 = update_steps steps2 succs'
   247               val steps2 = update_steps steps2 succs'
   245             in
   248             in
   246               decrement_step_count (); (* candidate successfully eliminated *)
   249               decrement_step_count (); (* candidate successfully eliminated *)
   247               map2 set_preplay_outcome succ_lbls play_outcomes;
   250               map3 set_preplay_outcome succ_lbls succ_meths play_outcomes;
   248               map (replace_successor l succ_lbls) lfs;
   251               map (replace_successor l succ_lbls) lfs;
   249               (* removing the step would mess up the indices -> replace with dummy step instead *)
   252               (* removing the step would mess up the indices -> replace with dummy step instead *)
   250               steps1 @ dummy_isar_step :: steps2
   253               steps1 @ dummy_isar_step :: steps2
   251             end
   254             end
   252             handle Bind => steps
   255             handle Bind => steps