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 |
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; |