src/HOL/BNF/Tools/bnf_fp_rec_sugar.ML
changeset 53830 ed2eb7df2aac
parent 53822 6304b12c7627
child 53831 80423b9080cf
equal deleted inserted replaced
53829:92e71eb22ebe 53830:ed2eb7df2aac
   101     val (fun_name, args) = strip_comb lhs
   101     val (fun_name, args) = strip_comb lhs
   102       |>> (fn x => if is_Free x then fst (dest_Free x)
   102       |>> (fn x => if is_Free x then fst (dest_Free x)
   103           else primrec_error_eqn "malformed function equation (does not start with free)" eqn);
   103           else primrec_error_eqn "malformed function equation (does not start with free)" eqn);
   104     val (left_args, rest) = take_prefix is_Free args;
   104     val (left_args, rest) = take_prefix is_Free args;
   105     val (nonfrees, right_args) = take_suffix is_Free rest;
   105     val (nonfrees, right_args) = take_suffix is_Free rest;
   106     val _ = length nonfrees = 1 orelse if length nonfrees = 0 then
   106     val num_nonfrees = length nonfrees;
       
   107     val _ = num_nonfrees = 1 orelse if num_nonfrees = 0 then
   107       primrec_error_eqn "constructor pattern missing in left-hand side" eqn else
   108       primrec_error_eqn "constructor pattern missing in left-hand side" eqn else
   108       primrec_error_eqn "more than one non-variable argument in left-hand side" eqn;
   109       primrec_error_eqn "more than one non-variable argument in left-hand side" eqn;
   109     val _ = member (op =) fun_names fun_name orelse
   110     val _ = member (op =) fun_names fun_name orelse
   110       primrec_error_eqn "malformed function equation (does not start with function name)" eqn
   111       primrec_error_eqn "malformed function equation (does not start with function name)" eqn
   111 
   112 
   325     val res_Ts = map (#res_type o hd) funs_data;
   326     val res_Ts = map (#res_type o hd) funs_data;
   326     val callssss = funs_data
   327     val callssss = funs_data
   327       |> map (partition_eq ((op =) o pairself #ctr))
   328       |> map (partition_eq ((op =) o pairself #ctr))
   328       |> map (maps (map_filter (find_rec_calls has_call)));
   329       |> map (maps (map_filter (find_rec_calls has_call)));
   329 
   330 
   330     val ((nontriv, rec_specs, _, induct_thm, induct_thms), lthy') =
   331     val ((n2m, rec_specs, _, induct_thm, induct_thms), lthy') =
   331       rec_specs_of bs arg_Ts res_Ts (get_indices fixes) callssss lthy;
   332       rec_specs_of bs arg_Ts res_Ts (get_indices fixes) callssss lthy;
   332 
   333 
   333     val actual_nn = length funs_data;
   334     val actual_nn = length funs_data;
   334 
   335 
   335     val _ = let val ctrs = (maps (map #ctr o #ctr_specs) rec_specs) in
   336     val _ = let val ctrs = (maps (map #ctr o #ctr_specs) rec_specs) in
   351           |> map (fn (user_eqn, num_extra_args, rec_thm) =>
   352           |> map (fn (user_eqn, num_extra_args, rec_thm) =>
   352             mk_primrec_tac lthy num_extra_args nested_map_idents nested_map_comps def_thms rec_thm
   353             mk_primrec_tac lthy num_extra_args nested_map_idents nested_map_comps def_thms rec_thm
   353             |> K |> Goal.prove lthy [] [] user_eqn)
   354             |> K |> Goal.prove lthy [] [] user_eqn)
   354 
   355 
   355         val notes =
   356         val notes =
   356           [(inductN, if nontriv then [induct_thm] else [], []),
   357           [(inductN, if n2m then [induct_thm] else [], []),
   357            (simpsN, simp_thms, code_nitpick_simp_attrs @ simp_attrs)]
   358            (simpsN, simp_thms, code_nitpick_simp_attrs @ simp_attrs)]
   358           |> filter_out (null o #2)
   359           |> filter_out (null o #2)
   359           |> map (fn (thmN, thms, attrs) =>
   360           |> map (fn (thmN, thms, attrs) =>
   360             ((Binding.qualify true fun_name (Binding.name thmN), attrs), [(thms, [])]));
   361             ((Binding.qualify true fun_name (Binding.name thmN), attrs), [(thms, [])]));
   361       in
   362       in
   363       end;
   364       end;
   364 
   365 
   365     val common_name = mk_common_name fun_names;
   366     val common_name = mk_common_name fun_names;
   366 
   367 
   367     val common_notes =
   368     val common_notes =
   368       [(inductN, if nontriv then [induct_thm] else [], [])]
   369       [(inductN, if n2m then [induct_thm] else [], [])]
   369       |> filter_out (null o #2)
   370       |> filter_out (null o #2)
   370       |> map (fn (thmN, thms, attrs) =>
   371       |> map (fn (thmN, thms, attrs) =>
   371         ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])]));
   372         ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])]));
   372   in
   373   in
   373     lthy'
   374     lthy'
   697     val (bs, mxs) = map_split (apfst fst) fixes;
   698     val (bs, mxs) = map_split (apfst fst) fixes;
   698     val (arg_Ts, res_Ts) = map (strip_type o snd o fst #>> HOLogic.mk_tupleT) fixes |> split_list;
   699     val (arg_Ts, res_Ts) = map (strip_type o snd o fst #>> HOLogic.mk_tupleT) fixes |> split_list;
   699 
   700 
   700     val callssss = []; (* FIXME *)
   701     val callssss = []; (* FIXME *)
   701 
   702 
   702     val ((nontriv, corec_specs', _, coinduct_thm, strong_coinduct_thm, coinduct_thms,
   703     val ((n2m, corec_specs', _, coinduct_thm, strong_coinduct_thm, coinduct_thms,
   703           strong_coinduct_thms), lthy') =
   704           strong_coinduct_thms), lthy') =
   704       corec_specs_of bs arg_Ts res_Ts (get_indices fixes) callssss lthy;
   705       corec_specs_of bs arg_Ts res_Ts (get_indices fixes) callssss lthy;
   705 
   706 
       
   707     val actual_nn = length bs;
   706     val fun_names = map Binding.name_of bs;
   708     val fun_names = map Binding.name_of bs;
   707     val corec_specs = take (length fun_names) corec_specs'; (*###*)
   709     val corec_specs = take actual_nn corec_specs'; (*###*)
   708 
   710 
   709     val (eqns_data, _) =
   711     val (eqns_data, _) =
   710       fold_map (co_dissect_eqn sequential fun_names corec_specs) (map snd specs) []
   712       fold_map (co_dissect_eqn sequential fun_names corec_specs) (map snd specs) []
   711       |>> flat;
   713       |>> flat;
   712 
   714 
   855         val anonymous_notes =
   857         val anonymous_notes =
   856           [(flat safe_ctr_thmss, simp_attrs)]
   858           [(flat safe_ctr_thmss, simp_attrs)]
   857           |> map (fn (thms, attrs) => ((Binding.empty, attrs), [(thms, [])]));
   859           |> map (fn (thms, attrs) => ((Binding.empty, attrs), [(thms, [])]));
   858 
   860 
   859         val notes =
   861         val notes =
   860           [(coinductN, map (if nontriv then single else K []) coinduct_thms, []),
   862           [(coinductN, map (if n2m then single else K []) coinduct_thms, []),
   861            (codeN, ctr_thmss(*FIXME*), code_nitpick_simp_attrs),
   863            (codeN, ctr_thmss(*FIXME*), code_nitpick_simp_attrs),
   862            (ctrN, ctr_thmss, []),
   864            (ctrN, ctr_thmss, []),
   863            (discN, disc_thmss, simp_attrs),
   865            (discN, disc_thmss, simp_attrs),
   864            (selN, sel_thmss, simp_attrs),
   866            (selN, sel_thmss, simp_attrs),
   865            (simpsN, simp_thmss, []),
   867            (simpsN, simp_thmss, []),
   866            (strong_coinductN, map (if nontriv then single else K []) strong_coinduct_thms, [])]
   868            (strong_coinductN, map (if n2m then single else K []) strong_coinduct_thms, [])]
   867           |> maps (fn (thmN, thmss, attrs) =>
   869           |> maps (fn (thmN, thmss, attrs) =>
   868             map2 (fn fun_name => fn thms =>
   870             map2 (fn fun_name => fn thms =>
   869                 ((Binding.qualify true fun_name (Binding.name thmN), attrs), [(thms, [])]))
   871                 ((Binding.qualify true fun_name (Binding.name thmN), attrs), [(thms, [])]))
   870               fun_names thmss)
   872               fun_names (take actual_nn thmss))
   871           |> filter_out (null o fst o hd o snd);
   873           |> filter_out (null o fst o hd o snd);
   872 
   874 
   873         val common_notes =
   875         val common_notes =
   874           [(coinductN, if nontriv then [coinduct_thm] else [], []),
   876           [(coinductN, if n2m then [coinduct_thm] else [], []),
   875            (strong_coinductN, if nontriv then [strong_coinduct_thm] else [], [])]
   877            (strong_coinductN, if n2m then [strong_coinduct_thm] else [], [])]
   876           |> filter_out (null o #2)
   878           |> filter_out (null o #2)
   877           |> map (fn (thmN, thms, attrs) =>
   879           |> map (fn (thmN, thms, attrs) =>
   878             ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])]));
   880             ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])]));
   879       in
   881       in
   880         lthy |> Local_Theory.notes (anonymous_notes @ notes @ common_notes) |> snd
   882         lthy |> Local_Theory.notes (anonymous_notes @ notes @ common_notes) |> snd