22 |
26 |
23 infix 0 MRSL |
27 infix 0 MRSL |
24 |
28 |
25 exception SETUP_LIFTING_INFR of string |
29 exception SETUP_LIFTING_INFR of string |
26 |
30 |
27 fun define_crel rep_fun lthy = |
31 (* Config *) |
|
32 |
|
33 type config = { notes: bool }; |
|
34 val default_config = { notes = true }; |
|
35 |
|
36 fun define_crel config rep_fun lthy = |
28 let |
37 let |
29 val (qty, rty) = (dest_funT o fastype_of) rep_fun |
38 val (qty, rty) = (dest_funT o fastype_of) rep_fun |
30 val rep_fun_graph = (HOLogic.eq_const rty) $ Bound 1 $ (rep_fun $ Bound 0) |
39 val rep_fun_graph = (HOLogic.eq_const rty) $ Bound 1 $ (rep_fun $ Bound 0) |
31 val def_term = Abs ("x", rty, Abs ("y", qty, rep_fun_graph)) |
40 val def_term = Abs ("x", rty, Abs ("y", qty, rep_fun_graph)) |
32 val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty |
41 val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty |
33 val crel_name = Binding.prefix_name "cr_" qty_name |
42 val crel_name = Binding.prefix_name "cr_" qty_name |
34 val (fixed_def_term, lthy') = yield_singleton (Variable.importT_terms) def_term lthy |
43 val (fixed_def_term, lthy) = yield_singleton (Variable.importT_terms) def_term lthy |
35 val ((_, (_ , def_thm)), lthy'') = |
44 val ((_, (_ , def_thm)), lthy) = if #notes config then |
36 Local_Theory.define ((crel_name, NoSyn), ((Thm.def_binding crel_name, []), fixed_def_term)) lthy' |
45 Local_Theory.define ((crel_name, NoSyn), ((Thm.def_binding crel_name, []), fixed_def_term)) lthy |
37 in |
46 else |
38 (def_thm, lthy'') |
47 Local_Theory.define ((Binding.concealed crel_name, NoSyn), ((Binding.empty, []), fixed_def_term)) lthy |
|
48 in |
|
49 (def_thm, lthy) |
39 end |
50 end |
40 |
51 |
41 fun print_define_pcrel_warning msg = |
52 fun print_define_pcrel_warning msg = |
42 let |
53 let |
43 val warning_msg = cat_lines |
54 val warning_msg = cat_lines |
65 val rty = (domain_type o fastype_of) param_rel_fixed |
76 val rty = (domain_type o fastype_of) param_rel_fixed |
66 val relcomp_op = Const (@{const_name "relcompp"}, |
77 val relcomp_op = Const (@{const_name "relcompp"}, |
67 (rty --> rty' --> HOLogic.boolT) --> |
78 (rty --> rty' --> HOLogic.boolT) --> |
68 (rty' --> qty --> HOLogic.boolT) --> |
79 (rty' --> qty --> HOLogic.boolT) --> |
69 rty --> qty --> HOLogic.boolT) |
80 rty --> qty --> HOLogic.boolT) |
70 val relator_type = foldr1 (op -->) ((map type_of args_fixed) @ [rty, qty, HOLogic.boolT]) |
|
71 val qty_name = (fst o dest_Type) qty |
81 val qty_name = (fst o dest_Type) qty |
72 val pcrel_name = Binding.prefix_name "pcr_" ((Binding.name o Long_Name.base_name) qty_name) |
82 val pcrel_name = Binding.prefix_name "pcr_" ((Binding.name o Long_Name.base_name) qty_name) |
|
83 val relator_type = foldr1 (op -->) ((map type_of args_fixed) @ [rty, qty, HOLogic.boolT]) |
73 val lhs = Library.foldl (op $) ((Free (Binding.name_of pcrel_name, relator_type)), args_fixed) |
84 val lhs = Library.foldl (op $) ((Free (Binding.name_of pcrel_name, relator_type)), args_fixed) |
74 val rhs = relcomp_op $ param_rel_fixed $ fixed_crel |
85 val rhs = relcomp_op $ param_rel_fixed $ fixed_crel |
75 val definition_term = Logic.mk_equals (lhs, rhs) |
86 val definition_term = Logic.mk_equals (lhs, rhs) |
76 val ((_, (_, def_thm)), lthy) = Specification.definition ((SOME (pcrel_name, SOME relator_type, NoSyn)), |
87 fun note_def lthy = |
77 ((Binding.empty, []), definition_term)) lthy |
88 Specification.definition ((SOME (pcrel_name, SOME relator_type, NoSyn)), |
|
89 ((Binding.empty, []), definition_term)) lthy |>> (snd #> snd); |
|
90 fun raw_def lthy = |
|
91 let |
|
92 val ((_, rhs), prove) = Local_Defs.derived_def lthy true definition_term; |
|
93 val ((_, (_, raw_th)), lthy) = lthy |
|
94 |> Local_Theory.define ((Binding.concealed pcrel_name, NoSyn), ((Binding.empty, []), rhs)); |
|
95 val th = prove lthy raw_th; |
|
96 in |
|
97 (th, lthy) |
|
98 end |
|
99 val (def_thm, lthy) = if #notes config then note_def lthy else raw_def lthy |
78 in |
100 in |
79 (SOME def_thm, lthy) |
101 (SOME def_thm, lthy) |
80 end |
102 end |
81 handle Lifting_Term.PARAM_QUOT_THM (_, msg) => (print_define_pcrel_warning msg; (NONE, lthy)) |
103 handle Lifting_Term.PARAM_QUOT_THM (_, msg) => (print_define_pcrel_warning msg; (NONE, lthy)) |
82 |
104 |
227 in |
249 in |
228 lthy |
250 lthy |
229 |> Local_Theory.declaration {syntax = false, pervasive = true} |
251 |> Local_Theory.declaration {syntax = false, pervasive = true} |
230 (fn phi => Lifting_Info.init_restore_data bundle_name (phi_qinfo phi)) |
252 (fn phi => Lifting_Info.init_restore_data bundle_name (phi_qinfo phi)) |
231 |> Bundle.bundle ((binding, [restore_lifting_att])) [] |
253 |> Bundle.bundle ((binding, [restore_lifting_att])) [] |
232 end |
254 |> pair binding |
233 |
255 end |
234 fun setup_lifting_infr quot_thm opt_reflp_thm lthy = |
256 |
|
257 fun setup_lifting_infr config quot_thm opt_reflp_thm lthy = |
235 let |
258 let |
236 val _ = quot_thm_sanity_check lthy quot_thm |
259 val _ = quot_thm_sanity_check lthy quot_thm |
237 val (_, qty) = quot_thm_rty_qty quot_thm |
260 val (_, qty) = quot_thm_rty_qty quot_thm |
238 val (pcrel_def, lthy) = define_pcrel (quot_thm_crel quot_thm) lthy |
261 val (pcrel_def, lthy) = define_pcrel config (quot_thm_crel quot_thm) lthy |
239 (**) |
262 (**) |
240 val pcrel_def = Option.map (Morphism.thm (Local_Theory.target_morphism lthy)) pcrel_def |
263 val pcrel_def = Option.map (Morphism.thm (Local_Theory.target_morphism lthy)) pcrel_def |
241 (**) |
264 (**) |
242 val (pcr_cr_eq, lthy) = case pcrel_def of |
265 val (pcr_cr_eq, lthy) = case pcrel_def of |
243 SOME pcrel_def => apfst SOME (define_pcr_cr_eq lthy pcrel_def) |
266 SOME pcrel_def => apfst SOME (define_pcr_cr_eq config lthy pcrel_def) |
244 | NONE => (NONE, lthy) |
267 | NONE => (NONE, lthy) |
245 val pcr_info = case pcrel_def of |
268 val pcr_info = case pcrel_def of |
246 SOME pcrel_def => SOME { pcrel_def = pcrel_def, pcr_cr_eq = the pcr_cr_eq } |
269 SOME pcrel_def => SOME { pcrel_def = pcrel_def, pcr_cr_eq = the pcr_cr_eq } |
247 | NONE => NONE |
270 | NONE => NONE |
248 val quotients = { quot_thm = quot_thm, pcr_info = pcr_info } |
271 val quotients = { quot_thm = quot_thm, pcr_info = pcr_info } |
457 val thm = |
480 val thm = |
458 (left_total RS @{thm pcr_Domainp_total}) |
481 (left_total RS @{thm pcr_Domainp_total}) |
459 |> fold_Domainp_pcrel pcrel_def |
482 |> fold_Domainp_pcrel pcrel_def |
460 |> reduce_Domainp ctxt (Transfer.get_relator_domain ctxt) |
483 |> reduce_Domainp ctxt (Transfer.get_relator_domain ctxt) |
461 in |
484 in |
462 [("domain", thm)] |
485 [("domain", [thm], @{attributes [transfer_domain_rule]})] |
463 end |
486 end |
464 |
487 |
465 end |
488 end |
466 |
489 |
467 fun get_pcrel_info ctxt qty_full_name = |
490 fun get_pcrel_info ctxt qty_full_name = |
468 #pcr_info (the (Lifting_Info.lookup_quotients ctxt qty_full_name)) |
491 #pcr_info (the (Lifting_Info.lookup_quotients ctxt qty_full_name)) |
469 |
492 |
470 fun get_Domainp_thm quot_thm = |
493 fun get_Domainp_thm quot_thm = |
471 the (get_first (try(curry op RS quot_thm)) [@{thm eq_onp_to_Domainp}, @{thm Quotient_to_Domainp}]) |
494 the (get_first (try(curry op RS quot_thm)) [@{thm eq_onp_to_Domainp}, @{thm Quotient_to_Domainp}]) |
|
495 |
|
496 fun notes names thms = |
|
497 let |
|
498 val notes = |
|
499 if names then map (fn (name, thms, attrs) => ((name, []), [(thms, attrs)])) thms |
|
500 else map_filter (fn (_, thms, attrs) => if null attrs then NONE |
|
501 else SOME ((Binding.empty, []), [(thms, attrs)])) thms |
|
502 in |
|
503 Local_Theory.notes notes #> snd |
|
504 end |
|
505 |
|
506 fun map_thms map_name map_thm thms = |
|
507 map (fn (name, thms, attr) => (map_name name, map map_thm thms, attr)) thms |
472 |
508 |
473 (* |
509 (* |
474 Sets up the Lifting package by a quotient theorem. |
510 Sets up the Lifting package by a quotient theorem. |
475 |
511 |
476 quot_thm - a quotient theorem (Quotient R Abs Rep T) |
512 quot_thm - a quotient theorem (Quotient R Abs Rep T) |
477 opt_reflp_thm - a theorem saying that a relation from quot_thm is reflexive |
513 opt_reflp_thm - a theorem saying that a relation from quot_thm is reflexive |
478 (in the form "reflp R") |
514 (in the form "reflp R") |
479 opt_par_thm - a parametricity theorem for R |
515 opt_par_thm - a parametricity theorem for R |
480 *) |
516 *) |
481 |
517 |
482 fun setup_by_quotient quot_thm opt_reflp_thm opt_par_thm lthy = |
518 fun setup_by_quotient config quot_thm opt_reflp_thm opt_par_thm lthy = |
483 let |
519 let |
484 (**) |
520 (**) |
485 val quot_thm = Morphism.thm (Local_Theory.target_morphism lthy) quot_thm |
521 val quot_thm = Morphism.thm (Local_Theory.target_morphism lthy) quot_thm |
486 (**) |
522 (**) |
487 val transfer_attr = Attrib.internal (K Transfer.transfer_add) |
|
488 val transfer_domain_attr = Attrib.internal (K Transfer.transfer_domain_add) |
|
489 val (rty, qty) = quot_thm_rty_qty quot_thm |
523 val (rty, qty) = quot_thm_rty_qty quot_thm |
490 val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty)))) |
524 val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty)))) |
491 val qty_full_name = (fst o dest_Type) qty |
525 val qty_full_name = (fst o dest_Type) qty |
492 val qty_name = (Binding.name o Long_Name.base_name) qty_full_name |
526 val qty_name = (Binding.name o Long_Name.base_name) qty_full_name |
493 fun qualify suffix = Binding.qualified true suffix qty_name |
527 fun qualify suffix = Binding.qualified true suffix qty_name |
494 val lthy = case opt_reflp_thm of |
528 val notes1 = case opt_reflp_thm of |
495 SOME reflp_thm => |
529 SOME reflp_thm => |
496 let |
530 let |
497 val thms = |
531 val thms = |
498 [("abs_induct", @{thm Quotient_total_abs_induct}, [induct_attr]), |
532 [("abs_induct", @{thms Quotient_total_abs_induct}, [induct_attr]), |
499 ("abs_eq_iff", @{thm Quotient_total_abs_eq_iff}, [] )] |
533 ("abs_eq_iff", @{thms Quotient_total_abs_eq_iff}, [] )] |
500 in |
534 in |
501 lthy |
535 map_thms qualify (fn thm => [quot_thm, reflp_thm] MRSL thm) thms |
502 |> fold (fn (name, thm, attr) => (snd oo Local_Theory.note) ((qualify name, attr), |
|
503 [[quot_thm, reflp_thm] MRSL thm])) thms |
|
504 end |
536 end |
505 | NONE => |
537 | NONE => |
506 let |
538 let |
507 val thms = |
539 val thms = |
508 [("abs_induct", @{thm Quotient_abs_induct}, [induct_attr])] |
540 [("abs_induct", @{thms Quotient_abs_induct}, [induct_attr])] |
509 in |
541 in |
510 fold (fn (name, thm, attr) => (snd oo Local_Theory.note) ((qualify name, attr), |
542 map_thms qualify (fn thm => quot_thm RS thm) thms |
511 [quot_thm RS thm])) thms lthy |
|
512 end |
543 end |
513 val dom_thm = get_Domainp_thm quot_thm |
544 val dom_thm = get_Domainp_thm quot_thm |
514 |
545 |
515 fun setup_transfer_rules_nonpar lthy = |
546 fun setup_transfer_rules_nonpar notes = |
516 let |
547 let |
517 val lthy = |
548 val notes1 = |
518 case opt_reflp_thm of |
549 case opt_reflp_thm of |
519 SOME reflp_thm => |
550 SOME reflp_thm => |
520 let |
551 let |
521 val thms = |
552 val thms = |
522 [("id_abs_transfer",@{thm Quotient_id_abs_transfer}), |
553 [("id_abs_transfer",@{thms Quotient_id_abs_transfer}, @{attributes [transfer_rule]}), |
523 ("left_total", @{thm Quotient_left_total} ), |
554 ("left_total", @{thms Quotient_left_total}, @{attributes [transfer_rule]}), |
524 ("bi_total", @{thm Quotient_bi_total})] |
555 ("bi_total", @{thms Quotient_bi_total}, @{attributes [transfer_rule]})] |
525 in |
556 in |
526 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
557 map_thms qualify (fn thm => [quot_thm, reflp_thm] MRSL thm) thms |
527 [[quot_thm, reflp_thm] MRSL thm])) thms lthy |
|
528 end |
558 end |
529 | NONE => |
559 | NONE => map_thms qualify I [("domain", [dom_thm], @{attributes [transfer_domain_rule]})] |
530 lthy |
560 |
531 |> (snd oo Local_Theory.note) ((qualify "domain", [transfer_domain_attr]), [dom_thm]) |
561 val notes2 = map_thms qualify (fn thm => quot_thm RS thm) |
532 |
562 [("rel_eq_transfer", @{thms Quotient_rel_eq_transfer}, @{attributes [transfer_rule]}), |
533 val thms = |
563 ("right_unique", @{thms Quotient_right_unique}, @{attributes [transfer_rule]}), |
534 [("rel_eq_transfer", @{thm Quotient_rel_eq_transfer}), |
564 ("right_total", @{thms Quotient_right_total}, @{attributes [transfer_rule]})] |
535 ("right_unique", @{thm Quotient_right_unique} ), |
565 in |
536 ("right_total", @{thm Quotient_right_total} )] |
566 notes2 @ notes1 @ notes |
537 in |
|
538 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
|
539 [quot_thm RS thm])) thms lthy |
|
540 end |
567 end |
541 |
568 |
542 fun generate_parametric_rel_eq lthy transfer_rule opt_param_thm = |
569 fun generate_parametric_rel_eq lthy transfer_rule opt_param_thm = |
543 option_fold transfer_rule (Lifting_Def.generate_parametric_transfer_rule lthy transfer_rule) opt_param_thm |
570 option_fold transfer_rule (Lifting_Def.generate_parametric_transfer_rule lthy transfer_rule) opt_param_thm |
544 handle Lifting_Term.MERGE_TRANSFER_REL msg => |
571 handle Lifting_Term.MERGE_TRANSFER_REL msg => |
566 (Lifting_Term.parametrize_transfer_rule lthy |
593 (Lifting_Term.parametrize_transfer_rule lthy |
567 ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer})) |
594 ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer})) |
568 val left_total = parametrize_class_constraint lthy pcrel_def left_total |
595 val left_total = parametrize_class_constraint lthy pcrel_def left_total |
569 val bi_total = parametrize_class_constraint lthy pcrel_def bi_total |
596 val bi_total = parametrize_class_constraint lthy pcrel_def bi_total |
570 val thms = |
597 val thms = |
571 [("id_abs_transfer",id_abs_transfer), |
598 [("id_abs_transfer", [id_abs_transfer], @{attributes [transfer_rule]}), |
572 ("left_total", left_total ), |
599 ("left_total", [left_total], @{attributes [transfer_rule]}), |
573 ("bi_total", bi_total )] |
600 ("bi_total", [bi_total], @{attributes [transfer_rule]})] |
574 in |
601 in |
575 lthy |
602 map_thms qualify I thms @ map_thms qualify I domain_thms |
576 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
|
577 [thm])) thms |
|
578 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), |
|
579 [thm])) domain_thms |
|
580 end |
603 end |
581 | NONE => |
604 | NONE => |
582 let |
605 let |
583 val thms = parametrize_domain dom_thm pcrel_info lthy |
606 val thms = parametrize_domain dom_thm pcrel_info lthy |
584 in |
607 in |
585 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), |
608 map_thms qualify I thms |
586 [thm])) thms lthy |
|
587 end |
609 end |
588 |
610 |
589 val rel_eq_transfer = generate_parametric_rel_eq lthy |
611 val rel_eq_transfer = generate_parametric_rel_eq lthy |
590 (Lifting_Term.parametrize_transfer_rule lthy (quot_thm RS @{thm Quotient_rel_eq_transfer})) |
612 (Lifting_Term.parametrize_transfer_rule lthy (quot_thm RS @{thm Quotient_rel_eq_transfer})) |
591 opt_par_thm |
613 opt_par_thm |
592 val right_unique = parametrize_class_constraint lthy pcrel_def |
614 val right_unique = parametrize_class_constraint lthy pcrel_def |
593 (quot_thm RS @{thm Quotient_right_unique}) |
615 (quot_thm RS @{thm Quotient_right_unique}) |
594 val right_total = parametrize_class_constraint lthy pcrel_def |
616 val right_total = parametrize_class_constraint lthy pcrel_def |
595 (quot_thm RS @{thm Quotient_right_total}) |
617 (quot_thm RS @{thm Quotient_right_total}) |
596 val thms = |
618 val notes2 = map_thms qualify I |
597 [("rel_eq_transfer", rel_eq_transfer), |
619 [("rel_eq_transfer", [rel_eq_transfer], @{attributes [transfer_rule]}), |
598 ("right_unique", right_unique ), |
620 ("right_unique", [right_unique], @{attributes [transfer_rule]}), |
599 ("right_total", right_total )] |
621 ("right_total", [right_total], @{attributes [transfer_rule]})] |
600 in |
622 in |
601 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
623 notes2 @ notes1 @ notes |
602 [thm])) thms lthy |
624 end |
603 end |
625 |
604 |
626 fun setup_rules lthy = |
605 fun setup_transfer_rules lthy = |
627 let |
606 if is_some (get_pcrel_info lthy qty_full_name) then setup_transfer_rules_par lthy |
628 val thms = if is_some (get_pcrel_info lthy qty_full_name) |
607 else setup_transfer_rules_nonpar lthy |
629 then setup_transfer_rules_par lthy notes1 else setup_transfer_rules_nonpar notes1 |
|
630 in |
|
631 notes (#notes config) thms lthy |
|
632 end |
608 in |
633 in |
609 lthy |
634 lthy |
610 |> setup_lifting_infr quot_thm opt_reflp_thm |
635 |> setup_lifting_infr config quot_thm opt_reflp_thm |
611 |> setup_transfer_rules |
636 ||> setup_rules |
612 end |
637 end |
613 |
638 |
614 (* |
639 (* |
615 Sets up the Lifting package by a typedef theorem. |
640 Sets up the Lifting package by a typedef theorem. |
616 |
641 |
617 gen_code - flag if an abstract type given by typedef_thm should be registred |
642 gen_code - flag if an abstract type given by typedef_thm should be registred |
618 as an abstract type in the code generator |
643 as an abstract type in the code generator |
619 typedef_thm - a typedef theorem (type_definition Rep Abs S) |
644 typedef_thm - a typedef theorem (type_definition Rep Abs S) |
620 *) |
645 *) |
621 |
646 |
622 fun setup_by_typedef_thm typedef_thm lthy = |
647 fun setup_by_typedef_thm config typedef_thm lthy = |
623 let |
648 let |
624 val transfer_attr = Attrib.internal (K Transfer.transfer_add) |
|
625 val transfer_domain_attr = Attrib.internal (K Transfer.transfer_domain_add) |
|
626 val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o Thm.prop_of) typedef_thm |
649 val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o Thm.prop_of) typedef_thm |
627 val (T_def, lthy) = define_crel rep_fun lthy |
650 val (T_def, lthy) = define_crel config rep_fun lthy |
628 (**) |
651 (**) |
629 val T_def = Morphism.thm (Local_Theory.target_morphism lthy) T_def |
652 val T_def = Morphism.thm (Local_Theory.target_morphism lthy) T_def |
630 (**) |
653 (**) |
631 val quot_thm = case typedef_set of |
654 val quot_thm = case typedef_set of |
632 Const (@{const_name top}, _) => |
655 Const (@{const_name top}, _) => |
644 Const (@{const_name top}, _) => |
667 Const (@{const_name top}, _) => |
645 SOME ((typedef_thm RS @{thm UNIV_typedef_to_equivp}) RS @{thm equivp_reflp2}) |
668 SOME ((typedef_thm RS @{thm UNIV_typedef_to_equivp}) RS @{thm equivp_reflp2}) |
646 | _ => NONE |
669 | _ => NONE |
647 val dom_thm = get_Domainp_thm quot_thm |
670 val dom_thm = get_Domainp_thm quot_thm |
648 |
671 |
649 fun setup_transfer_rules_nonpar lthy = |
672 fun setup_transfer_rules_nonpar notes = |
650 let |
673 let |
651 val lthy = |
674 val notes1 = |
652 case opt_reflp_thm of |
675 case opt_reflp_thm of |
653 SOME reflp_thm => |
676 SOME reflp_thm => |
654 let |
677 let |
655 val thms = |
678 val thms = |
656 [("id_abs_transfer",@{thm Quotient_id_abs_transfer}), |
679 [("id_abs_transfer",@{thms Quotient_id_abs_transfer}, @{attributes [transfer_rule]}), |
657 ("left_total", @{thm Quotient_left_total} ), |
680 ("left_total", @{thms Quotient_left_total}, @{attributes [transfer_rule]}), |
658 ("bi_total", @{thm Quotient_bi_total} )] |
681 ("bi_total", @{thms Quotient_bi_total}, @{attributes [transfer_rule]})] |
659 in |
682 in |
660 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
683 map_thms qualify (fn thm => [quot_thm, reflp_thm] MRSL thm) thms |
661 [[quot_thm, reflp_thm] MRSL thm])) thms lthy |
|
662 end |
684 end |
663 | NONE => |
685 | NONE => |
664 lthy |
686 map_thms qualify I [("domain", [dom_thm], @{attributes [transfer_domain_rule]})] |
665 |> (snd oo Local_Theory.note) ((qualify "domain", [transfer_domain_attr]), [dom_thm]) |
|
666 val thms = |
687 val thms = |
667 [("rep_transfer", @{thm typedef_rep_transfer}), |
688 [("rep_transfer", @{thms typedef_rep_transfer}, @{attributes [transfer_rule]}), |
668 ("left_unique", @{thm typedef_left_unique} ), |
689 ("left_unique", @{thms typedef_left_unique}, @{attributes [transfer_rule]}), |
669 ("right_unique", @{thm typedef_right_unique}), |
690 ("right_unique", @{thms typedef_right_unique}, @{attributes [transfer_rule]}), |
670 ("right_total", @{thm typedef_right_total} ), |
691 ("right_total", @{thms typedef_right_total}, @{attributes [transfer_rule]}), |
671 ("bi_unique", @{thm typedef_bi_unique} )] |
692 ("bi_unique", @{thms typedef_bi_unique}, @{attributes [transfer_rule]})] |
672 in |
693 in |
673 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
694 map_thms qualify (fn thm => [typedef_thm, T_def] MRSL thm) thms @ notes1 @ notes |
674 [[typedef_thm, T_def] MRSL thm])) thms lthy |
695 end |
675 end |
696 |
676 |
697 fun setup_transfer_rules_par lthy notes = |
677 fun setup_transfer_rules_par lthy = |
|
678 let |
698 let |
679 val pcrel_info = (the (get_pcrel_info lthy qty_full_name)) |
699 val pcrel_info = (the (get_pcrel_info lthy qty_full_name)) |
680 val pcrel_def = #pcrel_def pcrel_info |
700 val pcrel_def = #pcrel_def pcrel_info |
681 |
701 |
682 val lthy = |
702 val notes1 = |
683 case opt_reflp_thm of |
703 case opt_reflp_thm of |
684 SOME reflp_thm => |
704 SOME reflp_thm => |
685 let |
705 let |
686 val left_total = ([quot_thm, reflp_thm] MRSL @{thm Quotient_left_total}) |
706 val left_total = ([quot_thm, reflp_thm] MRSL @{thm Quotient_left_total}) |
687 val bi_total = ([quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total}) |
707 val bi_total = ([quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total}) |
690 val bi_total = parametrize_class_constraint lthy pcrel_def bi_total |
710 val bi_total = parametrize_class_constraint lthy pcrel_def bi_total |
691 val id_abs_transfer = generate_parametric_id lthy rty |
711 val id_abs_transfer = generate_parametric_id lthy rty |
692 (Lifting_Term.parametrize_transfer_rule lthy |
712 (Lifting_Term.parametrize_transfer_rule lthy |
693 ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer})) |
713 ([quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer})) |
694 val thms = |
714 val thms = |
695 [("left_total", left_total ), |
715 [("left_total", [left_total], @{attributes [transfer_rule]}), |
696 ("bi_total", bi_total ), |
716 ("bi_total", [bi_total], @{attributes [transfer_rule]}), |
697 ("id_abs_transfer",id_abs_transfer)] |
717 ("id_abs_transfer",[id_abs_transfer], @{attributes [transfer_rule]})] |
698 in |
718 in |
699 lthy |
719 map_thms qualify I thms @ map_thms qualify I domain_thms |
700 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
|
701 [thm])) thms |
|
702 |> fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), |
|
703 [thm])) domain_thms |
|
704 end |
720 end |
705 | NONE => |
721 | NONE => |
706 let |
722 let |
707 val thms = parametrize_domain dom_thm pcrel_info lthy |
723 val thms = parametrize_domain dom_thm pcrel_info lthy |
708 in |
724 in |
709 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_domain_attr]), |
725 map_thms qualify I thms |
710 [thm])) thms lthy |
|
711 end |
726 end |
712 |
727 |
713 val thms = |
728 val notes2 = map_thms qualify (fn thm => generate_parametric_id lthy rty |
714 ("rep_transfer", generate_parametric_id lthy rty |
729 (Lifting_Term.parametrize_transfer_rule lthy ([typedef_thm, T_def] MRSL thm))) |
715 (Lifting_Term.parametrize_transfer_rule lthy ([typedef_thm, T_def] MRSL @{thm typedef_rep_transfer}))) |
730 [("rep_transfer", @{thms typedef_rep_transfer}, @{attributes [transfer_rule]})]; |
716 :: |
731 val notes3 = |
717 (map_snd (fn thm => parametrize_class_constraint lthy pcrel_def ([typedef_thm, T_def] MRSL thm)) |
732 map_thms qualify |
718 [("left_unique", @{thm typedef_left_unique} ), |
733 (fn thm => parametrize_class_constraint lthy pcrel_def ([typedef_thm, T_def] MRSL thm)) |
719 ("right_unique", @{thm typedef_right_unique}), |
734 [("left_unique", @{thms typedef_left_unique}, @{attributes [transfer_rule]}), |
720 ("bi_unique", @{thm typedef_bi_unique} ), |
735 ("right_unique", @{thms typedef_right_unique},@{attributes [transfer_rule]}), |
721 ("right_total", @{thm typedef_right_total} )]) |
736 ("bi_unique", @{thms typedef_bi_unique}, @{attributes [transfer_rule]}), |
722 in |
737 ("right_total", @{thms typedef_right_total}, @{attributes [transfer_rule]})] |
723 fold (fn (name, thm) => (snd oo Local_Theory.note) ((qualify name, [transfer_attr]), |
738 in |
724 [thm])) thms lthy |
739 notes3 @ notes2 @ notes1 @ notes |
725 end |
740 end |
726 |
741 |
727 fun setup_transfer_rules lthy = |
742 val notes1 = [(Binding.prefix_name "Quotient_" qty_name, [quot_thm], [])] |
728 if is_some (get_pcrel_info lthy qty_full_name) then setup_transfer_rules_par lthy |
743 |
729 else setup_transfer_rules_nonpar lthy |
744 fun setup_rules lthy = |
730 |
745 let |
|
746 val thms = if is_some (get_pcrel_info lthy qty_full_name) |
|
747 then setup_transfer_rules_par lthy notes1 else setup_transfer_rules_nonpar notes1 |
|
748 in |
|
749 notes (#notes config) thms lthy |
|
750 end |
731 in |
751 in |
732 lthy |
752 lthy |
733 |> (snd oo Local_Theory.note) ((Binding.prefix_name "Quotient_" qty_name, []), |
753 |> setup_lifting_infr config quot_thm opt_reflp_thm |
734 [quot_thm]) |
754 ||> setup_rules |
735 |> setup_lifting_infr quot_thm opt_reflp_thm |
|
736 |> setup_transfer_rules |
|
737 end |
755 end |
738 |
756 |
739 fun setup_lifting_cmd xthm opt_reflp_xthm opt_par_xthm lthy = |
757 fun setup_lifting_cmd xthm opt_reflp_xthm opt_par_xthm lthy = |
740 let |
758 let |
741 val input_thm = singleton (Attrib.eval_thms lthy) xthm |
759 val input_thm = singleton (Attrib.eval_thms lthy) xthm |