23 (* Generation of the code certificate from the rsp theorem *) |
25 (* Generation of the code certificate from the rsp theorem *) |
24 |
26 |
25 infix 0 MRSL |
27 infix 0 MRSL |
26 |
28 |
27 fun ants MRSL thm = fold (fn rl => fn thm => rl RS thm) ants thm |
29 fun ants MRSL thm = fold (fn rl => fn thm => rl RS thm) ants thm |
|
30 |
|
31 exception FORCE_RTY of typ * term |
28 |
32 |
29 fun get_body_types (Type ("fun", [_, U]), Type ("fun", [_, V])) = get_body_types (U, V) |
33 fun get_body_types (Type ("fun", [_, U]), Type ("fun", [_, V])) = get_body_types (U, V) |
30 | get_body_types (U, V) = (U, V) |
34 | get_body_types (U, V) = (U, V) |
31 |
35 |
32 fun get_binder_types (Type ("fun", [T, U]), Type ("fun", [V, W])) = (T, V) :: get_binder_types (U, W) |
36 fun get_binder_types (Type ("fun", [T, U]), Type ("fun", [V, W])) = (T, V) :: get_binder_types (U, W) |
36 let |
40 let |
37 val thy = Proof_Context.theory_of ctxt |
41 val thy = Proof_Context.theory_of ctxt |
38 val rhs_schematic = singleton (Variable.polymorphic ctxt) rhs |
42 val rhs_schematic = singleton (Variable.polymorphic ctxt) rhs |
39 val rty_schematic = fastype_of rhs_schematic |
43 val rty_schematic = fastype_of rhs_schematic |
40 val match = Sign.typ_match thy (rty_schematic, rty) Vartab.empty |
44 val match = Sign.typ_match thy (rty_schematic, rty) Vartab.empty |
|
45 handle Type.TYPE_MATCH => raise FORCE_RTY (rty, rhs) |
41 in |
46 in |
42 Envir.subst_term_types match rhs_schematic |
47 Envir.subst_term_types match rhs_schematic |
43 end |
48 end |
44 |
49 |
45 fun unabs_def ctxt def = |
50 fun unabs_def ctxt def = |
281 case maybe_proven_rsp_thm of |
286 case maybe_proven_rsp_thm of |
282 SOME _ => Proof.theorem NONE after_qed [] lthy |
287 SOME _ => Proof.theorem NONE after_qed [] lthy |
283 | NONE => Proof.theorem NONE after_qed [[(readable_rsp_tm,[])]] lthy |
288 | NONE => Proof.theorem NONE after_qed [[(readable_rsp_tm,[])]] lthy |
284 end |
289 end |
285 |
290 |
|
291 fun quot_thm_err ctxt (rty, qty) pretty_msg = |
|
292 let |
|
293 val error_msg = cat_lines |
|
294 ["Lifting failed for the following types:", |
|
295 Pretty.string_of (Pretty.block |
|
296 [Pretty.str "Raw type:", Pretty.brk 2, Syntax.pretty_typ ctxt rty]), |
|
297 Pretty.string_of (Pretty.block |
|
298 [Pretty.str "Abstract type:", Pretty.brk 2, Syntax.pretty_typ ctxt qty]), |
|
299 "", |
|
300 (Pretty.string_of (Pretty.block |
|
301 [Pretty.str "Reason:", Pretty.brk 2, pretty_msg]))] |
|
302 in |
|
303 error error_msg |
|
304 end |
|
305 |
|
306 fun force_rty_err ctxt rty rhs = |
|
307 let |
|
308 val error_msg = cat_lines |
|
309 ["Lifting failed for the following term:", |
|
310 Pretty.string_of (Pretty.block |
|
311 [Pretty.str "Term:", Pretty.brk 2, Syntax.pretty_term ctxt rhs]), |
|
312 Pretty.string_of (Pretty.block |
|
313 [Pretty.str "Type:", Pretty.brk 2, Syntax.pretty_typ ctxt (fastype_of rhs)]), |
|
314 "", |
|
315 (Pretty.string_of (Pretty.block |
|
316 [Pretty.str "Reason:", |
|
317 Pretty.brk 2, |
|
318 Pretty.str "The type of the term cannot be instancied to", |
|
319 Pretty.brk 1, |
|
320 Pretty.quote (Syntax.pretty_typ ctxt rty), |
|
321 Pretty.str "."]))] |
|
322 in |
|
323 error error_msg |
|
324 end |
|
325 |
|
326 fun lift_def_cmd_with_err_handling (raw_var, rhs_raw) lthy = |
|
327 (lift_def_cmd (raw_var, rhs_raw) lthy |
|
328 handle Lifting_Term.QUOT_THM (rty, qty, msg) => quot_thm_err lthy (rty, qty) msg) |
|
329 handle FORCE_RTY (rty, rhs) => force_rty_err lthy rty rhs |
|
330 |
286 (* parser and command *) |
331 (* parser and command *) |
287 val liftdef_parser = |
332 val liftdef_parser = |
288 ((Parse.binding -- (@{keyword "::"} |-- (Parse.typ >> SOME) -- Parse.opt_mixfix')) >> Parse.triple2) |
333 ((Parse.binding -- (@{keyword "::"} |-- (Parse.typ >> SOME) -- Parse.opt_mixfix')) >> Parse.triple2) |
289 --| @{keyword "is"} -- Parse.term |
334 --| @{keyword "is"} -- Parse.term |
290 |
335 |
291 val _ = |
336 val _ = |
292 Outer_Syntax.local_theory_to_proof @{command_spec "lift_definition"} |
337 Outer_Syntax.local_theory_to_proof @{command_spec "lift_definition"} |
293 "definition for constants over the quotient type" |
338 "definition for constants over the quotient type" |
294 (liftdef_parser >> lift_def_cmd) |
339 (liftdef_parser >> lift_def_cmd_with_err_handling) |
295 |
340 |
296 |
341 |
297 end; (* structure *) |
342 end; (* structure *) |