src/HOL/Tools/BNF/bnf_gfp_rec_sugar.ML
changeset 59596 c067eba942e7
parent 59595 2d90b85b9264
child 59597 70a68edcc79b
equal deleted inserted replaced
59595:2d90b85b9264 59596:c067eba942e7
    89 fun ill_formed_corec_call ctxt t =
    89 fun ill_formed_corec_call ctxt t =
    90   error ("Ill-formed corecursive call " ^ quote (Syntax.string_of_term ctxt t));
    90   error ("Ill-formed corecursive call " ^ quote (Syntax.string_of_term ctxt t));
    91 fun invalid_map ctxt t =
    91 fun invalid_map ctxt t =
    92   error_at ctxt [t] "Invalid map function";
    92   error_at ctxt [t] "Invalid map function";
    93 fun unexpected_corec_call ctxt eqns t =
    93 fun unexpected_corec_call ctxt eqns t =
    94   error_at ctxt eqns ("Unexpected corecursive call " ^ quote (Syntax.string_of_term ctxt t));
    94   error_at ctxt eqns ("Unexpected corecursive call in " ^ quote (Syntax.string_of_term ctxt t));
    95 
    95 
    96 datatype corec_option =
    96 datatype corec_option =
    97   Plugins_Option of Proof.context -> Plugin_Name.filter |
    97   Plugins_Option of Proof.context -> Plugin_Name.filter |
    98   Sequential_Option |
    98   Sequential_Option |
    99   Exhaustive_Option |
    99   Exhaustive_Option |
   215 fun case_of ctxt s =
   215 fun case_of ctxt s =
   216   (case ctr_sugar_of ctxt s of
   216   (case ctr_sugar_of ctxt s of
   217     SOME {casex = Const (s', _), split_sels = _ :: _, ...} => SOME s'
   217     SOME {casex = Const (s', _), split_sels = _ :: _, ...} => SOME s'
   218   | _ => NONE);
   218   | _ => NONE);
   219 
   219 
   220 fun massage_let_if_case ctxt has_call massage_leaf =
   220 fun massage_let_if_case ctxt has_call massage_leaf bound_Ts t0 =
   221   let
   221   let
   222     val thy = Proof_Context.theory_of ctxt;
   222     val thy = Proof_Context.theory_of ctxt;
   223 
   223 
   224     fun check_no_call t = if has_call t then unexpected_corec_call ctxt [] t else ();
   224     fun check_no_call t = if has_call t then unexpected_corec_call ctxt [t0] t else ();
   225 
   225 
   226     fun massage_abs bound_Ts 0 t = massage_rec bound_Ts t
   226     fun massage_abs bound_Ts 0 t = massage_rec bound_Ts t
   227       | massage_abs bound_Ts m (Abs (s, T, t)) = Abs (s, T, massage_abs (T :: bound_Ts) (m - 1) t)
   227       | massage_abs bound_Ts m (Abs (s, T, t)) = Abs (s, T, massage_abs (T :: bound_Ts) (m - 1) t)
   228       | massage_abs bound_Ts m t =
   228       | massage_abs bound_Ts m t =
   229         let val T = domain_type (fastype_of1 (bound_Ts, t)) in
   229         let val T = domain_type (fastype_of1 (bound_Ts, t)) in
   269             end
   269             end
   270           | NONE => massage_leaf bound_Ts t)
   270           | NONE => massage_leaf bound_Ts t)
   271         | _ => massage_leaf bound_Ts t)
   271         | _ => massage_leaf bound_Ts t)
   272       end;
   272       end;
   273   in
   273   in
   274     massage_rec
   274     massage_rec bound_Ts t0
   275   end;
   275   end;
   276 
   276 
   277 fun curried_type (Type (@{type_name fun}, [Type (@{type_name prod}, Ts), T])) = Ts ---> T;
   277 fun curried_type (Type (@{type_name fun}, [Type (@{type_name prod}, Ts), T])) = Ts ---> T;
   278 
   278 
   279 fun massage_nested_corec_call ctxt has_call raw_massage_call bound_Ts U t =
   279 fun massage_nested_corec_call ctxt has_call raw_massage_call bound_Ts U t0 =
   280   let
   280   let
   281     fun check_no_call t = if has_call t then unexpected_corec_call ctxt [] t else ();
   281     fun check_no_call t = if has_call t then unexpected_corec_call ctxt [t0] t else ();
   282 
   282 
   283     val build_map_Inl = build_map ctxt [] (uncurry Inl_const o dest_sumT o snd);
   283     val build_map_Inl = build_map ctxt [] (uncurry Inl_const o dest_sumT o snd);
   284 
   284 
   285     fun massage_mutual_call bound_Ts U T t =
   285     fun massage_mutual_call bound_Ts U T t =
   286       if has_call t then
   286       if has_call t then
   355               | _ => massage_mutual_call bound_Ts U T t))
   355               | _ => massage_mutual_call bound_Ts U T t))
   356           | _ => ill_formed_corec_call ctxt t)
   356           | _ => ill_formed_corec_call ctxt t)
   357         else
   357         else
   358           build_map_Inl (T, U) $ t) bound_Ts;
   358           build_map_Inl (T, U) $ t) bound_Ts;
   359 
   359 
   360     val T = fastype_of1 (bound_Ts, t);
   360     val T = fastype_of1 (bound_Ts, t0);
   361   in
   361   in
   362     if has_call t then massage_call bound_Ts U T t else build_map_Inl (T, U) $ t
   362     if has_call t0 then massage_call bound_Ts U T t0 else build_map_Inl (T, U) $ t0
   363   end;
   363   end;
   364 
   364 
   365 fun expand_to_ctr_term ctxt s Ts t =
   365 fun expand_to_ctr_term ctxt s Ts t =
   366   (case ctr_sugar_of ctxt s of
   366   (case ctr_sugar_of ctxt s of
   367     SOME {ctrs, casex, ...} =>
   367     SOME {ctrs, casex, ...} =>
  1071         SOME (K (HEADGOAL (mk_primcorec_assumption_tac lthy [])))
  1071         SOME (K (HEADGOAL (mk_primcorec_assumption_tac lthy [])))
  1072       else
  1072       else
  1073         tac_opt;
  1073         tac_opt;
  1074 
  1074 
  1075     val excludess'' = @{map 3} (fn tac_opt => fn sequential => map (fn (j, goal) =>
  1075     val excludess'' = @{map 3} (fn tac_opt => fn sequential => map (fn (j, goal) =>
  1076         (j, (Option.map (Goal.prove_sorry lthy [] [] goal #> Thm.close_derivation)
  1076         (j, (Option.map (Goal.prove (*no sorry*) lthy [] [] goal #> Thm.close_derivation)
  1077            (exclude_tac tac_opt sequential j), goal))))
  1077            (exclude_tac tac_opt sequential j), goal))))
  1078       tac_opts sequentials excludess';
  1078       tac_opts sequentials excludess';
  1079 
  1079 
  1080     val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) excludess'';
  1080     val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) excludess'';
  1081     val (goal_idxss, exclude_goalss) = excludess''
  1081     val (goal_idxss, exclude_goalss) = excludess''
  1104             | [goal] => fn true =>
  1104             | [goal] => fn true =>
  1105               let
  1105               let
  1106                 val (_, _, arg_exhaust_discs, _, _) =
  1106                 val (_, _, arg_exhaust_discs, _, _) =
  1107                   case_thms_of_term lthy (the_default Term.dummy code_rhs_opt);
  1107                   case_thms_of_term lthy (the_default Term.dummy code_rhs_opt);
  1108               in
  1108               in
  1109                 [Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, ...} =>
  1109                 [Goal.prove (*no sorry*) lthy [] [] goal (fn {context = ctxt, ...} =>
  1110                    mk_primcorec_nchotomy_tac ctxt (res_exhaust_discs @ arg_exhaust_discs))
  1110                    mk_primcorec_nchotomy_tac ctxt (res_exhaust_discs @ arg_exhaust_discs))
  1111                  |> Thm.close_derivation]
  1111                  |> Thm.close_derivation]
  1112               end
  1112               end
  1113             | false =>
  1113             | false =>
  1114               (case tac_opt of
  1114               (case tac_opt of