src/HOL/Tools/BNF/bnf_gfp_rec_sugar.ML
changeset 59058 a78612c67ec0
parent 59044 c04eccae1de8
child 59275 77cd4992edcd
equal deleted inserted replaced
59057:5b649fb2f2e1 59058:a78612c67ec0
   126 fun invalid_map ctxt t =
   126 fun invalid_map ctxt t =
   127   error ("Invalid map function in " ^ quote (Syntax.string_of_term ctxt t));
   127   error ("Invalid map function in " ^ quote (Syntax.string_of_term ctxt t));
   128 fun unexpected_corec_call ctxt t =
   128 fun unexpected_corec_call ctxt t =
   129   error ("Unexpected corecursive call: " ^ quote (Syntax.string_of_term ctxt t));
   129   error ("Unexpected corecursive call: " ^ quote (Syntax.string_of_term ctxt t));
   130 
   130 
   131 fun sort_list_duplicates xs = map snd (sort (int_ord o pairself fst) xs);
   131 fun sort_list_duplicates xs = map snd (sort (int_ord o apply2 fst) xs);
   132 
   132 
   133 val mk_conjs = try (foldr1 HOLogic.mk_conj) #> the_default @{const True};
   133 val mk_conjs = try (foldr1 HOLogic.mk_conj) #> the_default @{const True};
   134 val mk_disjs = try (foldr1 HOLogic.mk_disj) #> the_default @{const False};
   134 val mk_disjs = try (foldr1 HOLogic.mk_disj) #> the_default @{const False};
   135 val mk_dnf = mk_disjs o map mk_conjs;
   135 val mk_dnf = mk_disjs o map mk_conjs;
   136 
   136 
   413       nested_to_mutual_fps (K true) Greatest_FP bs res_Ts callers callssss0 lthy0;
   413       nested_to_mutual_fps (K true) Greatest_FP bs res_Ts callers callssss0 lthy0;
   414 
   414 
   415     val coinduct_attrs_pair =
   415     val coinduct_attrs_pair =
   416       (case gfp_sugar_thms of SOME ((_, attrs_pair), _, _, _, _) => attrs_pair | NONE => ([], []));
   416       (case gfp_sugar_thms of SOME ((_, attrs_pair), _, _, _, _) => attrs_pair | NONE => ([], []));
   417 
   417 
   418     val perm_fp_sugars = sort (int_ord o pairself #fp_res_index) fp_sugars;
   418     val perm_fp_sugars = sort (int_ord o apply2 #fp_res_index) fp_sugars;
   419 
   419 
   420     val indices = map #fp_res_index fp_sugars;
   420     val indices = map #fp_res_index fp_sugars;
   421     val perm_indices = map #fp_res_index perm_fp_sugars;
   421     val perm_indices = map #fp_res_index perm_fp_sugars;
   422 
   422 
   423     val perm_fpTs = map #T perm_fp_sugars;
   423     val perm_fpTs = map #T perm_fp_sugars;
   996           orelse primcorec_error_eqns ("missing equations for function(s): " ^ commas missing) []
   996           orelse primcorec_error_eqns ("missing equations for function(s): " ^ commas missing) []
   997       end;
   997       end;
   998 
   998 
   999     val callssss =
   999     val callssss =
  1000       map_filter (try (fn Sel x => x)) eqns_data
  1000       map_filter (try (fn Sel x => x)) eqns_data
  1001       |> partition_eq (op = o pairself #fun_name)
  1001       |> partition_eq (op = o apply2 #fun_name)
  1002       |> fst o finds (fn (x, ({fun_name, ...} :: _)) => x = fun_name) fun_names
  1002       |> fst o finds (fn (x, ({fun_name, ...} :: _)) => x = fun_name) fun_names
  1003       |> map (flat o snd)
  1003       |> map (flat o snd)
  1004       |> map2 (fold o find_corec_calls lthy has_call) basic_ctr_specss
  1004       |> map2 (fold o find_corec_calls lthy has_call) basic_ctr_specss
  1005       |> map2 (curry (op |>)) (map (map (fn {ctr, sels, ...} =>
  1005       |> map2 (curry (op |>)) (map (map (fn {ctr, sels, ...} =>
  1006         (ctr, map (K []) sels))) basic_ctr_specss);
  1006         (ctr, map (K []) sels))) basic_ctr_specss);
  1010       corec_specs_of bs arg_Ts res_Ts frees callssss lthy;
  1010       corec_specs_of bs arg_Ts res_Ts frees callssss lthy;
  1011     val corec_specs = take actual_nn corec_specs';
  1011     val corec_specs = take actual_nn corec_specs';
  1012     val ctr_specss = map #ctr_specs corec_specs;
  1012     val ctr_specss = map #ctr_specs corec_specs;
  1013 
  1013 
  1014     val disc_eqnss' = map_filter (try (fn Disc x => x)) eqns_data
  1014     val disc_eqnss' = map_filter (try (fn Disc x => x)) eqns_data
  1015       |> partition_eq (op = o pairself #fun_name)
  1015       |> partition_eq (op = o apply2 #fun_name)
  1016       |> fst o finds (fn (x, ({fun_name, ...} :: _)) => x = fun_name) fun_names
  1016       |> fst o finds (fn (x, ({fun_name, ...} :: _)) => x = fun_name) fun_names
  1017       |> map (sort (op < o pairself #ctr_no |> make_ord) o flat o snd);
  1017       |> map (sort (op < o apply2 #ctr_no |> make_ord) o flat o snd);
  1018 
  1018 
  1019     val _ = disc_eqnss' |> map (fn x =>
  1019     val _ = disc_eqnss' |> map (fn x =>
  1020       let val d = duplicates (op = o pairself #ctr_no) x in null d orelse
  1020       let val d = duplicates (op = o apply2 #ctr_no) x in
  1021         (if forall (is_some o #ctr_rhs_opt) x then
  1021         null d orelse
  1022           primcorec_error_eqns "multiple equations for constructor(s)"
  1022          (if forall (is_some o #ctr_rhs_opt) x then
  1023             (maps (fn t => filter (curry (op =) (#ctr_no t) o #ctr_no) x) d
  1023             primcorec_error_eqns "multiple equations for constructor(s)"
  1024               |> map (the o #ctr_rhs_opt)) else
  1024               (maps (fn t => filter (curry (op =) (#ctr_no t) o #ctr_no) x) d
  1025           primcorec_error_eqns "excess discriminator formula in definition"
  1025                 |> map (the o #ctr_rhs_opt))
  1026             (maps (fn t => filter (curry (op =) (#ctr_no t) o #ctr_no) x) d |> map #user_eqn)) end);
  1026           else
       
  1027             primcorec_error_eqns "excess discriminator formula in definition"
       
  1028               (maps (fn t => filter (curry (op =) (#ctr_no t) o #ctr_no) x) d |> map #user_eqn))
       
  1029       end);
  1027 
  1030 
  1028     val sel_eqnss = map_filter (try (fn Sel x => x)) eqns_data
  1031     val sel_eqnss = map_filter (try (fn Sel x => x)) eqns_data
  1029       |> partition_eq (op = o pairself #fun_name)
  1032       |> partition_eq (op = o apply2 #fun_name)
  1030       |> fst o finds (fn (x, ({fun_name, ...} :: _)) => x = fun_name) fun_names
  1033       |> fst o finds (fn (x, ({fun_name, ...} :: _)) => x = fun_name) fun_names
  1031       |> map (flat o snd);
  1034       |> map (flat o snd);
  1032 
  1035 
  1033     val arg_Tss = map (binder_types o snd o fst) fixes;
  1036     val arg_Tss = map (binder_types o snd o fst) fixes;
  1034     val disc_eqnss = @{map 6} mk_actual_disc_eqns bs arg_Tss exhaustives corec_specs sel_eqnss
  1037     val disc_eqnss = @{map 6} mk_actual_disc_eqns bs arg_Tss exhaustives corec_specs sel_eqnss
  1314                   NONE => []
  1317                   NONE => []
  1315                 | SOME (exhaustive_code, rhs, raw_rhs, ctr_thms) =>
  1318                 | SOME (exhaustive_code, rhs, raw_rhs, ctr_thms) =>
  1316                   let
  1319                   let
  1317                     val ms = map (Logic.count_prems o prop_of) ctr_thms;
  1320                     val ms = map (Logic.count_prems o prop_of) ctr_thms;
  1318                     val (raw_goal, goal) = (raw_rhs, rhs)
  1321                     val (raw_goal, goal) = (raw_rhs, rhs)
  1319                       |> pairself (curry mk_Trueprop_eq (applied_fun_of fun_name fun_T fun_args)
  1322                       |> apply2 (curry mk_Trueprop_eq (applied_fun_of fun_name fun_T fun_args)
  1320                         #> curry Logic.list_all (map dest_Free fun_args));
  1323                         #> curry Logic.list_all (map dest_Free fun_args));
  1321                     val (distincts, discIs, _, split_sels, split_sel_asms) =
  1324                     val (distincts, discIs, _, split_sels, split_sel_asms) =
  1322                       case_thms_of_term lthy raw_rhs;
  1325                       case_thms_of_term lthy raw_rhs;
  1323 
  1326 
  1324                     val raw_code_thm = mk_primcorec_raw_code_tac lthy distincts discIs split_sels
  1327                     val raw_code_thm = mk_primcorec_raw_code_tac lthy distincts discIs split_sels
  1370           |> map sort_list_duplicates;
  1373           |> map sort_list_duplicates;
  1371 
  1374 
  1372         val ctr_alists = @{map 6} (fn disc_alist => maps oooo prove_ctr disc_alist) disc_alists
  1375         val ctr_alists = @{map 6} (fn disc_alist => maps oooo prove_ctr disc_alist) disc_alists
  1373           (map (map snd) sel_alists) corec_specs disc_eqnss sel_eqnss ctr_specss;
  1376           (map (map snd) sel_alists) corec_specs disc_eqnss sel_eqnss ctr_specss;
  1374         val ctr_thmss0 = map (map snd) ctr_alists;
  1377         val ctr_thmss0 = map (map snd) ctr_alists;
  1375         val ctr_thmss = map (map (snd o snd) o sort (int_ord o pairself fst)) ctr_alists;
  1378         val ctr_thmss = map (map (snd o snd) o sort (int_ord o apply2 fst)) ctr_alists;
  1376 
  1379 
  1377         val code_thmss =
  1380         val code_thmss =
  1378           @{map 6} prove_code exhaustives disc_eqnss sel_eqnss nchotomy_thmss ctr_thmss0 ctr_specss;
  1381           @{map 6} prove_code exhaustives disc_eqnss sel_eqnss nchotomy_thmss ctr_thmss0 ctr_specss;
  1379 
  1382 
  1380         val disc_iff_or_disc_thmss =
  1383         val disc_iff_or_disc_thmss =