src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 56648 2ffa440b3074
parent 56641 029997d3b5d8
child 56650 1f9ab71d43a5
equal deleted inserted replaced
56647:ce8297d5017a 56648:2ffa440b3074
    27      common_co_inducts: thm list,
    27      common_co_inducts: thm list,
    28      co_inducts: thm list,
    28      co_inducts: thm list,
    29      co_rec_thms: thm list,
    29      co_rec_thms: thm list,
    30      disc_co_recs: thm list,
    30      disc_co_recs: thm list,
    31      sel_co_recss: thm list list,
    31      sel_co_recss: thm list list,
    32      rel_injects: thm list};
    32      rel_injects: thm list,
       
    33      rel_distincts: thm list};
    33 
    34 
    34   val morph_fp_sugar: morphism -> fp_sugar -> fp_sugar
    35   val morph_fp_sugar: morphism -> fp_sugar -> fp_sugar
    35   val transfer_fp_sugar: Proof.context -> fp_sugar -> fp_sugar
    36   val transfer_fp_sugar: Proof.context -> fp_sugar -> fp_sugar
    36   val fp_sugar_of: Proof.context -> string -> fp_sugar option
    37   val fp_sugar_of: Proof.context -> string -> fp_sugar option
    37   val fp_sugars_of: Proof.context -> fp_sugar list
    38   val fp_sugars_of: Proof.context -> fp_sugar list
   143    common_co_inducts: thm list,
   144    common_co_inducts: thm list,
   144    co_inducts: thm list,
   145    co_inducts: thm list,
   145    co_rec_thms: thm list,
   146    co_rec_thms: thm list,
   146    disc_co_recs: thm list,
   147    disc_co_recs: thm list,
   147    sel_co_recss: thm list list,
   148    sel_co_recss: thm list list,
   148    rel_injects: thm list};
   149    rel_injects: thm list,
   149 
   150    rel_distincts: thm list};
   150 fun morph_fp_sugar phi ({T, X, fp, fp_res, fp_res_index, pre_bnf, absT_info, nested_bnfs,
   151 
   151     nesting_bnfs, ctrXs_Tss, ctr_defs, ctr_sugar, co_rec, maps, common_co_inducts, co_inducts,
   152 fun morph_fp_sugar phi ({T, BT, X, fp, fp_res, fp_res_index, pre_bnf, absT_info, nested_bnfs,
   152     co_rec_thms, disc_co_recs, sel_co_recss, rel_injects} : fp_sugar) =
   153     nesting_bnfs, ctrXs_Tss, ctr_defs, ctr_sugar, co_rec, co_rec_def, maps, common_co_inducts,
       
   154     co_inducts, co_rec_thms, disc_co_recs, sel_co_recss, rel_injects, rel_distincts} : fp_sugar) =
   153   {T = Morphism.typ phi T,
   155   {T = Morphism.typ phi T,
       
   156    BT = Morphism.typ phi BT,
   154    X = Morphism.typ phi X,
   157    X = Morphism.typ phi X,
   155    fp = fp,
   158    fp = fp,
   156    fp_res = morph_fp_result phi fp_res,
   159    fp_res = morph_fp_result phi fp_res,
   157    fp_res_index = fp_res_index,
   160    fp_res_index = fp_res_index,
   158    pre_bnf = morph_bnf phi pre_bnf,
   161    pre_bnf = morph_bnf phi pre_bnf,
   168    common_co_inducts = map (Morphism.thm phi) common_co_inducts,
   171    common_co_inducts = map (Morphism.thm phi) common_co_inducts,
   169    co_inducts = map (Morphism.thm phi) co_inducts,
   172    co_inducts = map (Morphism.thm phi) co_inducts,
   170    co_rec_thms = map (Morphism.thm phi) co_rec_thms,
   173    co_rec_thms = map (Morphism.thm phi) co_rec_thms,
   171    disc_co_recs = map (Morphism.thm phi) disc_co_recs,
   174    disc_co_recs = map (Morphism.thm phi) disc_co_recs,
   172    sel_co_recss = map (map (Morphism.thm phi)) sel_co_recss,
   175    sel_co_recss = map (map (Morphism.thm phi)) sel_co_recss,
   173    rel_injects = map (Morphism.thm phi) rel_injects};
   176    rel_injects = map (Morphism.thm phi) rel_injects,
       
   177    rel_distincts = map (Morphism.thm phi) rel_distincts};
   174 
   178 
   175 val transfer_fp_sugar = morph_fp_sugar o Morphism.transfer_morphism o Proof_Context.theory_of;
   179 val transfer_fp_sugar = morph_fp_sugar o Morphism.transfer_morphism o Proof_Context.theory_of;
   176 
   180 
   177 structure Data = Generic_Data
   181 structure Data = Generic_Data
   178 (
   182 (
   196 (
   200 (
   197   type T = fp_sugar list;
   201   type T = fp_sugar list;
   198   val eq: T * T -> bool = op = o pairself (map #T);
   202   val eq: T * T -> bool = op = o pairself (map #T);
   199 );
   203 );
   200 
   204 
   201 fun with_repaired_path f (fp_sugars : fp_sugar list) thy =
   205 fun with_repaired_path f (fp_sugars as ({T = Type (s, _), ...} : fp_sugar) :: _) thy =
   202   thy
   206   thy
   203   (* FIXME: |> Sign.root_path*)
   207   |> Sign.root_path (* FIXME *)
   204   |> Sign.add_path (Long_Name.qualifier (mk_common_name (map (fst o dest_Type o #T) fp_sugars)))
   208   |> Sign.add_path (Long_Name.qualifier s)
   205   |> f fp_sugars
   209   |> f fp_sugars
   206   |> Sign.restore_naming thy;
   210   |> Sign.restore_naming thy;
   207 
   211 
   208 val fp_sugar_interpretation = FP_Sugar_Interpretation.interpretation o with_repaired_path;
   212 val fp_sugar_interpretation = FP_Sugar_Interpretation.interpretation o with_repaired_path;
   209 
   213 
   210 fun register_fp_sugars fp_sugars =
   214 fun register_fp_sugars fp_sugars =
   211   fold (fn fp_sugar as {T as Type (s, _), ...} =>
   215   fold (fn fp_sugar as {T = Type (s, _), ...} =>
   212       Local_Theory.declaration {syntax = false, pervasive = true}
   216       Local_Theory.declaration {syntax = false, pervasive = true}
   213         (fn phi => Data.map (Symtab.update (s, morph_fp_sugar phi fp_sugar))))
   217         (fn phi => Data.map (Symtab.update (s, morph_fp_sugar phi fp_sugar))))
   214     fp_sugars
   218     fp_sugars
   215   #> Local_Theory.background_theory (FP_Sugar_Interpretation.data fp_sugars);
   219   #> Local_Theory.background_theory (FP_Sugar_Interpretation.data fp_sugars);
   216 
   220 
   217 fun register_as_fp_sugars Xs fp pre_bnfs absT_infos nested_bnfs nesting_bnfs (fp_res as {Ts, ...})
   221 fun register_as_fp_sugars Ts BTs Xs fp pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
   218     ctrXs_Tsss ctr_defss ctr_sugars co_recs mapss common_co_inducts co_inductss co_rec_thmss
   222     ctrXs_Tsss ctr_defss ctr_sugars co_recs co_rec_defs mapss common_co_inducts co_inductss
   219     disc_co_recss sel_co_recsss =
   223     co_rec_thmss disc_co_recss sel_co_recsss rel_injectss rel_distinctss =
   220   let
   224   let
   221     val fp_sugars =
   225     val fp_sugars =
   222       map_index (fn (kk, T) =>
   226       map_index (fn (kk, T) =>
   223         {T = T, X = nth Xs kk, fp = fp, fp_res = fp_res, fp_res_index = kk,
   227         {T = T, BT = nth BTs kk, X = nth Xs kk, fp = fp, fp_res = fp_res, fp_res_index = kk,
   224          pre_bnf = nth pre_bnfs kk, absT_info = nth absT_infos kk, nested_bnfs = nested_bnfs,
   228          pre_bnf = nth pre_bnfs kk, absT_info = nth absT_infos kk, nested_bnfs = nested_bnfs,
   225          nesting_bnfs = nesting_bnfs, ctrXs_Tss = nth ctrXs_Tsss kk, ctr_defs = nth ctr_defss kk,
   229          nesting_bnfs = nesting_bnfs, ctrXs_Tss = nth ctrXs_Tsss kk, ctr_defs = nth ctr_defss kk,
   226          ctr_sugar = nth ctr_sugars kk, co_rec = nth co_recs kk, maps = nth mapss kk,
   230          ctr_sugar = nth ctr_sugars kk, co_rec = nth co_recs kk, co_rec_def = nth co_rec_defs kk,
   227          common_co_inducts = common_co_inducts, co_inducts = nth co_inductss kk,
   231          maps = nth mapss kk, common_co_inducts = common_co_inducts,
   228          co_rec_thms = nth co_rec_thmss kk, disc_co_recs = nth disc_co_recss kk,
   232          co_inducts = nth co_inductss kk, co_rec_thms = nth co_rec_thmss kk,
   229          sel_co_recss = nth sel_co_recsss kk}) Ts
   233          disc_co_recs = nth disc_co_recss kk, sel_co_recss = nth sel_co_recsss kk,
       
   234          rel_injects = nth rel_injectss kk, rel_distincts = nth rel_distinctss kk}) Ts
   230   in
   235   in
   231     register_fp_sugars fp_sugars
   236     register_fp_sugars fp_sugars
   232   end;
   237   end;
   233 
   238 
   234 (* This function could produce (fairly harmless) clashes in contrived examples (e.g., "x.A",
   239 (* This function could produce (fairly harmless) clashes in contrived examples (e.g., "x.A",
   449   end;
   454   end;
   450 
   455 
   451 fun mk_co_recs_prelims fp ctr_Tsss fpTs Cs absTs repTs ns mss xtor_co_recs0 lthy =
   456 fun mk_co_recs_prelims fp ctr_Tsss fpTs Cs absTs repTs ns mss xtor_co_recs0 lthy =
   452   let
   457   let
   453     val thy = Proof_Context.theory_of lthy;
   458     val thy = Proof_Context.theory_of lthy;
   454     val nn = length fpTs;
       
   455 
   459 
   456     val (xtor_co_rec_fun_Ts, xtor_co_recs) =
   460     val (xtor_co_rec_fun_Ts, xtor_co_recs) =
   457       mk_xtor_co_recs thy fp fpTs Cs xtor_co_recs0 |> `(binder_fun_types o fastype_of o hd);
   461       mk_xtor_co_recs thy fp fpTs Cs xtor_co_recs0 |> `(binder_fun_types o fastype_of o hd);
   458 
   462 
   459     val ((recs_args_types, corecs_args_types), lthy') =
   463     val ((recs_args_types, corecs_args_types), lthy') =
  1318     fun mk_simp_thms ({injects, distincts, case_thms, ...} : ctr_sugar) co_recs mapsx rel_injects
  1322     fun mk_simp_thms ({injects, distincts, case_thms, ...} : ctr_sugar) co_recs mapsx rel_injects
  1319         rel_distincts setss =
  1323         rel_distincts setss =
  1320       injects @ distincts @ case_thms @ co_recs @ mapsx @ rel_injects @ rel_distincts @ flat setss;
  1324       injects @ distincts @ case_thms @ co_recs @ mapsx @ rel_injects @ rel_distincts @ flat setss;
  1321 
  1325 
  1322     fun derive_note_induct_recs_thms_for_types
  1326     fun derive_note_induct_recs_thms_for_types
  1323         ((((mapss, rel_injects, rel_distincts, setss), (ctrss, _, ctr_defss, ctr_sugars)),
  1327         ((((mapss, rel_injectss, rel_distinctss, setss), (ctrss, _, ctr_defss, ctr_sugars)),
  1324           (recs, rec_defs)), lthy) =
  1328           (recs, rec_defs)), lthy) =
  1325       let
  1329       let
  1326         val ((induct_thms, induct_thm, induct_attrs), (rec_thmss, rec_attrs)) =
  1330         val ((induct_thms, induct_thm, induct_attrs), (rec_thmss, rec_attrs)) =
  1327           derive_induct_recs_thms_for_types pre_bnfs recs_args_types xtor_co_induct xtor_co_rec_thms
  1331           derive_induct_recs_thms_for_types pre_bnfs recs_args_types xtor_co_induct xtor_co_rec_thms
  1328             nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses type_definitions
  1332             nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses type_definitions
  1329             abs_inverses ctrss ctr_defss recs rec_defs lthy;
  1333             abs_inverses ctrss ctr_defss recs rec_defs lthy;
  1330 
  1334 
  1331         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
  1335         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
  1332 
  1336 
  1333         val simp_thmss =
  1337         val simp_thmss =
  1334           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injects rel_distincts setss;
  1338           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injectss rel_distinctss setss;
  1335 
  1339 
  1336         val common_notes =
  1340         val common_notes =
  1337           (if nn > 1 then [(inductN, [induct_thm], induct_attrs)] else [])
  1341           (if nn > 1 then [(inductN, [induct_thm], induct_attrs)] else [])
  1338           |> massage_simple_notes fp_common_name;
  1342           |> massage_simple_notes fp_common_name;
  1339 
  1343 
  1344           |> massage_multi_notes;
  1348           |> massage_multi_notes;
  1345       in
  1349       in
  1346         lthy
  1350         lthy
  1347         |> Spec_Rules.add Spec_Rules.Equational (recs, flat rec_thmss)
  1351         |> Spec_Rules.add Spec_Rules.Equational (recs, flat rec_thmss)
  1348         |> Local_Theory.notes (common_notes @ notes) |> snd
  1352         |> Local_Theory.notes (common_notes @ notes) |> snd
  1349         |> register_as_fp_sugars Xs Least_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
  1353         |> register_as_fp_sugars fpTs fpBTs Xs Least_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs
  1350           ctrXs_Tsss ctr_defss ctr_sugars recs mapss [induct_thm] (map single induct_thms)
  1354           fp_res ctrXs_Tsss ctr_defss ctr_sugars recs rec_defs mapss [induct_thm]
  1351           rec_thmss (replicate nn []) (replicate nn []) rel_injects
  1355           (map single induct_thms) rec_thmss (replicate nn []) (replicate nn []) rel_injectss
       
  1356           rel_distinctss
  1352       end;
  1357       end;
  1353 
  1358 
  1354     fun derive_note_coinduct_corecs_thms_for_types
  1359     fun derive_note_coinduct_corecs_thms_for_types
  1355         ((((mapss, rel_injects, rel_distincts, setss), (_, _, ctr_defss, ctr_sugars)),
  1360         ((((mapss, rel_injectss, rel_distinctss, setss), (_, _, ctr_defss, ctr_sugars)),
  1356           (corecs, corec_defs)), lthy) =
  1361           (corecs, corec_defs)), lthy) =
  1357       let
  1362       let
  1358         val (([(coinduct_thms, coinduct_thm), (strong_coinduct_thms, strong_coinduct_thm)],
  1363         val (([(coinduct_thms, coinduct_thm), (strong_coinduct_thms, strong_coinduct_thm)],
  1359               coinduct_attrs),
  1364               coinduct_attrs),
  1360              (corec_thmss, corec_attrs), (disc_corec_thmss, disc_corec_attrs),
  1365              (corec_thmss, corec_attrs), (disc_corec_thmss, disc_corec_attrs),
  1371         val flat_corec_thms = append oo append;
  1376         val flat_corec_thms = append oo append;
  1372 
  1377 
  1373         val simp_thmss =
  1378         val simp_thmss =
  1374           map6 mk_simp_thms ctr_sugars
  1379           map6 mk_simp_thms ctr_sugars
  1375             (map3 flat_corec_thms disc_corec_thmss disc_corec_iff_thmss sel_corec_thmss)
  1380             (map3 flat_corec_thms disc_corec_thmss disc_corec_iff_thmss sel_corec_thmss)
  1376             mapss rel_injects rel_distincts setss;
  1381             mapss rel_injectss rel_distinctss setss;
  1377 
  1382 
  1378         val common_notes =
  1383         val common_notes =
  1379           (if nn > 1 then
  1384           (if nn > 1 then
  1380              [(coinductN, [coinduct_thm], coinduct_attrs),
  1385              [(coinductN, [coinduct_thm], coinduct_attrs),
  1381               (strong_coinductN, [strong_coinduct_thm], coinduct_attrs)]
  1386               (strong_coinductN, [strong_coinduct_thm], coinduct_attrs)]
  1397         lthy
  1402         lthy
  1398         (* TODO: code theorems *)
  1403         (* TODO: code theorems *)
  1399         |> fold (curry (Spec_Rules.add Spec_Rules.Equational) corecs)
  1404         |> fold (curry (Spec_Rules.add Spec_Rules.Equational) corecs)
  1400           [flat sel_corec_thmss, flat corec_thmss]
  1405           [flat sel_corec_thmss, flat corec_thmss]
  1401         |> Local_Theory.notes (common_notes @ notes) |> snd
  1406         |> Local_Theory.notes (common_notes @ notes) |> snd
  1402         |> register_as_fp_sugars Xs Greatest_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
  1407         |> register_as_fp_sugars fpTs fpBTs Xs Greatest_FP pre_bnfs absT_infos nested_bnfs
  1403           ctrXs_Tsss ctr_defss ctr_sugars corecs mapss [coinduct_thm, strong_coinduct_thm]
  1408           nesting_bnfs fp_res ctrXs_Tsss ctr_defss ctr_sugars corecs corec_defs mapss
  1404           (transpose [coinduct_thms, strong_coinduct_thms]) corec_thmss disc_corec_thmss
  1409           [coinduct_thm, strong_coinduct_thm] (transpose [coinduct_thms, strong_coinduct_thms])
  1405           sel_corec_thmsss rel_injects
  1410           corec_thmss disc_corec_thmss sel_corec_thmsss rel_injectss rel_distinctss
  1406       end;
  1411       end;
  1407 
  1412 
  1408     val lthy'' = lthy'
  1413     val lthy'' = lthy'
  1409       |> fold_map define_ctrs_dtrs_for_type (fp_bnfs ~~ fp_bs ~~ fpTs ~~ ctors ~~ dtors ~~
  1414       |> fold_map define_ctrs_dtrs_for_type (fp_bnfs ~~ fp_bs ~~ fpTs ~~ ctors ~~ dtors ~~
  1410         xtor_co_recs ~~ ctor_dtors ~~ dtor_ctors ~~ ctor_injects ~~ pre_map_defs ~~ pre_set_defss ~~
  1415         xtor_co_recs ~~ ctor_dtors ~~ dtor_ctors ~~ ctor_injects ~~ pre_map_defs ~~ pre_set_defss ~~