src/HOL/Tools/BNF/bnf_gfp_grec_sugar.ML
changeset 64705 7596b0736ab9
parent 64674 ef0a5fd30f3b
child 66251 cd935b7cb3fb
equal deleted inserted replaced
64704:08c2d80428ff 64705:7596b0736ab9
    85   let val thy = Proof_Context.theory_of lthy in
    85   let val thy = Proof_Context.theory_of lthy in
    86     Raw_Simplifier.rewrite_term thy unfold_id_thms1 []
    86     Raw_Simplifier.rewrite_term thy unfold_id_thms1 []
    87     #> Raw_Simplifier.rewrite_term thy @{thms BNF_Composition.id_bnf_def} []
    87     #> Raw_Simplifier.rewrite_term thy @{thms BNF_Composition.id_bnf_def} []
    88   end;
    88   end;
    89 
    89 
    90 fun unexpected_corec_call ctxt eqns t =
       
    91   error_at ctxt eqns ("Unexpected corecursive call in " ^ quote (Syntax.string_of_term ctxt t));
       
    92 fun unsupported_case_around_corec_call ctxt eqns t =
       
    93   error_at ctxt eqns ("Unsupported corecursive call under case expression " ^
       
    94     quote (Syntax.string_of_term ctxt t) ^ "\n(Define " ^
       
    95     quote (Syntax.string_of_typ ctxt (domain_type (fastype_of t))) ^
       
    96     " with  discriminators and selectors to circumvent this limitation.)");
       
    97 
       
    98 datatype corec_option =
    90 datatype corec_option =
    99   Plugins_Option of Proof.context -> Plugin_Name.filter |
    91   Plugins_Option of Proof.context -> Plugin_Name.filter |
   100   Friend_Option |
    92   Friend_Option |
   101   Transfer_Option;
    93   Transfer_Option;
   102 
    94 
   752   let
   744   let
   753     val (fun_t, arg_ts) = strip_comb lhs;
   745     val (fun_t, arg_ts) = strip_comb lhs;
   754 
   746 
   755     fun check_fun_name () =
   747     fun check_fun_name () =
   756       null fun_frees orelse member (op aconv) fun_frees fun_t orelse
   748       null fun_frees orelse member (op aconv) fun_frees fun_t orelse
   757       error (quote (Syntax.string_of_term ctxt fun_t) ^
   749       ill_formed_equation_head ctxt [] fun_t;
   758         " is not the function currently being defined");
       
   759 
       
   760     fun check_args_are_vars () =
       
   761       let
       
   762         fun is_ok_Free_or_Var (Free (s, _)) = not (String.isSuffix inner_fp_suffix s)
       
   763           | is_ok_Free_or_Var (Var _) = true
       
   764           | is_ok_Free_or_Var _ = false;
       
   765 
       
   766         fun is_valid arg =
       
   767           (is_ok_Free_or_Var arg andalso not (member (op aconv) fun_frees arg)) orelse
       
   768           error ("Argument " ^ quote (Syntax.string_of_term ctxt arg) ^ " is not free");
       
   769       in
       
   770         forall is_valid arg_ts
       
   771       end;
       
   772 
       
   773     fun check_no_duplicate_arg () =
       
   774       (case duplicates (op =) arg_ts of
       
   775         [] => ()
       
   776       | arg :: _ => error ("Repeated argument: " ^ quote (Syntax.string_of_term ctxt arg)));
       
   777 
   750 
   778     fun check_no_other_frees () =
   751     fun check_no_other_frees () =
   779       (case Term.add_frees rhs [] |> map Free |> subtract (op =) (fun_frees @ arg_ts)
   752       (case Term.add_frees rhs [] |> map Free |> subtract (op =) (fun_frees @ arg_ts)
   780           |> filter_out (Variable.is_fixed ctxt o fst o dest_Free) of
   753           |> find_first (not o Variable.is_fixed ctxt o fst o dest_Free) of
   781         [] => ()
   754         NONE => ()
   782       | Free (s, _) :: _ => error ("Extra variable on right-hand side: " ^ quote s));
   755       | SOME t => extra_variable_in_rhs ctxt [] t);
   783   in
   756   in
   784     check_no_duplicate_arg ();
   757     check_duplicate_variables_in_lhs ctxt [] arg_ts;
   785     check_fun_name ();
   758     check_fun_name ();
   786     check_args_are_vars ();
   759     check_all_fun_arg_frees ctxt [] (filter_out is_Var arg_ts);
   787     check_no_other_frees ()
   760     check_no_other_frees ()
   788   end;
   761   end;
   789 
   762 
   790 fun parse_corec_equation ctxt fun_frees eq =
   763 fun parse_corec_equation ctxt fun_frees eq =
   791   let
   764   let
   792     val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (drop_all eq))
   765     val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (drop_all eq))
   793       handle TERM _ => error "Expected HOL equation";
   766       handle TERM _ => ill_formed_equation_lhs_rhs ctxt [eq];
   794 
   767 
   795     val _ = check_corec_equation ctxt fun_frees (lhs, rhs);
   768     val _ = check_corec_equation ctxt fun_frees (lhs, rhs);
   796 
   769 
   797     val (fun_t, arg_ts) = strip_comb lhs;
   770     val (fun_t, arg_ts) = strip_comb lhs;
   798     val (arg_Ts, _) = strip_type (fastype_of fun_t);
   771     val (arg_Ts, _) = strip_type (fastype_of fun_t);
  1534               explore params t
  1507               explore params t
  1535           end
  1508           end
  1536         | NONE => explore params t)
  1509         | NONE => explore params t)
  1537       | _ => explore params t)
  1510       | _ => explore params t)
  1538     and explore_cond params t =
  1511     and explore_cond params t =
  1539       if has_self_call t then
  1512       if has_self_call t then unexpected_rec_call_in lthy [] t else explore_inner params t
  1540         error ("Unallowed corecursive call in condition " ^ quote (Syntax.string_of_term lthy t))
       
  1541       else
       
  1542         explore_inner params t
       
  1543     and explore_inner params t =
  1513     and explore_inner params t =
  1544       massage_rho explore_inner_general params t
  1514       massage_rho explore_inner_general params t
  1545     and explore_inner_general (params as {bound_Us, bound_Ts, T, ...}) t =
  1515     and explore_inner_general (params as {bound_Us, bound_Ts, T, ...}) t =
  1546       let val (fun_t, arg_ts) = strip_comb t in
  1516       let val (fun_t, arg_ts) = strip_comb t in
  1547         if is_constant t then
  1517         if is_constant t then
  1558                 fun_t $ arg'
  1528                 fun_t $ arg'
  1559               else if arg_U = YpreT then
  1529               else if arg_U = YpreT then
  1560                 disc' $ arg'
  1530                 disc' $ arg'
  1561               else
  1531               else
  1562                 error ("Discriminator " ^ quote (Syntax.string_of_term lthy fun_t) ^
  1532                 error ("Discriminator " ^ quote (Syntax.string_of_term lthy fun_t) ^
  1563                   " cannot be applied to non-lhs argument " ^
  1533                   " cannot be applied to non-variable " ^
  1564                   quote (Syntax.string_of_term lthy (hd arg_ts)))
  1534                   quote (Syntax.string_of_term lthy (hd arg_ts)))
  1565             end
  1535             end
  1566           | _ =>
  1536           | _ =>
  1567             (case as_member_of sels fun_t of
  1537             (case as_member_of sels fun_t of
  1568               SOME sel' =>
  1538               SOME sel' =>
  1574                   build_function_after_encapsulation fun_t fun_t params arg_ts arg_ts'
  1544                   build_function_after_encapsulation fun_t fun_t params arg_ts arg_ts'
  1575                 else if arg_U = YpreT then
  1545                 else if arg_U = YpreT then
  1576                   build_function_after_encapsulation fun_t sel' params arg_ts arg_ts'
  1546                   build_function_after_encapsulation fun_t sel' params arg_ts arg_ts'
  1577                 else
  1547                 else
  1578                   error ("Selector " ^ quote (Syntax.string_of_term lthy fun_t) ^
  1548                   error ("Selector " ^ quote (Syntax.string_of_term lthy fun_t) ^
  1579                     " cannot be applied to non-lhs argument " ^
  1549                     " cannot be applied to non-variable " ^
  1580                     quote (Syntax.string_of_term lthy (hd arg_ts)))
  1550                     quote (Syntax.string_of_term lthy (hd arg_ts)))
  1581               end
  1551               end
  1582             | NONE =>
  1552             | NONE =>
  1583               (case as_member_of friends fun_t of
  1553               (case as_member_of friends fun_t of
  1584                 SOME (_, friend') =>
  1554                 SOME (_, friend') =>
  1613         val ctr_opt = as_member_of ctr_guards fun_t;
  1583         val ctr_opt = as_member_of ctr_guards fun_t;
  1614       in
  1584       in
  1615         if is_some ctr_opt then
  1585         if is_some ctr_opt then
  1616           rebuild_function_after_exploration fun_t (the ctr_opt) explore_inner params arg_ts
  1586           rebuild_function_after_exploration fun_t (the ctr_opt) explore_inner params arg_ts
  1617         else
  1587         else
  1618           error ("Constructor expected on right-hand side, " ^
  1588           not_constructor_in_rhs lthy [] fun_t
  1619             quote (Syntax.string_of_term lthy fun_t) ^ " found instead")
       
  1620       end;
  1589       end;
  1621 
  1590 
  1622     val rho_rhs = rhs
  1591     val rho_rhs = rhs
  1623       |> explore_ctr (build_params [] [] (fastype_of rhs))
  1592       |> explore_ctr (build_params [] [] (fastype_of rhs))
  1624       |> abs_tuple_balanced (map (map_types (fpT_to YpreT)) lhs_args)
  1593       |> abs_tuple_balanced (map (map_types (fpT_to YpreT)) lhs_args)
  1646     val rho_rhsZ = substT Y Z rho_rhs;
  1615     val rho_rhsZ = substT Y Z rho_rhs;
  1647   in
  1616   in
  1648     HOLogic.mk_Trueprop (rho_rel $ rho_rhs $ rho_rhsZ)
  1617     HOLogic.mk_Trueprop (rho_rel $ rho_rhs $ rho_rhsZ)
  1649   end;
  1618   end;
  1650 
  1619 
  1651 fun extract_rho_return_transfer_goals fun_b version dead_pre_bnf dead_k_bnf Y Z preT fun_T k_T
  1620 fun extract_rho_return_transfer_goals fun_b version dead_pre_bnf dead_k_bnf Y Z preT k_T ssig_T
  1652     ssig_T ssig_fp_sugar friend_parse_info fun_t parsed_eq lthy =
  1621     ssig_fp_sugar friend_parse_info fun_t parsed_eq lthy =
  1653   let
  1622   let
  1654     val Type (fpT_name, _) = body_type fun_T;
       
  1655 
       
  1656     fun mk_rel T bnf =
  1623     fun mk_rel T bnf =
  1657       let
  1624       let
  1658         val ZT = Tsubst Y Z T;
  1625         val ZT = Tsubst Y Z T;
  1659         val rel_T = mk_predT [mk_pred2T Y Z, T, ZT];
  1626         val rel_T = mk_predT [mk_pred2T Y Z, T, ZT];
  1660       in
  1627       in
  1732       else
  1699       else
  1733         explore params t
  1700         explore params t
  1734 
  1701 
  1735     fun massage_let_if_case_corec explore {bound_Ts, U, T, ...} t =
  1702     fun massage_let_if_case_corec explore {bound_Ts, U, T, ...} t =
  1736       massage_let_if_case ctxt has_self_call (fn bound_Ts => explore (build_params bound_Ts U T))
  1703       massage_let_if_case ctxt has_self_call (fn bound_Ts => explore (build_params bound_Ts U T))
  1737         (K (unexpected_corec_call ctxt [t])) (K (unsupported_case_around_corec_call ctxt [t]))
  1704         (K (unexpected_corec_call_in ctxt [t])) (K (unsupported_case_around_corec_call ctxt [t]))
  1738         bound_Ts t;
  1705         bound_Ts t;
  1739 
  1706 
  1740     val massage_map_let_if_case =
  1707     val massage_map_let_if_case =
  1741       massage_star [massage_map_corec, massage_fun, massage_comp, massage_let_if_case_corec];
  1708       massage_star [massage_map_corec, massage_fun, massage_comp, massage_let_if_case_corec];
  1742 
  1709 
  2002 
  1969 
  2003     val (plugins, friend, transfer) = get_options lthy opts;
  1970     val (plugins, friend, transfer) = get_options lthy opts;
  2004     val ([((b, fun_T), mx)], [(_, eq)]) =
  1971     val ([((b, fun_T), mx)], [(_, eq)]) =
  2005       fst (Specification.read_multi_specs raw_fixes [((Binding.empty_atts, raw_eq), [], [])] lthy);
  1972       fst (Specification.read_multi_specs raw_fixes [((Binding.empty_atts, raw_eq), [], [])] lthy);
  2006 
  1973 
  2007     val _ = Sign.of_sort (Proof_Context.theory_of lthy) (fun_T, @{sort type}) orelse
  1974     val _ = check_top_sort lthy b fun_T;
  2008       error ("Type of " ^ Binding.print b ^ " contains top sort");
       
  2009 
  1975 
  2010     val (arg_Ts, res_T) = strip_type fun_T;
  1976     val (arg_Ts, res_T) = strip_type fun_T;
  2011     val fpT_name = (case res_T of Type (s, _) => s | _ => not_codatatype lthy res_T);
  1977     val fpT_name = (case res_T of Type (s, _) => s | _ => not_codatatype lthy res_T);
  2012     val fun_free = Free (Binding.name_of b, fun_T);
  1978     val fun_free = Free (Binding.name_of b, fun_T);
  2013     val parsed_eq = parse_corec_equation lthy [fun_free] eq;
  1979     val parsed_eq = parse_corec_equation lthy [fun_free] eq;
  2028         val friend_parse_info = friend_parse_info_of lthy arg_Ts res_T buffer;
  1994         val friend_parse_info = friend_parse_info_of lthy arg_Ts res_T buffer;
  2029 
  1995 
  2030         val parsed_eq' = parsed_eq ||> subst_atomic [(fun_free, fun_t)];
  1996         val parsed_eq' = parsed_eq ||> subst_atomic [(fun_free, fun_t)];
  2031       in
  1997       in
  2032         lthy
  1998         lthy
  2033         |> extract_rho_return_transfer_goals b version dead_pre_bnf dead_k_bnf Y Z preT fun_T k_T
  1999         |> extract_rho_return_transfer_goals b version dead_pre_bnf dead_k_bnf Y Z preT k_T ssig_T
  2034           ssig_T ssig_fp_sugar friend_parse_info fun_t parsed_eq'
  2000           ssig_fp_sugar friend_parse_info fun_t parsed_eq'
  2035         |>> pair prepared
  2001         |>> pair prepared
  2036       end;
  2002       end;
  2037 
  2003 
  2038     val ((prepareds, (rho_datas, transfer_goal_datas)), lthy) =
  2004     val ((prepareds, (rho_datas, transfer_goal_datas)), lthy) =
  2039       if friend then extract_rho lthy |>> (apfst single ##> (apfst single #> apsnd single))
  2005       if friend then extract_rho lthy |>> (apfst single ##> (apfst single #> apsnd single))
  2275     val code_goal = Syntax.read_prop fake_lthy raw_eq;
  2241     val code_goal = Syntax.read_prop fake_lthy raw_eq;
  2276 
  2242 
  2277     val fun_T =
  2243     val fun_T =
  2278       (case code_goal of
  2244       (case code_goal of
  2279         @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ t $ _) => fastype_of (head_of t)
  2245         @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ t $ _) => fastype_of (head_of t)
  2280       | _ => error "Expected HOL equation");
  2246       | _ => ill_formed_equation_lhs_rhs lthy [code_goal]);
  2281     val fun_t = Const (fun_name, fun_T);
  2247     val fun_t = Const (fun_name, fun_T);
  2282 
  2248 
  2283     val (arg_Ts, res_T as Type (fpT_name, _)) = strip_type fun_T;
  2249     val (arg_Ts, res_T as Type (fpT_name, _)) = strip_type fun_T;
  2284 
  2250 
  2285     val no_base = has_no_corec_info lthy fpT_name;
  2251     val no_base = has_no_corec_info lthy fpT_name;
  2292     val friend_parse_info = friend_parse_info_of lthy arg_Ts res_T buffer;
  2258     val friend_parse_info = friend_parse_info_of lthy arg_Ts res_T buffer;
  2293 
  2259 
  2294     val parsed_eq = parse_corec_equation lthy [] code_goal;
  2260     val parsed_eq = parse_corec_equation lthy [] code_goal;
  2295 
  2261 
  2296     val (((rho, rho_def), (const_transfer_goals, rho_transfer_goal)), lthy) =
  2262     val (((rho, rho_def), (const_transfer_goals, rho_transfer_goal)), lthy) =
  2297       extract_rho_return_transfer_goals fun_b version dead_pre_bnf dead_k_bnf Y Z preT fun_T k_T
  2263       extract_rho_return_transfer_goals fun_b version dead_pre_bnf dead_k_bnf Y Z preT k_T ssig_T
  2298         ssig_T ssig_fp_sugar friend_parse_info fun_t parsed_eq lthy;
  2264         ssig_fp_sugar friend_parse_info fun_t parsed_eq lthy;
  2299 
  2265 
  2300     fun register_friend_extra_and_note_thms code_goal code_thm const_transfers k_T friend_info
  2266     fun register_friend_extra_and_note_thms code_goal code_thm const_transfers k_T friend_info
  2301         lthy =
  2267         lthy =
  2302       let
  2268       let
  2303         val (corec_info, lthy) = corec_info_of res_T lthy;
  2269         val (corec_info, lthy) = corec_info_of res_T lthy;