src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 57893 7bc128647d6e
parent 57891 d23a85b59dec
child 57898 f7f75b33d6c8
equal deleted inserted replaced
57892:3d61d6a61cfc 57893:7bc128647d6e
   100 
   100 
   101 val corec_codeN = "corec_code";
   101 val corec_codeN = "corec_code";
   102 val disc_map_iffN = "disc_map_iff";
   102 val disc_map_iffN = "disc_map_iff";
   103 val sel_mapN = "sel_map";
   103 val sel_mapN = "sel_map";
   104 val sel_setN = "sel_set";
   104 val sel_setN = "sel_set";
       
   105 val set_casesN = "set_cases";
   105 val set_emptyN = "set_empty";
   106 val set_emptyN = "set_empty";
   106 val set_introsN = "set_intros";
   107 val set_introsN = "set_intros";
   107 val set_inductN = "set_induct";
   108 val set_inductN = "set_induct";
   108 
   109 
   109 structure Data = Generic_Data
   110 structure Data = Generic_Data
   111   type T = fp_sugar Symtab.table;
   112   type T = fp_sugar Symtab.table;
   112   val empty = Symtab.empty;
   113   val empty = Symtab.empty;
   113   val extend = I;
   114   val extend = I;
   114   fun merge data : T = Symtab.merge (K true) data;
   115   fun merge data : T = Symtab.merge (K true) data;
   115 );
   116 );
       
   117 
       
   118 fun zipping_map f =
       
   119   let
       
   120     fun zmap _ [] = []
       
   121       | zmap xs (y :: ys) = f (xs, y, ys) :: zmap (xs @ [y]) ys
       
   122   in zmap [] end;
   116 
   123 
   117 fun choose_binary_fun fs AB =
   124 fun choose_binary_fun fs AB =
   118   find_first (fastype_of #> binder_types #> (fn [A, B] => AB = (A, B))) fs;
   125   find_first (fastype_of #> binder_types #> (fn [A, B] => AB = (A, B))) fs;
   119 fun build_binary_fun_app fs a b =
   126 fun build_binary_fun_app fs a b =
   120   Option.map (rapp b o rapp a) (choose_binary_fun fs (fastype_of a, fastype_of b));
   127   Option.map (rapp b o rapp a) (choose_binary_fun fs (fastype_of a, fastype_of b));
   501 
   508 
   502     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
   509     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
   503       (map2 (build_the_rel lthy (Rs @ IRs) []) fpA_Ts fpB_Ts) IRs));
   510       (map2 (build_the_rel lthy (Rs @ IRs) []) fpA_Ts fpB_Ts) IRs));
   504 
   511 
   505     val rel_induct0_thm = Goal.prove_sorry lthy [] premises goal
   512     val rel_induct0_thm = Goal.prove_sorry lthy [] premises goal
   506       (fn {context = ctxt, prems = prems} =>
   513       (fn {context = ctxt, prems} =>
   507           mk_rel_induct0_tac ctxt ctor_rel_induct prems (map (certify ctxt) IRs) exhausts ctor_defss
   514           mk_rel_induct0_tac ctxt ctor_rel_induct prems (map (certify ctxt) IRs) exhausts ctor_defss
   508             ctor_injects pre_rel_defs abs_inverses live_nesting_rel_eqs)
   515             ctor_injects pre_rel_defs abs_inverses live_nesting_rel_eqs)
   509       |> singleton (Proof_Context.export names_lthy lthy)
   516       |> singleton (Proof_Context.export names_lthy lthy)
   510       |> Thm.close_derivation;
   517       |> Thm.close_derivation;
   511   in
   518   in
   752 
   759 
   753     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
   760     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
   754       IRs (map2 (build_the_rel lthy (Rs @ IRs) []) fpA_Ts fpB_Ts)));
   761       IRs (map2 (build_the_rel lthy (Rs @ IRs) []) fpA_Ts fpB_Ts)));
   755 
   762 
   756     val rel_coinduct0_thm = Goal.prove_sorry lthy [] premises goal
   763     val rel_coinduct0_thm = Goal.prove_sorry lthy [] premises goal
   757       (fn {context = ctxt, prems = prems} =>
   764       (fn {context = ctxt, prems} =>
   758           mk_rel_coinduct0_tac ctxt dtor_rel_coinduct (map (certify ctxt) IRs) prems
   765           mk_rel_coinduct0_tac ctxt dtor_rel_coinduct (map (certify ctxt) IRs) prems
   759             (map #exhaust ctr_sugars) (map (flat o #disc_thmss) ctr_sugars)
   766             (map #exhaust ctr_sugars) (map (flat o #disc_thmss) ctr_sugars)
   760             (map (flat o #sel_thmss) ctr_sugars) ctor_defss dtor_ctors ctor_injects abs_injects
   767             (map (flat o #sel_thmss) ctr_sugars) ctor_defss dtor_ctors ctor_injects abs_injects
   761             rel_pre_defs abs_inverses live_nesting_rel_eqs)
   768             rel_pre_defs abs_inverses live_nesting_rel_eqs)
   762       |> singleton (Proof_Context.export names_lthy lthy)
   769       |> singleton (Proof_Context.export names_lthy lthy)
   802         if T = A then ([HOLogic.mk_Trueprop (the (build_binary_fun_app Ps t ctr_args))], ctxt)
   809         if T = A then ([HOLogic.mk_Trueprop (the (build_binary_fun_app Ps t ctr_args))], ctxt)
   803         else ([], ctxt));
   810         else ([], ctxt));
   804 
   811 
   805     fun mk_prems_for_ctr A Ps ctr ctxt =
   812     fun mk_prems_for_ctr A Ps ctr ctxt =
   806       let
   813       let
   807         val (args, ctxt') = mk_Frees "arg" (binder_types (fastype_of ctr)) ctxt;
   814         val (args, ctxt') = mk_Frees "z" (binder_types (fastype_of ctr)) ctxt;
   808       in
   815       in
   809         fold_map (mk_prems A Ps (list_comb (ctr, args))) args ctxt'
   816         fold_map (mk_prems A Ps (list_comb (ctr, args))) args ctxt'
   810         |>> map (fold_rev Logic.all args) o flat
   817         |>> map (fold_rev Logic.all args) o flat
   811         |>> (fn prems => (prems, mk_names (length prems) (name_of_ctr ctr)))
   818         |>> (fn prems => (prems, mk_names (length prems) (name_of_ctr ctr)))
   812       end;
   819       end;
   835           |>> apfst (apfst flat)
   842           |>> apfst (apfst flat)
   836           |>> apfst (apsnd (Library.foldr1 HOLogic.mk_conj))
   843           |>> apfst (apsnd (Library.foldr1 HOLogic.mk_conj))
   837           |>> apsnd flat;
   844           |>> apsnd flat;
   838 
   845 
   839         val thm =  Goal.prove_sorry lthy [] premises (HOLogic.mk_Trueprop conclusion)
   846         val thm =  Goal.prove_sorry lthy [] premises (HOLogic.mk_Trueprop conclusion)
   840           (fn {context = ctxt, prems = prems} =>
   847           (fn {context = ctxt, prems} =>
   841              mk_set_induct0_tac ctxt (map (certify ctxt'') Ps) prems dtor_set_inducts exhausts
   848              mk_set_induct0_tac ctxt (map (certify ctxt'') Ps) prems dtor_set_inducts exhausts
   842               set_pre_defs ctor_defs dtor_ctors Abs_pre_inverses)
   849               set_pre_defs ctor_defs dtor_ctors Abs_pre_inverses)
   843           |> singleton (Proof_Context.export ctxt'' ctxt)
   850           |> singleton (Proof_Context.export ctxt'' ctxt)
   844           |> Thm.close_derivation;
   851           |> Thm.close_derivation;
   845 
   852 
  1489                 map (fn th => th RS @{thm eq_False[THEN iffD2]}) rel_distinct_thms @
  1496                 map (fn th => th RS @{thm eq_False[THEN iffD2]}) rel_distinct_thms @
  1490                 map2 (fn th => fn 0 => th RS @{thm eq_True[THEN iffD2]} | _ => th)
  1497                 map2 (fn th => fn 0 => th RS @{thm eq_True[THEN iffD2]} | _ => th)
  1491                   rel_inject_thms ms;
  1498                   rel_inject_thms ms;
  1492 
  1499 
  1493               val (disc_map_iff_thms, sel_map_thms, sel_set_thms, rel_sel_thms, set_intros_thms,
  1500               val (disc_map_iff_thms, sel_map_thms, sel_set_thms, rel_sel_thms, set_intros_thms,
  1494                   (rel_cases_thm, rel_cases_attrs)) =
  1501                   (set_cases_thms, set_cases_attrss), (rel_cases_thm, rel_cases_attrs)) =
  1495                 let
  1502                 let
  1496                   val (((Ds, As), Bs), names_lthy) = lthy
  1503                   val (((Ds, As), Bs), names_lthy) = lthy
  1497                     |> mk_TFrees (dead_of_bnf fp_bnf)
  1504                     |> mk_TFrees (dead_of_bnf fp_bnf)
  1498                     ||>> mk_TFrees (live_of_bnf fp_bnf)
  1505                     ||>> mk_TFrees (live_of_bnf fp_bnf)
  1499                     ||>> mk_TFrees (live_of_bnf fp_bnf);
  1506                     ||>> mk_TFrees (live_of_bnf fp_bnf);
  1500                   val TA as Type (_, ADs) = mk_T_of_bnf Ds As fp_bnf;
  1507                   val TA as Type (_, ADs) = mk_T_of_bnf Ds As fp_bnf;
  1501                   val TB as Type (_, BDs) = mk_T_of_bnf Ds Bs fp_bnf;
  1508                   val TB as Type (_, BDs) = mk_T_of_bnf Ds Bs fp_bnf;
  1502                   val fTs = map2 (curry op -->) As Bs;
  1509                   val fTs = map2 (curry op -->) As Bs;
  1503                   val rel = mk_rel_of_bnf Ds As Bs fp_bnf;
  1510                   val rel = mk_rel_of_bnf Ds As Bs fp_bnf;
  1504                   val ((((fs, Rs), ta), tb), names_lthy) = names_lthy
  1511                   val (((((fs, Rs), ta), tb), thesis), names_lthy) = names_lthy
  1505                     |> mk_Frees "f" fTs
  1512                     |> mk_Frees "f" fTs
  1506                     ||>> mk_Frees "R" (map2 mk_pred2T As Bs)
  1513                     ||>> mk_Frees "R" (map2 mk_pred2T As Bs)
  1507                     ||>> yield_singleton (mk_Frees "a") TA
  1514                     ||>> yield_singleton (mk_Frees "a") TA
  1508                     ||>> yield_singleton (mk_Frees "b") TB;
  1515                     ||>> yield_singleton (mk_Frees "b") TB
       
  1516                     ||>> apfst HOLogic.mk_Trueprop o
       
  1517                       yield_singleton (mk_Frees "thesis") HOLogic.boolT;
  1509                   val map_term = mk_map_of_bnf Ds As Bs fp_bnf;
  1518                   val map_term = mk_map_of_bnf Ds As Bs fp_bnf;
  1510                   val ctrAs = map (mk_ctr ADs) ctrs;
  1519                   val ctrAs = map (mk_ctr ADs) ctrs;
  1511                   val setAs = map (mk_set ADs) (sets_of_bnf fp_bnf);
  1520                   val setAs = map (mk_set ADs) (sets_of_bnf fp_bnf);
  1512                   val discAs = map (mk_disc_or_sel ADs) discs;
  1521                   val discAs = map (mk_disc_or_sel ADs) discs;
  1513                   val selAss = map (map (mk_disc_or_sel ADs)) selss;
  1522                   val selAss = map (map (mk_disc_or_sel ADs)) selss;
  1514                   val discAs_selAss = flat (map2 (map o pair) discAs selAss);
  1523                   val discAs_selAss = flat (map2 (map o pair) discAs selAss);
       
  1524 
       
  1525                   val (set_cases_thms, set_cases_attrss) =
       
  1526                     let
       
  1527                       fun mk_prems assms elem t ctxt =
       
  1528                         (case fastype_of t of
       
  1529                           Type (type_name, xs) =>
       
  1530                           (case bnf_of ctxt type_name of
       
  1531                             NONE => ([], ctxt)
       
  1532                           | SOME bnf =>
       
  1533                             apfst flat (fold_map (fn set => fn ctxt =>
       
  1534                               let
       
  1535                                 val X = HOLogic.dest_setT (range_type (fastype_of set));
       
  1536                                 val new_var = not (X = fastype_of elem);
       
  1537                                 val (x, ctxt') =
       
  1538                                   if new_var then yield_singleton (mk_Frees "x") X ctxt
       
  1539                                   else (elem, ctxt);
       
  1540                               in
       
  1541                                 mk_prems (mk_Trueprop_mem (x, set $ t) :: assms) elem x ctxt'
       
  1542                                 |>> map (if new_var then Logic.all x else I)
       
  1543                               end) (map (mk_set xs) (sets_of_bnf bnf)) ctxt))
       
  1544                         | T => rpair ctxt
       
  1545                           (if T = fastype_of elem then [fold (curry Logic.mk_implies) assms thesis]
       
  1546                            else []));
       
  1547                     in
       
  1548                       split_list (map (fn set =>
       
  1549                         let
       
  1550                           val A = HOLogic.dest_setT (range_type (fastype_of set));
       
  1551                           val (elem, names_lthy) = yield_singleton (mk_Frees "e") A names_lthy;
       
  1552                           val premss =
       
  1553                             map (fn ctr =>
       
  1554                               let
       
  1555                                 val (args, names_lthy) =
       
  1556                                   mk_Frees "z" (binder_types (fastype_of ctr)) names_lthy;
       
  1557                               in
       
  1558                                 flat (zipping_map (fn (prev_args, arg, next_args) =>
       
  1559                                   let
       
  1560                                     val (args_with_elem, args_without_elem) =
       
  1561                                       if fastype_of arg = A then
       
  1562                                         (prev_args @ [elem] @ next_args, prev_args @ next_args)
       
  1563                                       else
       
  1564                                         `I (prev_args @ [arg] @ next_args);
       
  1565                                   in
       
  1566                                     mk_prems
       
  1567                                       [mk_Trueprop_eq (ta, Term.list_comb (ctr, args_with_elem))]
       
  1568                                       elem arg names_lthy
       
  1569                                     |> fst
       
  1570                                     |> map (fold_rev Logic.all args_without_elem)
       
  1571                                   end) args)
       
  1572                               end) ctrAs;
       
  1573                           val goal = Logic.mk_implies (mk_Trueprop_mem (elem, set $ ta), thesis);
       
  1574                           val thm =
       
  1575                             Goal.prove_sorry lthy [] (flat premss) goal
       
  1576                               (fn {context = ctxt, prems} =>
       
  1577                                 mk_set_cases_tac ctxt (certify ctxt ta) prems exhaust set_thms)
       
  1578                             |> singleton (Proof_Context.export names_lthy lthy)
       
  1579                             |> Thm.close_derivation
       
  1580                             |> rotate_prems ~1;
       
  1581                         in
       
  1582                           (thm, [](* TODO: [@{attributes [elim?]},
       
  1583                             Attrib.internal (K (Induct.cases_pred (name_of_set set)))] *))
       
  1584                         end) setAs)
       
  1585                     end;
  1515 
  1586 
  1516                   val set_intros_thms =
  1587                   val set_intros_thms =
  1517                     let
  1588                     let
  1518                       fun mk_goals A setA ctr_args t ctxt =
  1589                       fun mk_goals A setA ctr_args t ctxt =
  1519                         (case fastype_of t of
  1590                         (case fastype_of t of
  1591                           |> map Thm.close_derivation
  1662                           |> map Thm.close_derivation
  1592                     end;
  1663                     end;
  1593 
  1664 
  1594                   val (rel_cases_thm, rel_cases_attrs) =
  1665                   val (rel_cases_thm, rel_cases_attrs) =
  1595                     let
  1666                     let
  1596                       val (thesis, names_lthy) = apfst HOLogic.mk_Trueprop
       
  1597                         (yield_singleton (mk_Frees "thesis") HOLogic.boolT names_lthy);
       
  1598 
       
  1599                       val rel_Rs_a_b = list_comb (rel, Rs) $ ta $ tb;
  1667                       val rel_Rs_a_b = list_comb (rel, Rs) $ ta $ tb;
  1600                       val ctrBs = map (mk_ctr BDs) ctrs;
  1668                       val ctrBs = map (mk_ctr BDs) ctrs;
  1601 
  1669 
  1602                       fun mk_assms ctrA ctrB ctxt =
  1670                       fun mk_assms ctrA ctrB ctxt =
  1603                         let
  1671                         let
  1759                           |> Proof_Context.export names_lthy lthy
  1827                           |> Proof_Context.export names_lthy lthy
  1760                           |> map Thm.close_derivation
  1828                           |> map Thm.close_derivation
  1761                     end;
  1829                     end;
  1762                 in
  1830                 in
  1763                   (disc_map_iff_thms, sel_map_thms, sel_set_thms, rel_sel_thms, set_intros_thms,
  1831                   (disc_map_iff_thms, sel_map_thms, sel_set_thms, rel_sel_thms, set_intros_thms,
  1764                     (rel_cases_thm, rel_cases_attrs))
  1832                     (set_cases_thms, set_cases_attrss), (rel_cases_thm, rel_cases_attrs))
  1765                 end;
  1833                 end;
  1766 
  1834 
  1767               val anonymous_notes =
  1835               val anonymous_notes =
  1768                 [([case_cong], fundefcong_attrs),
  1836                 [([case_cong], fundefcong_attrs),
  1769                  (rel_eq_thms, code_nitpicksimp_attrs)]
  1837                  (rel_eq_thms, code_nitpicksimp_attrs)]
  1778                  (rel_introsN, rel_intro_thms, K []),
  1846                  (rel_introsN, rel_intro_thms, K []),
  1779                  (rel_selN, rel_sel_thms, K []),
  1847                  (rel_selN, rel_sel_thms, K []),
  1780                  (setN, set_thms, K (code_nitpicksimp_attrs @ simp_attrs)),
  1848                  (setN, set_thms, K (code_nitpicksimp_attrs @ simp_attrs)),
  1781                  (sel_mapN, sel_map_thms, K []),
  1849                  (sel_mapN, sel_map_thms, K []),
  1782                  (sel_setN, sel_set_thms, K []),
  1850                  (sel_setN, sel_set_thms, K []),
       
  1851                  (set_casesN, set_cases_thms, nth set_cases_attrss),
  1783                  (set_emptyN, set_empty_thms, K []),
  1852                  (set_emptyN, set_empty_thms, K []),
  1784                  (set_introsN, set_intros_thms, K [])]
  1853                  (set_introsN, set_intros_thms, K [])]
  1785                 |> massage_simple_notes fp_b_name;
  1854                 |> massage_simple_notes fp_b_name;
  1786 
  1855 
  1787               val (noted, lthy') =
  1856               val (noted, lthy') =