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 *) |