20 fixes : (string * typ) list, |
20 fixes : (string * typ) list, |
21 assumptions: (label * term) list, |
21 assumptions: (label * term) list, |
22 steps : isar_step list |
22 steps : isar_step list |
23 } |
23 } |
24 and isar_step = |
24 and isar_step = |
25 Let of term * term | |
25 Let of { |
26 Prove of isar_qualifier list * (string * typ) list * label * term * isar_proof list |
26 lhs : term, |
27 * facts * proof_method list * string |
27 rhs : term |
|
28 } | |
|
29 Prove of { |
|
30 qualifiers : isar_qualifier list, |
|
31 obtains : (string * typ) list, |
|
32 label : label, |
|
33 goal : term, |
|
34 subproofs : isar_proof list, |
|
35 facts : facts, |
|
36 proof_methods : proof_method list, |
|
37 comment : string |
|
38 } |
28 |
39 |
29 val no_label : label |
40 val no_label : label |
30 |
41 |
31 val label_ord : label ord |
42 val label_ord : label ord |
32 val string_of_label : label -> string |
43 val string_of_label : label -> string |
33 val sort_facts : facts -> facts |
44 val sort_facts : facts -> facts |
34 |
45 |
35 val steps_of_isar_proof : isar_proof -> isar_step list |
46 val steps_of_isar_proof : isar_proof -> isar_step list |
36 val isar_proof_with_steps : isar_proof -> isar_step list -> isar_proof |
47 val isar_proof_with_steps : isar_proof -> isar_step list -> isar_proof |
|
48 |
37 val label_of_isar_step : isar_step -> label option |
49 val label_of_isar_step : isar_step -> label option |
38 val facts_of_isar_step : isar_step -> facts |
50 val facts_of_isar_step : isar_step -> facts |
39 val proof_methods_of_isar_step : isar_step -> proof_method list |
51 val proof_methods_of_isar_step : isar_step -> proof_method list |
40 |
52 |
41 val fold_isar_steps : (isar_step -> 'a -> 'a) -> isar_step list -> 'a -> 'a |
53 val fold_isar_steps : (isar_step -> 'a -> 'a) -> isar_step list -> 'a -> 'a |
77 fixes : (string * typ) list, |
89 fixes : (string * typ) list, |
78 assumptions: (label * term) list, |
90 assumptions: (label * term) list, |
79 steps : isar_step list |
91 steps : isar_step list |
80 } |
92 } |
81 and isar_step = |
93 and isar_step = |
82 Let of term * term | |
94 Let of { |
83 Prove of isar_qualifier list * (string * typ) list * label * term * isar_proof list |
95 lhs : term, |
84 * facts * proof_method list * string |
96 rhs : term |
|
97 } | |
|
98 Prove of { |
|
99 qualifiers : isar_qualifier list, |
|
100 obtains : (string * typ) list, |
|
101 label : label, |
|
102 goal : term, |
|
103 subproofs : isar_proof list, |
|
104 facts : facts, |
|
105 proof_methods : proof_method list, |
|
106 comment : string |
|
107 } |
85 |
108 |
86 val no_label = ("", ~1) |
109 val no_label = ("", ~1) |
87 |
110 |
88 (* cf. "label_ord" below *) |
111 (* cf. "label_ord" below *) |
89 val assume_prefix = "a" |
112 val assume_prefix = "a" |
105 |
128 |
106 fun steps_of_isar_proof (Proof {steps, ...}) = steps |
129 fun steps_of_isar_proof (Proof {steps, ...}) = steps |
107 fun isar_proof_with_steps (Proof {fixes, assumptions, ...}) steps = |
130 fun isar_proof_with_steps (Proof {fixes, assumptions, ...}) steps = |
108 Proof {fixes = fixes, assumptions = assumptions, steps = steps} |
131 Proof {fixes = fixes, assumptions = assumptions, steps = steps} |
109 |
132 |
110 fun label_of_isar_step (Prove (_, _, l, _, _, _, _, _)) = SOME l |
133 fun label_of_isar_step (Prove {label, ...}) = SOME label |
111 | label_of_isar_step _ = NONE |
134 | label_of_isar_step _ = NONE |
112 |
135 |
113 fun subproofs_of_isar_step (Prove (_, _, _, _, subs, _, _, _)) = subs |
136 fun subproofs_of_isar_step (Prove {subproofs, ...}) = subproofs |
114 | subproofs_of_isar_step _ = [] |
137 | subproofs_of_isar_step _ = [] |
115 |
138 |
116 fun facts_of_isar_step (Prove (_, _, _, _, _, facts, _, _)) = facts |
139 fun facts_of_isar_step (Prove {facts, ...}) = facts |
117 | facts_of_isar_step _ = ([], []) |
140 | facts_of_isar_step _ = ([], []) |
118 |
141 |
119 fun proof_methods_of_isar_step (Prove (_, _, _, _, _, _, meths, _)) = meths |
142 fun proof_methods_of_isar_step (Prove {proof_methods, ...}) = proof_methods |
120 | proof_methods_of_isar_step _ = [] |
143 | proof_methods_of_isar_step _ = [] |
121 |
144 |
122 fun fold_isar_step f step = |
145 fun fold_isar_step f step = |
123 fold (steps_of_isar_proof #> fold_isar_steps f) (subproofs_of_isar_step step) #> f step |
146 fold (steps_of_isar_proof #> fold_isar_steps f) (subproofs_of_isar_step step) #> f step |
124 and fold_isar_steps f = fold (fold_isar_step f) |
147 and fold_isar_steps f = fold (fold_isar_step f) |
125 |
148 |
126 fun map_isar_steps f = |
149 fun map_isar_steps f = |
127 let |
150 let |
128 fun map_proof (proof as Proof {steps, ...}) = isar_proof_with_steps proof (map map_step steps) |
151 fun map_proof (proof as Proof {steps, ...}) = isar_proof_with_steps proof (map map_step steps) |
129 and map_step (step as Let _) = f step |
152 and map_step (step as Let _) = f step |
130 | map_step (Prove (qs, xs, l, t, subs, facts, meths, comment)) = |
153 | map_step (Prove {qualifiers, obtains, label, goal, subproofs, facts, proof_methods, |
131 f (Prove (qs, xs, l, t, map map_proof subs, facts, meths, comment)) |
154 comment}) = |
|
155 f (Prove { |
|
156 qualifiers = qualifiers, |
|
157 obtains = obtains, |
|
158 label = label, |
|
159 goal = goal, |
|
160 subproofs = map map_proof subproofs, |
|
161 facts = facts, |
|
162 proof_methods = proof_methods, |
|
163 comment = comment}) |
132 in map_proof end |
164 in map_proof end |
133 |
165 |
134 val add_isar_steps = fold_isar_steps (fn Prove _ => Integer.add 1 | _ => I) |
166 val add_isar_steps = fold_isar_steps (fn Prove _ => Integer.add 1 | _ => I) |
135 |
167 |
136 (* canonical proof labels: 1, 2, 3, ... in post traversal order *) |
168 (* canonical proof labels: 1, 2, 3, ... in post traversal order *) |
138 |
170 |
139 structure Canonical_Label_Tab = Table( |
171 structure Canonical_Label_Tab = Table( |
140 type key = label |
172 type key = label |
141 val ord = canonical_label_ord) |
173 val ord = canonical_label_ord) |
142 |
174 |
143 fun comment_isar_step comment_of (Prove (qs, xs, l, t, subs, facts, meths, _)) = |
175 fun comment_isar_step comment_of (Prove {qualifiers, obtains, label, goal, subproofs, facts, |
144 Prove (qs, xs, l, t, subs, facts, meths, comment_of l meths) |
176 proof_methods, ...}) = |
|
177 Prove { |
|
178 qualifiers = qualifiers, |
|
179 obtains = obtains, |
|
180 label = label, |
|
181 goal = goal, |
|
182 subproofs = subproofs, |
|
183 facts = facts, |
|
184 proof_methods = proof_methods, |
|
185 comment = comment_of label proof_methods} |
145 | comment_isar_step _ step = step |
186 | comment_isar_step _ step = step |
146 fun comment_isar_proof comment_of = map_isar_steps (comment_isar_step comment_of) |
187 fun comment_isar_proof comment_of = map_isar_steps (comment_isar_step comment_of) |
147 |
188 |
148 fun chain_qs_lfs NONE lfs = ([], lfs) |
189 fun chain_qs_lfs NONE lfs = ([], lfs) |
149 | chain_qs_lfs (SOME l0) lfs = |
190 | chain_qs_lfs (SOME l0) lfs = |
150 if member (op =) lfs l0 then ([Then], remove (op =) l0 lfs) else ([], lfs) |
191 if member (op =) lfs l0 then ([Then], remove (op =) l0 lfs) else ([], lfs) |
151 |
192 |
152 fun chain_isar_step lbl (Prove (qs, xs, l, t, subs, (lfs, gfs), meths, comment)) = |
193 fun chain_isar_step lbl (Prove {qualifiers, obtains, label, goal, subproofs, |
|
194 facts = (lfs, gfs), proof_methods, comment}) = |
153 let val (qs', lfs) = chain_qs_lfs lbl lfs in |
195 let val (qs', lfs) = chain_qs_lfs lbl lfs in |
154 Prove (qs' @ qs, xs, l, t, map chain_isar_proof subs, (lfs, gfs), meths, comment) |
196 Prove { |
|
197 qualifiers = qs' @ qualifiers, |
|
198 obtains = obtains, |
|
199 label = label, |
|
200 goal = goal, |
|
201 subproofs = map chain_isar_proof subproofs, |
|
202 facts = (lfs, gfs), |
|
203 proof_methods = proof_methods, |
|
204 comment = comment} |
155 end |
205 end |
156 | chain_isar_step _ step = step |
206 | chain_isar_step _ step = step |
157 and chain_isar_steps _ [] = [] |
207 and chain_isar_steps _ [] = [] |
158 | chain_isar_steps prev (i :: is) = |
208 | chain_isar_steps prev (i :: is) = |
159 chain_isar_step prev i :: chain_isar_steps (label_of_isar_step i) is |
209 chain_isar_step prev i :: chain_isar_steps (label_of_isar_step i) is |
165 val used_ls = |
215 val used_ls = |
166 fold_isar_steps (facts_of_isar_step #> fst #> union (op =)) (steps_of_isar_proof proof) [] |
216 fold_isar_steps (facts_of_isar_step #> fst #> union (op =)) (steps_of_isar_proof proof) [] |
167 |
217 |
168 fun kill_label l = if member (op =) used_ls l then l else no_label |
218 fun kill_label l = if member (op =) used_ls l then l else no_label |
169 |
219 |
170 fun kill_step (Prove (qs, xs, l, t, subs, facts, meths, comment)) = |
220 fun kill_step (Prove {qualifiers, obtains, label, goal, subproofs, facts, proof_methods, |
171 Prove (qs, xs, kill_label l, t, map kill_proof subs, facts, meths, comment) |
221 comment}) = |
|
222 Prove { |
|
223 qualifiers = qualifiers, |
|
224 obtains = obtains, |
|
225 label = kill_label label, |
|
226 goal = goal, |
|
227 subproofs = map kill_proof subproofs, |
|
228 facts = facts, |
|
229 proof_methods = proof_methods, |
|
230 comment = comment} |
172 | kill_step step = step |
231 | kill_step step = step |
173 and kill_proof (Proof {fixes, assumptions, steps}) = |
232 and kill_proof (Proof {fixes, assumptions, steps}) = |
174 let |
233 let |
175 val assumptions' = map (apfst kill_label) assumptions |
234 val assumptions' = map (apfst kill_label) assumptions |
176 val steps' = map kill_step steps |
235 val steps' = map kill_step steps |
184 fun relabel_isar_proof_canonically proof = |
243 fun relabel_isar_proof_canonically proof = |
185 let |
244 let |
186 fun next_label l (next, subst) = |
245 fun next_label l (next, subst) = |
187 let val l' = ("", next) in (l', (next + 1, (l, l') :: subst)) end |
246 let val l' = ("", next) in (l', (next + 1, (l, l') :: subst)) end |
188 |
247 |
189 fun relabel_step (Prove (qs, fix, l, t, subs, (lfs, gfs), meths, comment)) |
248 fun relabel_step (Prove {qualifiers, obtains, label, goal, subproofs, facts = (lfs, gfs), |
190 (accum as (_, subst)) = |
249 proof_methods, comment}) (accum as (_, subst)) = |
191 let |
250 let |
192 val lfs' = maps (the_list o AList.lookup (op =) subst) lfs |
251 val lfs' = maps (the_list o AList.lookup (op =) subst) lfs |
193 val ((subs', l'), accum') = accum |
252 val ((subs', l'), accum') = accum |
194 |> fold_map relabel_proof subs |
253 |> fold_map relabel_proof subproofs |
195 ||>> next_label l |
254 ||>> next_label label |
|
255 val prove = Prove { |
|
256 qualifiers = qualifiers, |
|
257 obtains = obtains, |
|
258 label = l', |
|
259 goal = goal, |
|
260 subproofs = subs', |
|
261 facts = (lfs', gfs), |
|
262 proof_methods = proof_methods, |
|
263 comment = comment} |
196 in |
264 in |
197 (Prove (qs, fix, l', t, subs', (lfs', gfs), meths, comment), accum') |
265 (prove, accum') |
198 end |
266 end |
199 | relabel_step step accum = (step, accum) |
267 | relabel_step step accum = (step, accum) |
200 and relabel_proof (Proof {fixes, assumptions, steps}) = |
268 and relabel_proof (Proof {fixes, assumptions, steps}) = |
201 fold_map (fn (l, t) => next_label l #> apfst (rpair t)) assumptions |
269 fold_map (fn (l, t) => next_label l #> apfst (rpair t)) assumptions |
202 ##>> fold_map relabel_step steps |
270 ##>> fold_map relabel_step steps |
214 else |
282 else |
215 let val l' = (replicate_string (depth + 1) prefix, next) in |
283 let val l' = (replicate_string (depth + 1) prefix, next) in |
216 (l', (next + 1, (l, l') :: subst)) |
284 (l', (next + 1, (l, l') :: subst)) |
217 end |
285 end |
218 |
286 |
219 fun relabel_step depth (Prove (qs, xs, l, t, subs, (lfs, gfs), meths, comment)) |
287 fun relabel_step depth (Prove {qualifiers, obtains, label, goal, |
220 (accum as (_, subst)) = |
288 subproofs, facts = (lfs, gfs), proof_methods, comment}) (accum as (_, subst)) = |
221 let |
289 let |
222 val lfs' = maps (the_list o AList.lookup (op =) subst) lfs |
290 val (l', accum' as (_, subst')) = next_label depth have_prefix label accum |
223 val (l', accum' as (_, subst')) = next_label depth have_prefix l accum |
291 val prove = Prove { |
224 val subs' = map (relabel_proof subst' (depth + 1)) subs |
292 qualifiers = qualifiers, |
|
293 obtains = obtains, |
|
294 label = l', |
|
295 goal = goal, |
|
296 subproofs = map (relabel_proof subst' (depth + 1)) subproofs, |
|
297 facts = (maps (the_list o AList.lookup (op =) subst) lfs, gfs), |
|
298 proof_methods = proof_methods, |
|
299 comment = comment} |
225 in |
300 in |
226 (Prove (qs, xs, l', t, subs', (lfs', gfs), meths, comment), accum') |
301 (prove, accum') |
227 end |
302 end |
228 | relabel_step _ step accum = (step, accum) |
303 | relabel_step _ step accum = (step, accum) |
229 and relabel_proof subst depth (Proof {fixes, assumptions, steps}) = |
304 and relabel_proof subst depth (Proof {fixes, assumptions, steps}) = |
230 (1, subst) |
305 (1, subst) |
231 |> fold_map (fn (l, t) => next_label depth assume_prefix l #> apfst (rpair t)) assumptions |
306 |> fold_map (fn (l, t) => next_label depth assume_prefix l #> apfst (rpair t)) assumptions |
248 val ys = map2 pair new_names Ts |
323 val ys = map2 pair new_names Ts |
249 in |
324 in |
250 (ys, ((map Free xs ~~ map Free ys) @ subst, ctxt')) |
325 (ys, ((map Free xs ~~ map Free ys) @ subst, ctxt')) |
251 end |
326 end |
252 |
327 |
253 fun rationalize_step (Prove (qs, xs, l, t, subs, facts, meths, comment)) subst_ctxt = |
328 fun rationalize_step (Prove {qualifiers, obtains, label, goal, subproofs, facts, proof_methods, |
|
329 comment}) subst_ctxt = |
254 let |
330 let |
255 val (xs', subst_ctxt' as (subst', _)) = rename_obtains xs subst_ctxt |
331 val (obtains', subst_ctxt' as (subst', _)) = rename_obtains obtains subst_ctxt |
256 val t' = subst_atomic subst' t |
332 val prove = Prove { |
257 val subs' = map (rationalize_proof false subst_ctxt') subs |
333 qualifiers = qualifiers, |
|
334 obtains = obtains', |
|
335 label = label, |
|
336 goal = subst_atomic subst' goal, |
|
337 subproofs = map (rationalize_proof false subst_ctxt') subproofs, |
|
338 facts = facts, |
|
339 proof_methods = proof_methods, |
|
340 comment = comment} |
258 in |
341 in |
259 (Prove (qs, xs', l, t', subs', facts, meths, comment), subst_ctxt') |
342 (prove, subst_ctxt') |
260 end |
343 end |
261 and rationalize_proof outer (subst_ctxt as (subst, ctxt)) (Proof {fixes, assumptions, steps}) = |
344 and rationalize_proof outer (subst_ctxt as (subst, ctxt)) (Proof {fixes, assumptions, steps}) = |
262 let |
345 let |
263 val (fixes', subst_ctxt' as (subst', _)) = |
346 val (fixes', subst_ctxt' as (subst', _)) = |
264 if outer then |
347 if outer then |
365 | of_subproofs ind ctxt qs subs = |
448 | of_subproofs ind ctxt qs subs = |
366 (if member (op =) qs Then then of_moreover ind else "") ^ |
449 (if member (op =) qs Then then of_moreover ind else "") ^ |
367 space_implode (of_moreover ind) (map (of_subproof ind ctxt) subs) |
450 space_implode (of_moreover ind) (map (of_subproof ind ctxt) subs) |
368 and add_step_pre ind qs subs (s, ctxt) = |
451 and add_step_pre ind qs subs (s, ctxt) = |
369 (s ^ of_subproofs ind ctxt qs subs ^ of_indent ind, ctxt) |
452 (s ^ of_subproofs ind ctxt qs subs ^ of_indent ind, ctxt) |
370 and add_step ind (Let (t1, t2)) = |
453 and add_step ind (Let {lhs = t1, rhs = t2}) = |
371 add_str (of_indent ind ^ "let ") #> add_term t1 #> add_str " = " #> add_term t2 |
454 add_str (of_indent ind ^ "let ") #> add_term t1 #> add_str " = " #> add_term t2 |
372 #> add_str "\n" |
455 #> add_str "\n" |
373 | add_step ind (Prove (qs, xs, l, t, subs, (ls, ss), meth :: _, comment)) = |
456 | add_step ind (Prove {qualifiers, obtains, label, goal, subproofs, facts = (ls, ss), |
374 add_step_pre ind qs subs |
457 proof_methods = meth :: _, comment}) = |
375 #> (case xs of |
458 let val num_subproofs = length subproofs in |
376 [] => add_str (of_have qs (length subs) ^ " ") |
459 add_step_pre ind qualifiers subproofs |
377 | _ => |
460 #> (case obtains of |
378 add_str (of_obtain qs (length subs) ^ " ") |
461 [] => add_str (of_have qualifiers num_subproofs ^ " ") |
379 #> add_frees xs |
462 | _ => |
380 #> add_str (" where\n" ^ of_indent (ind + 1))) |
463 add_str (of_obtain qualifiers num_subproofs ^ " ") |
381 #> add_str (of_label l) |
464 #> add_frees obtains |
382 #> add_term (if is_thesis ctxt t then HOLogic.mk_Trueprop (Var thesis_var) else t) |
465 #> add_str (" where\n" ^ of_indent (ind + 1))) |
383 #> add_str ("\n" ^ of_indent (ind + 1) ^ of_method ls ss meth ^ |
466 #> add_str (of_label label) |
384 (if comment = "" then "" else " (* " ^ comment ^ " *)") ^ "\n") |
467 #> add_term (if is_thesis ctxt goal then HOLogic.mk_Trueprop (Var thesis_var) else goal) |
|
468 #> add_str ("\n" ^ of_indent (ind + 1) ^ of_method ls ss meth ^ |
|
469 (if comment = "" then "" else " (* " ^ comment ^ " *)") ^ "\n") |
|
470 end |
385 and add_steps ind = fold (add_step ind) |
471 and add_steps ind = fold (add_step ind) |
386 and of_proof ind ctxt (Proof {fixes, assumptions, steps}) = |
472 and of_proof ind ctxt (Proof {fixes, assumptions, steps}) = |
387 ("", ctxt) |
473 ("", ctxt) |
388 |> add_fix ind fixes |
474 |> add_fix ind fixes |
389 |> fold (add_assm ind) assumptions |
475 |> fold (add_assm ind) assumptions |