src/HOL/BNF/Tools/bnf_gfp_rec_sugar.ML
changeset 55729 8dd0e0316881
parent 55724 9d623cada37f
child 55731 3ffb74b52ed6
equal deleted inserted replaced
55728:d26b6b935a6f 55729:8dd0e0316881
   266         handle AINT_NO_MAP _ => massage_mutual_fun bound_Ts U T t;
   266         handle AINT_NO_MAP _ => massage_mutual_fun bound_Ts U T t;
   267 
   267 
   268     fun massage_call bound_Ts U T =
   268     fun massage_call bound_Ts U T =
   269       massage_let_if_case ctxt has_call (fn bound_Ts => fn t =>
   269       massage_let_if_case ctxt has_call (fn bound_Ts => fn t =>
   270         if has_call t then
   270         if has_call t then
   271           (case U of
   271           (case t of
   272             Type (s, Us) =>
   272             Const (@{const_name prod_case}, _) $ t' =>
   273             (case try (dest_ctr ctxt s) t of
   273             let
   274               SOME (f, args) =>
   274               val U' = curried_type U;
   275               let
   275               val T' = curried_type T;
   276                 val typof = curry fastype_of1 bound_Ts;
   276             in
   277                 val f' = mk_ctr Us f
   277               Const (@{const_name prod_case}, U' --> U) $ massage_call bound_Ts U' T' t'
   278                 val f'_T = typof f';
   278             end
   279                 val arg_Ts = map typof args;
   279           | t1 $ t2 =>
   280               in
   280             (if has_call t2 then
   281                 Term.list_comb (f', map3 (massage_call bound_Ts) (binder_types f'_T) arg_Ts args)
   281               massage_mutual_call bound_Ts U T t
   282               end
   282             else
   283             | NONE =>
   283               massage_map bound_Ts U T t1 $ t2
   284               (case t of
   284               handle AINT_NO_MAP _ => massage_mutual_call bound_Ts U T t)
   285                 Const (@{const_name prod_case}, _) $ t' =>
   285           | Abs (s, T', t') =>
   286                 let
   286             Abs (s, T', massage_call (T' :: bound_Ts) (range_type U) (range_type T) t')
   287                   val U' = curried_type U;
   287           | _ => massage_mutual_call bound_Ts U T t)
   288                   val T' = curried_type T;
       
   289                 in
       
   290                   Const (@{const_name prod_case}, U' --> U) $ massage_call bound_Ts U' T' t'
       
   291                 end
       
   292               | t1 $ t2 =>
       
   293                 (if has_call t2 then
       
   294                   massage_mutual_call bound_Ts U T t
       
   295                 else
       
   296                   massage_map bound_Ts U T t1 $ t2
       
   297                   handle AINT_NO_MAP _ => massage_mutual_call bound_Ts U T t)
       
   298               | Abs (s, T', t') =>
       
   299                 Abs (s, T', massage_call (T' :: bound_Ts) (range_type U) (range_type T) t')
       
   300               | _ => massage_mutual_call bound_Ts U T t))
       
   301           | _ => ill_formed_corec_call ctxt t)
       
   302         else
   288         else
   303           build_map_Inl (T, U) $ t) bound_Ts;
   289           build_map_Inl (T, U) $ t) bound_Ts;
   304 
   290 
   305     val T = fastype_of1 (bound_Ts, t);
   291     val T = fastype_of1 (bound_Ts, t);
   306   in
   292   in