22 (((lift_bnf_option list * (binding option * (string * string option)) list) * |
22 (((lift_bnf_option list * (binding option * (string * string option)) list) * |
23 string) * (Facts.ref * Token.src list) option) * (binding * binding * binding) -> |
23 string) * (Facts.ref * Token.src list) option) * (binding * binding * binding) -> |
24 local_theory -> local_theory |
24 local_theory -> local_theory |
25 val lift_bnf: |
25 val lift_bnf: |
26 ((((lift_bnf_option list * (binding option * (string * sort option)) list) * |
26 ((((lift_bnf_option list * (binding option * (string * sort option)) list) * |
27 string) * term list option) * thm option) * (binding * binding * binding) -> |
27 string) * term list option) * thm list option) * (binding * binding * binding) -> |
28 ({context: Proof.context, prems: thm list} -> tactic) list -> |
28 ({context: Proof.context, prems: thm list} -> tactic) list -> |
29 local_theory -> local_theory |
29 local_theory -> local_theory |
30 val lift_bnf_cmd: |
30 val lift_bnf_cmd: |
31 ((((lift_bnf_option list * (binding option * (string * string option)) list) * |
31 ((((lift_bnf_option list * (binding option * (string * string option)) list) * |
32 string) * string list) * (Facts.ref * Token.src list) option) * |
32 string) * string list) * (Facts.ref * Token.src list) list option) * |
33 (binding * binding * binding) -> local_theory -> Proof.state |
33 (binding * binding * binding) -> local_theory -> Proof.state |
34 end |
34 end |
35 |
35 |
36 structure BNF_Lift : BNF_LIFT = |
36 structure BNF_Lift : BNF_LIFT = |
37 struct |
37 struct |
325 fun mk_transfer_thms quiet bnf_F bnf_G name consts thm Tss defs lthy = let |
325 fun mk_transfer_thms quiet bnf_F bnf_G name consts thm Tss defs lthy = let |
326 |
326 |
327 fun mk_crel_def quot_thm = |
327 fun mk_crel_def quot_thm = |
328 (case thm of |
328 (case thm of |
329 Quotient equiv => @{thm Quotient_crel_quotient} OF [quot_thm, equiv] |
329 Quotient equiv => @{thm Quotient_crel_quotient} OF [quot_thm, equiv] |
330 | Typedef _ => hd ([quot_thm] RL @{thms Quotient_crel_typedef Quotient_crel_typecopy})); |
330 | Typedef => hd ([quot_thm] RL @{thms Quotient_crel_typedef Quotient_crel_typecopy})); |
331 fun no_quotient _ = [Pretty.para ("No quotient theorem has been registered for " ^ |
331 fun no_quotient _ = [Pretty.para ("No quotient theorem has been registered for " ^ |
332 Binding.name_of (name_of_bnf bnf_G) ^ "."), |
332 Binding.name_of (name_of_bnf bnf_G) ^ "."), |
333 Pretty.para "Use setup_lifting to register a quotient or type definition theorem."]; |
333 Pretty.para "Use setup_lifting to register a quotient or type definition theorem."]; |
334 fun wrong_quotient T lthy = [Pretty.para ("A wrong quotient theorem has been registered for " ^ |
334 fun wrong_quotient T lthy = [Pretty.para ("A wrong quotient theorem has been registered for " ^ |
335 Binding.name_of (name_of_bnf bnf_G) ^ "."), |
335 Binding.name_of (name_of_bnf bnf_G) ^ "."), |
684 |
684 |
685 val unfold_morphism = Morphism.thm_morphism "BNF" (unfold_thms lthy defs); |
685 val unfold_morphism = Morphism.thm_morphism "BNF" (unfold_thms lthy defs); |
686 val (bnf_G, lthy) = morph_bnf_defs unfold_morphism bnf_G |
686 val (bnf_G, lthy) = morph_bnf_defs unfold_morphism bnf_G |
687 |> (fn bnf => note_bnf_defs bnf lthy); |
687 |> (fn bnf => note_bnf_defs bnf lthy); |
688 |
688 |
689 val setup_lifting_thm = Typedef thm; |
|
690 val quiet = exists (fn No_Warn_Transfer => true | _ => false) opts; |
689 val quiet = exists (fn No_Warn_Transfer => true | _ => false) opts; |
691 |
690 |
692 val transfer_consts = mk_typedef_transfer_tacs bnf_F bnf_G |
691 val transfer_consts = mk_typedef_transfer_tacs bnf_F bnf_G |
693 {map_closed=map_closed_thm,typedef=thm} old_defs map_raw rel_raw pred_raw sets_F; |
692 {map_closed=map_closed_thm,typedef=thm} old_defs map_raw rel_raw pred_raw sets_F; |
694 in |
693 in |
695 lthy |> BNF_Def.register_bnf plugins AbsT_name bnf_G |> |
694 lthy |> BNF_Def.register_bnf plugins AbsT_name bnf_G |> |
696 mk_transfer_thms quiet bnf_F bnf_G AbsT_name transfer_consts setup_lifting_thm |
695 mk_transfer_thms quiet bnf_F bnf_G AbsT_name transfer_consts Typedef |
697 {abs=typ_subst_atomic (alphas ~~ alphas') AbsT, rep=RepT, Ds0=map TFree Ds0, |
696 {abs=typ_subst_atomic (alphas ~~ alphas') AbsT, rep=RepT, Ds0=map TFree Ds0, |
698 deads = deads, alphas=alphas, betas=alphas', gammas=betas, deltas=betas'} defs |
697 deads = deads, alphas=alphas, betas=alphas', gammas=betas, deltas=betas'} defs |
699 end |
698 end |
700 | after_qed _ _ = raise Match; |
699 | after_qed _ _ = raise Match; |
701 in |
700 in |
830 sets={raws=sets_raw,tacs=map2 set_transfer_q (#sets old_defs) set_F'_thmss}, |
829 sets={raws=sets_raw,tacs=map2 set_transfer_q (#sets old_defs) set_F'_thmss}, |
831 pred=NONE} |
830 pred=NONE} |
832 end; |
831 end; |
833 |
832 |
834 |
833 |
835 fun quotient_bnf (equiv_thm, quot_thm) _ wits specs map_b rel_b pred_b opts lthy = |
834 fun quotient_bnf (equiv_thm, quot_thm) wits specs map_b rel_b pred_b opts lthy = |
836 let |
835 let |
837 (* extract rep_G and abs_G *) |
836 (* extract rep_G and abs_G *) |
838 val (equiv_rel, abs_G, rep_G) = strip3 quot_thm; |
837 val (equiv_rel, abs_G, rep_G) = strip3 quot_thm; |
839 val (repT, absT) = dest_funT (fastype_of abs_G); (* ("?'a F", "?'a G") *) |
838 val (repT, absT) = dest_funT (fastype_of abs_G); (* ("?'a F", "?'a G") *) |
840 val absT_name = fst (dest_Type absT); |
839 val absT_name = fst (dest_Type absT); |
1966 (** main commands **) |
1965 (** main commands **) |
1967 |
1966 |
1968 local |
1967 local |
1969 |
1968 |
1970 fun prepare_common prepare_name prepare_sort prepare_term prepare_thm |
1969 fun prepare_common prepare_name prepare_sort prepare_term prepare_thm |
1971 (((((plugins, raw_specs), raw_absT_name), raw_wits), xthm_opt), (map_b, rel_b, pred_b)) lthy = |
1970 (((((plugins, raw_specs), raw_absT_name), raw_wits), xthms_opt), (map_b, rel_b, pred_b)) lthy = |
1972 let |
1971 let |
1973 val absT_name = prepare_name lthy raw_absT_name; |
1972 val absT_name = prepare_name lthy raw_absT_name; |
1974 |
1973 |
1975 val input_thm = |
1974 fun bad_input input = |
1976 (case xthm_opt of |
1975 Pretty.chunks [Pretty.para ("Expected theorem(s) of either form:"), |
1977 SOME xthm => prepare_thm lthy xthm |
1976 Pretty.item [Pretty.enum "," "" "" [Syntax.pretty_term lthy @{term "Quotient R Abs Rep T"}, |
1978 | NONE => Typedef.get_info lthy absT_name |> hd |> snd |> #type_definition); |
1977 Syntax.pretty_term lthy @{term "reflp R"}]], |
|
1978 Pretty.item [Syntax.pretty_term lthy @{term "Quotient R Abs Rep T"}], |
|
1979 Pretty.item [Syntax.pretty_term lthy @{term "type_definition Rep Abs A"}], |
|
1980 Pretty.para ("Got"), Pretty.enum "," "" "" (map (Thm.pretty_thm lthy) input)] |
|
1981 |> Pretty.string_of |
|
1982 |> error; |
|
1983 |
|
1984 fun no_refl qthm = |
|
1985 Pretty.chunks [Pretty.para ("Could not find a reflexivity rule for the Quotient theorem:"), |
|
1986 Pretty.item [Thm.pretty_thm lthy qthm], |
|
1987 Pretty.para ("Try supplying a reflexivity theorem manually or registering it in setup_lifting.")] |
|
1988 |> Pretty.string_of |
|
1989 |> error; |
|
1990 |
|
1991 fun find_equiv_thm_via_Quotient qthm = |
|
1992 let |
|
1993 val refl_thms = Lifting_Info.get_reflexivity_rules lthy |
|
1994 |> map (unfold_thms lthy @{thms reflp_eq[symmetric]}); |
|
1995 in |
|
1996 (case refl_thms RL [qthm RS @{thm Quotient_reflp_imp_equivp}] of |
|
1997 [] => no_refl qthm |
|
1998 | thm :: _ => thm) |
|
1999 end; |
|
2000 |
|
2001 val (lift_thm, equiv_thm) = |
|
2002 (case Option.map (prepare_thm lthy) xthms_opt of |
|
2003 SOME (thms as [qthm, _]) => |
|
2004 (case try (fn thms => @{thm Quotient_reflp_imp_equivp} OF thms) thms of |
|
2005 SOME equiv_thm => (qthm RS @{thm Quotient_Quotient3}, Quotient equiv_thm) |
|
2006 | NONE => bad_input thms) |
|
2007 | SOME [thm] => |
|
2008 (case try (fn thm => thm RS @{thm Quotient_Quotient3}) thm of |
|
2009 SOME qthm => (qthm, Quotient (find_equiv_thm_via_Quotient thm)) |
|
2010 | NONE => if can (fn thm => thm RS @{thm type_definition.Rep}) thm |
|
2011 then (thm, Typedef) |
|
2012 else bad_input [thm]) |
|
2013 | NONE => (case Lifting_Info.lookup_quotients lthy absT_name of |
|
2014 SOME {quot_thm = qthm, ...} => |
|
2015 let |
|
2016 val qthm = Thm.transfer' lthy qthm; |
|
2017 in |
|
2018 case [qthm] RL @{thms Quotient_eq_onp_typedef Quotient_eq_onp_type_copy} of |
|
2019 thm :: _ => (thm, Typedef) |
|
2020 | _ => (qthm RS @{thm Quotient_Quotient3}, |
|
2021 Quotient (find_equiv_thm_via_Quotient qthm)) |
|
2022 end |
|
2023 | NONE => (Typedef.get_info lthy absT_name |> hd |> snd |> #type_definition, Typedef)) |
|
2024 | SOME thms => bad_input thms); |
1979 val wits = (Option.map o map) (prepare_term lthy) raw_wits; |
2025 val wits = (Option.map o map) (prepare_term lthy) raw_wits; |
1980 val specs = |
2026 val specs = |
1981 map (apsnd (apsnd (the_default @{sort type} o Option.map (prepare_sort lthy)))) raw_specs; |
2027 map (apsnd (apsnd (the_default @{sort type} o Option.map (prepare_sort lthy)))) raw_specs; |
1982 |
2028 |
1983 val which_bnf = (case (xthm_opt, Quotient_Info.lookup_quotients lthy absT_name) of |
2029 val which_bnf = (case equiv_thm of |
1984 (NONE, SOME qs) => quotient_bnf (#equiv_thm qs, #quot_thm qs) |
2030 Quotient thm => quotient_bnf (thm, lift_thm) |
1985 | (SOME _, _) => |
2031 | Typedef => typedef_bnf lift_thm); |
1986 if can (fn thm => thm RS @{thm bnf_lift_Quotient_equivp}) input_thm |
|
1987 then quotient_bnf (input_thm RS conjunct2, input_thm RS conjunct1 RS @{thm Quotient_Quotient3}) |
|
1988 else if can (fn thm => thm RS @{thm type_definition.Rep}) input_thm |
|
1989 then typedef_bnf |
|
1990 else Pretty.chunks [Pretty.para ("Expected theorem of either form:"), |
|
1991 Pretty.item [Syntax.pretty_term lthy @{term "Quotient R Abs Rep T \<and> equivp R"}], |
|
1992 Pretty.item [Syntax.pretty_term lthy @{term "type_definition Rep Abs A"}], |
|
1993 Pretty.para ("Got"), Pretty.item [Thm.pretty_thm lthy input_thm]] |
|
1994 |> Pretty.string_of |
|
1995 |> error |
|
1996 | _ => typedef_bnf); |
|
1997 |
|
1998 in |
2032 in |
1999 which_bnf input_thm wits specs map_b rel_b pred_b plugins lthy |
2033 which_bnf wits specs map_b rel_b pred_b plugins lthy |
2000 end; |
2034 end; |
2001 |
2035 |
2002 fun prepare_lift_bnf prepare_name prepare_sort prepare_term prepare_thm = |
2036 fun prepare_lift_bnf prepare_name prepare_sort prepare_term prepare_thm = |
2003 (fn (goals, after_qed, definitions, lthy) => |
2037 (fn (goals, after_qed, definitions, lthy) => |
2004 lthy |
2038 lthy |
2020 in |
2054 in |
2021 |
2055 |
2022 val lift_bnf_cmd = |
2056 val lift_bnf_cmd = |
2023 prepare_lift_bnf |
2057 prepare_lift_bnf |
2024 (fst o dest_Type oo Proof_Context.read_type_name {proper = true, strict = false}) |
2058 (fst o dest_Type oo Proof_Context.read_type_name {proper = true, strict = false}) |
2025 Syntax.read_sort Syntax.read_term (singleton o Attrib.eval_thms); |
2059 Syntax.read_sort Syntax.read_term Attrib.eval_thms; |
2026 |
2060 |
2027 fun lift_bnf args tacs = |
2061 fun lift_bnf args tacs = |
2028 prepare_solve (K I) (K I) (K I) (K I) (K tacs) args; |
2062 prepare_solve (K I) (K I) (K I) (K I) (K tacs) args; |
2029 |
2063 |
2030 fun copy_bnf_tac {context = ctxt, prems = _} = |
2064 fun copy_bnf_tac {context = ctxt, prems = _} = |
2031 REPEAT_DETERM (resolve_tac ctxt [bexI, conjI, UNIV_I, refl, subset_refl] 1); |
2065 REPEAT_DETERM (resolve_tac ctxt [bexI, conjI, UNIV_I, refl, subset_refl] 1); |
2032 |
2066 |
2033 val copy_bnf = |
2067 val copy_bnf = |
2034 apfst (apfst (rpair NONE)) |
2068 apfst (apfst (rpair NONE)) |
|
2069 #> apfst (apsnd (Option.map single)) |
2035 #> prepare_solve (K I) (K I) (K I) (K I) |
2070 #> prepare_solve (K I) (K I) (K I) (K I) |
2036 (fn n => replicate n copy_bnf_tac); |
2071 (fn n => replicate n copy_bnf_tac); |
2037 |
2072 |
2038 val copy_bnf_cmd = |
2073 val copy_bnf_cmd = |
2039 apfst (apfst (rpair NONE)) |
2074 apfst (apfst (rpair NONE)) |
|
2075 #> apfst (apsnd (Option.map single)) |
2040 #> prepare_solve |
2076 #> prepare_solve |
2041 (fst o dest_Type oo Proof_Context.read_type_name {proper = true, strict = false}) |
2077 (fst o dest_Type oo Proof_Context.read_type_name {proper = true, strict = false}) |
2042 Syntax.read_sort Syntax.read_term (singleton o Attrib.eval_thms) |
2078 Syntax.read_sort Syntax.read_term Attrib.eval_thms |
2043 (fn n => replicate n copy_bnf_tac); |
2079 (fn n => replicate n copy_bnf_tac); |
2044 |
2080 |
2045 end; |
2081 end; |
2046 |
2082 |
2047 (** outer syntax **) |
2083 (** outer syntax **) |
2066 val parse_lift_opts = Parse.reserved "no_warn_wits" >> K No_Warn_Wits |> parse_common_opts; |
2102 val parse_lift_opts = Parse.reserved "no_warn_wits" >> K No_Warn_Wits |> parse_common_opts; |
2067 |
2103 |
2068 val parse_copy_opts = parse_common_opts Scan.fail; |
2104 val parse_copy_opts = parse_common_opts Scan.fail; |
2069 |
2105 |
2070 val parse_xthm = Scan.option (Parse.reserved "via" |-- Parse.thm); |
2106 val parse_xthm = Scan.option (Parse.reserved "via" |-- Parse.thm); |
|
2107 val parse_xthms = Scan.option (Parse.reserved "via" |-- Parse.thms1); |
2071 |
2108 |
2072 in |
2109 in |
2073 |
2110 |
2074 (* exposed commands *) |
2111 (* exposed commands *) |
2075 |
2112 |
2076 val _ = |
2113 val _ = |
2077 Outer_Syntax.local_theory_to_proof @{command_keyword lift_bnf} |
2114 Outer_Syntax.local_theory_to_proof @{command_keyword lift_bnf} |
2078 "register a quotient type/subtype of a bounded natural functor (BNF) as a BNF" |
2115 "register a quotient type/subtype of a bounded natural functor (BNF) as a BNF" |
2079 ((parse_lift_opts -- parse_type_args_named_constrained -- Parse.type_const -- parse_wits -- |
2116 ((parse_lift_opts -- parse_type_args_named_constrained -- Parse.type_const -- parse_wits -- |
2080 parse_xthm -- parse_map_rel_pred_bindings) >> lift_bnf_cmd); |
2117 parse_xthms -- parse_map_rel_pred_bindings) >> lift_bnf_cmd); |
2081 |
2118 |
2082 val _ = |
2119 val _ = |
2083 Outer_Syntax.local_theory @{command_keyword copy_bnf} |
2120 Outer_Syntax.local_theory @{command_keyword copy_bnf} |
2084 "register a type copy of a bounded natural functor (BNF) as a BNF" |
2121 "register a type copy of a bounded natural functor (BNF) as a BNF" |
2085 ((parse_copy_opts -- parse_type_args_named_constrained -- Parse.type_const -- |
2122 ((parse_copy_opts -- parse_type_args_named_constrained -- Parse.type_const -- |