src/HOL/Tools/BNF/bnf_gfp_rec_sugar.ML
changeset 55527 171d73e39d6d
parent 55480 59cc4a8bc28a
child 55529 51998cb9d6b8
equal deleted inserted replaced
55526:39708e59f4b0 55527:171d73e39d6d
    40 
    40 
    41 val nitpicksimp_attrs = @{attributes [nitpick_simp]};
    41 val nitpicksimp_attrs = @{attributes [nitpick_simp]};
    42 val simp_attrs = @{attributes [simp]};
    42 val simp_attrs = @{attributes [simp]};
    43 val code_nitpicksimp_attrs = Code.add_default_eqn_attrib :: nitpicksimp_attrs;
    43 val code_nitpicksimp_attrs = Code.add_default_eqn_attrib :: nitpicksimp_attrs;
    44 
    44 
    45 exception Primcorec_Error of string * term list;
    45 exception PRIMCOREC of string * term list;
    46 
    46 
    47 fun primcorec_error str = raise Primcorec_Error (str, []);
    47 fun primcorec_error str = raise PRIMCOREC (str, []);
    48 fun primcorec_error_eqn str eqn = raise Primcorec_Error (str, [eqn]);
    48 fun primcorec_error_eqn str eqn = raise PRIMCOREC (str, [eqn]);
    49 fun primcorec_error_eqns str eqns = raise Primcorec_Error (str, eqns);
    49 fun primcorec_error_eqns str eqns = raise PRIMCOREC (str, eqns);
    50 
    50 
    51 datatype primcorec_option = Sequential_Option | Exhaustive_Option;
    51 datatype primcorec_option = Sequential_Option | Exhaustive_Option;
    52 
    52 
    53 datatype corec_call =
    53 datatype corec_call =
    54   Dummy_No_Corec of int |
    54   Dummy_No_Corec of int |
    81    nested_maps: thm list,
    81    nested_maps: thm list,
    82    nested_map_idents: thm list,
    82    nested_map_idents: thm list,
    83    nested_map_comps: thm list,
    83    nested_map_comps: thm list,
    84    ctr_specs: corec_ctr_spec list};
    84    ctr_specs: corec_ctr_spec list};
    85 
    85 
    86 exception AINT_NO_MAP of term;
    86 exception NOT_A_MAP of term;
    87 
    87 
    88 fun not_codatatype ctxt T =
    88 fun not_codatatype ctxt T =
    89   error ("Not a codatatype: " ^ Syntax.string_of_typ ctxt T);
    89   error ("Not a codatatype: " ^ Syntax.string_of_typ ctxt T);
    90 fun ill_formed_corec_call ctxt t =
    90 fun ill_formed_corec_call ctxt t =
    91   error ("Ill-formed corecursive call: " ^ quote (Syntax.string_of_term ctxt t));
    91   error ("Ill-formed corecursive call: " ^ quote (Syntax.string_of_term ctxt t));
   257             val fs' =
   257             val fs' =
   258               map_flattened_map_args ctxt s (map3 (massage_map_or_map_arg bound_Ts) Us Ts) fs;
   258               map_flattened_map_args ctxt s (map3 (massage_map_or_map_arg bound_Ts) Us Ts) fs;
   259           in
   259           in
   260             Term.list_comb (map', fs')
   260             Term.list_comb (map', fs')
   261           end
   261           end
   262         | NONE => raise AINT_NO_MAP t)
   262         | NONE => raise NOT_A_MAP t)
   263       | massage_map _ _ _ t = raise AINT_NO_MAP t
   263       | massage_map _ _ _ t = raise NOT_A_MAP t
   264     and massage_map_or_map_arg bound_Ts U T t =
   264     and massage_map_or_map_arg bound_Ts U T t =
   265       if T = U then
   265       if T = U then
   266         tap check_no_call t
   266         tap check_no_call t
   267       else
   267       else
   268         massage_map bound_Ts U T t
   268         massage_map bound_Ts U T t
   269         handle AINT_NO_MAP _ => massage_mutual_fun bound_Ts U T t
   269         handle NOT_A_MAP _ => massage_mutual_fun bound_Ts U T t
   270     and massage_mutual_fun bound_Ts U T t =
   270     and massage_mutual_fun bound_Ts U T t =
   271       (case t of
   271       (case t of
   272         Const (@{const_name comp}, _) $ t1 $ t2 =>
   272         Const (@{const_name comp}, _) $ t1 $ t2 =>
   273         mk_comp bound_Ts (massage_mutual_fun bound_Ts U T t1, tap check_no_call t2)
   273         mk_comp bound_Ts (massage_mutual_fun bound_Ts U T t1, tap check_no_call t2)
   274       | _ =>
   274       | _ =>
   305               | t1 $ t2 =>
   305               | t1 $ t2 =>
   306                 (if has_call t2 then
   306                 (if has_call t2 then
   307                   massage_mutual_call bound_Ts U T t
   307                   massage_mutual_call bound_Ts U T t
   308                 else
   308                 else
   309                   massage_map bound_Ts U T t1 $ t2
   309                   massage_map bound_Ts U T t1 $ t2
   310                   handle AINT_NO_MAP _ => massage_mutual_call bound_Ts U T t)
   310                   handle NOT_A_MAP _ => massage_mutual_call bound_Ts U T t)
   311               | Abs (s, T', t') =>
   311               | Abs (s, T', t') =>
   312                 Abs (s, T', massage_call (T' :: bound_Ts) (range_type U) (range_type T) t')
   312                 Abs (s, T', massage_call (T' :: bound_Ts) (range_type U) (range_type T) t')
   313               | _ => massage_mutual_call bound_Ts U T t))
   313               | _ => massage_mutual_call bound_Ts U T t))
   314           | _ => ill_formed_corec_call ctxt t)
   314           | _ => ill_formed_corec_call ctxt t)
   315         else
   315         else
   592 fun dissect_coeqn_sel fun_names (basic_ctr_specss : basic_corec_ctr_spec list list) eqn_pos
   592 fun dissect_coeqn_sel fun_names (basic_ctr_specss : basic_corec_ctr_spec list list) eqn_pos
   593     ctr_rhs_opt code_rhs_opt eqn0 of_spec_opt eqn =
   593     ctr_rhs_opt code_rhs_opt eqn0 of_spec_opt eqn =
   594   let
   594   let
   595     val (lhs, rhs) = HOLogic.dest_eq eqn
   595     val (lhs, rhs) = HOLogic.dest_eq eqn
   596       handle TERM _ =>
   596       handle TERM _ =>
   597         primcorec_error_eqn "malformed function equation (expected \"lhs = rhs\")" eqn;
   597              primcorec_error_eqn "malformed function equation (expected \"lhs = rhs\")" eqn;
   598     val sel = head_of lhs;
   598     val sel = head_of lhs;
   599     val ((fun_name, fun_T), fun_args) = dest_comb lhs |> snd |> strip_comb |> apfst dest_Free
   599     val ((fun_name, fun_T), fun_args) = dest_comb lhs |> snd |> strip_comb |> apfst dest_Free
   600       handle TERM _ =>
   600       handle TERM _ =>
   601         primcorec_error_eqn "malformed selector argument in left-hand side" eqn;
   601              primcorec_error_eqn "malformed selector argument in left-hand side" eqn;
   602     val basic_ctr_specs = the (AList.lookup (op =) (fun_names ~~ basic_ctr_specss) fun_name)
   602     val basic_ctr_specs = the (AList.lookup (op =) (fun_names ~~ basic_ctr_specss) fun_name)
   603       handle Option.Option =>
   603       handle Option.Option =>
   604         primcorec_error_eqn "malformed selector argument in left-hand side" eqn;
   604              primcorec_error_eqn "malformed selector argument in left-hand side" eqn;
   605     val {ctr, ...} =
   605     val {ctr, ...} =
   606       (case of_spec_opt of
   606       (case of_spec_opt of
   607         SOME of_spec => the (find_first (curry (op =) of_spec o #ctr) basic_ctr_specs)
   607         SOME of_spec => the (find_first (curry (op =) of_spec o #ctr) basic_ctr_specs)
   608       | NONE => filter (exists (curry (op =) sel) o #sels) basic_ctr_specs |> the_single
   608       | NONE => filter (exists (curry (op =) sel) o #sels) basic_ctr_specs |> the_single
   609           handle List.Empty => primcorec_error_eqn "ambiguous selector - use \"of\"" eqn);
   609           handle List.Empty => primcorec_error_eqn "ambiguous selector - use \"of\"" eqn);
  1352     val ((fixes, specs), _) = Specification.read_spec raw_fixes raw_specs lthy;
  1352     val ((fixes, specs), _) = Specification.read_spec raw_fixes raw_specs lthy;
  1353   in
  1353   in
  1354     add_primcorec_ursive auto opts fixes specs of_specs_opt lthy
  1354     add_primcorec_ursive auto opts fixes specs of_specs_opt lthy
  1355     handle ERROR str => primcorec_error str
  1355     handle ERROR str => primcorec_error str
  1356   end
  1356   end
  1357   handle Primcorec_Error (str, eqns) =>
  1357   handle PRIMCOREC (str, eqns) =>
  1358     if null eqns
  1358          if null eqns then
  1359     then error ("primcorec error:\n  " ^ str)
  1359            error ("primcorec error:\n  " ^ str)
  1360     else error ("primcorec error:\n  " ^ str ^ "\nin\n  " ^
  1360          else
  1361       space_implode "\n  " (map (quote o Syntax.string_of_term lthy) eqns));
  1361            error ("primcorec error:\n  " ^ str ^ "\nin\n  " ^
       
  1362              space_implode "\n  " (map (quote o Syntax.string_of_term lthy) eqns));
  1362 
  1363 
  1363 val add_primcorecursive_cmd = (fn (goalss, after_qed, lthy) =>
  1364 val add_primcorecursive_cmd = (fn (goalss, after_qed, lthy) =>
  1364   lthy
  1365   lthy
  1365   |> Proof.theorem NONE after_qed goalss
  1366   |> Proof.theorem NONE after_qed goalss
  1366   |> Proof.refine (Method.primitive_text (K I))
  1367   |> Proof.refine (Method.primitive_text (K I))