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 |