src/HOL/BNF/Tools/bnf_fp_def_sugar.ML
changeset 51853 cce8b6ba429d
parent 51852 23d938495367
child 51854 af63d7f52c02
equal deleted inserted replaced
51852:23d938495367 51853:cce8b6ba429d
    18      xxfold_thmss: thm list list,
    18      xxfold_thmss: thm list list,
    19      xxrec_thmss: thm list list};
    19      xxrec_thmss: thm list list};
    20 
    20 
    21   val fp_sugar_of: local_theory -> string -> fp_sugar option
    21   val fp_sugar_of: local_theory -> string -> fp_sugar option
    22 
    22 
    23   val build_maps: local_theory -> typ list -> (int -> typ * typ -> term) -> typ * typ -> term
    23   val build_map: local_theory -> typ list -> (int -> typ * typ -> term) -> typ * typ -> term
    24 
    24 
    25   val mk_fp_iter_fun_types: term -> typ list
    25   val mk_fp_iter_fun_types: term -> typ list
    26   val mk_fun_arg_typess: int -> int list -> typ -> typ list list
    26   val mk_fun_arg_typess: int -> int list -> typ -> typ list list
    27   val unzip_recT: typ list -> typ -> typ list * typ list
    27   val unzip_recT: typ list -> typ -> typ list * typ list
    28   val mk_fold_fun_typess: typ list list list -> typ list list -> typ list list
    28   val mk_fold_fun_typess: typ list list list -> typ list list -> typ list list
   368     val live = live_of_bnf bnf;
   368     val live = live_of_bnf bnf;
   369     val mapx = mk_map live Ts Us (map_of_bnf bnf);
   369     val mapx = mk_map live Ts Us (map_of_bnf bnf);
   370     val TUs' = map dest_funT (fst (strip_typeN live (fastype_of mapx)));
   370     val TUs' = map dest_funT (fst (strip_typeN live (fastype_of mapx)));
   371   in Term.list_comb (mapx, map build_arg TUs') end;
   371   in Term.list_comb (mapx, map build_arg TUs') end;
   372 
   372 
   373 fun build_maps lthy Ts build_simple =
   373 fun build_map lthy Ts build_simple =
   374   let
   374   let
   375     fun build (TU as (T, U)) =
   375     fun build (TU as (T, U)) =
   376       if T = U then
   376       if T = U then
   377         id_const T
   377         id_const T
   378       else
   378       else
   379         (case find_index (curry (op =) T) Ts of
   379         (case find_index (curry (op =) T) Ts of
   380           ~1 => build_map_step lthy build TU
   380           ~1 => build_map_step lthy build TU
   381         | kk => build_simple kk TU);
   381         | kk => build_simple kk TU);
       
   382   in build end;
       
   383 
       
   384 fun build_map' lthy build_simple =
       
   385   let
       
   386     fun build (TU as (T, U)) =
       
   387       if T = U then
       
   388         id_const T
       
   389       else
       
   390         (case TU of
       
   391           (Type (s, _), Type (s', _)) =>
       
   392           if s = s' then build_map_step lthy build TU else build_simple TU
       
   393         | _ => build_simple TU);
   382   in build end;
   394   in build end;
   383 
   395 
   384 fun build_rel_step lthy build_arg (Type (s, Ts)) =
   396 fun build_rel_step lthy build_arg (Type (s, Ts)) =
   385   let
   397   let
   386     val bnf = the (bnf_of lthy s);
   398     val bnf = the (bnf_of lthy s);
   516 
   528 
   517         val mk_U = typ_subst_nonatomic (map2 pair fpTs Cs);
   529         val mk_U = typ_subst_nonatomic (map2 pair fpTs Cs);
   518 
   530 
   519         fun unzip_iters fiters combine (x as Free (_, T)) =
   531         fun unzip_iters fiters combine (x as Free (_, T)) =
   520           if exists_subtype_in fpTs T then
   532           if exists_subtype_in fpTs T then
   521             combine (x, build_maps lthy fpTs (K o nth fiters) (T, mk_U T) $ x)
   533             combine (x, build_map lthy fpTs (K o nth fiters) (T, mk_U T) $ x)
   522           else
   534           else
   523             ([x], []);
   535             ([x], []);
   524 
   536 
   525         val gxsss = map (map (flat_rec (unzip_iters gfolds (fn (_, t) => ([t], []))))) xsss;
   537         val gxsss = map (map (flat_rec (unzip_iters gfolds (fn (_, t) => ([t], []))))) xsss;
   526         val hxsss = map (map (flat_rec (unzip_iters hrecs (pairself single)))) xsss;
   538         val hxsss = map (map (flat_rec (unzip_iters hrecs (pairself single)))) xsss;
   684 
   696 
   685         val mk_U = typ_subst_nonatomic (map2 pair Cs fpTs);
   697         val mk_U = typ_subst_nonatomic (map2 pair Cs fpTs);
   686 
   698 
   687         fun intr_coiters fcoiters [] [cf] =
   699         fun intr_coiters fcoiters [] [cf] =
   688             let val T = fastype_of cf in
   700             let val T = fastype_of cf in
   689               if exists_subtype_in Cs T then build_maps lthy Cs (K o nth fcoiters) (T, mk_U T) $ cf
   701               if exists_subtype_in Cs T then build_map lthy Cs (K o nth fcoiters) (T, mk_U T) $ cf
   690               else cf
   702               else cf
   691             end
   703             end
   692           | intr_coiters fcoiters [cq] [cf, cf'] =
   704           | intr_coiters fcoiters [cq] [cf, cf'] =
   693             mk_If cq (intr_coiters fcoiters [] [cf]) (intr_coiters fcoiters [] [cf']);
   705             mk_If cq (intr_coiters fcoiters [] [cf]) (intr_coiters fcoiters [] [cf']);
   694 
   706 
  1171 
  1183 
  1172         fun define_fold_rec no_defs_lthy =
  1184         fun define_fold_rec no_defs_lthy =
  1173           let
  1185           let
  1174             val fpT_to_C = fpT --> C;
  1186             val fpT_to_C = fpT --> C;
  1175 
  1187 
  1176             fun build_prod_proj mk_proj (TU as (T, U)) =
  1188             fun build_prod_proj mk_proj = build_map' lthy (mk_proj o fst);
  1177               if T = U then
       
  1178                 id_const T
       
  1179               else
       
  1180                 (case TU of
       
  1181                   (Type (s, _), Type (s', _)) =>
       
  1182                   if s = s' then build_map_step lthy (build_prod_proj mk_proj) TU else mk_proj T
       
  1183                 | _ => mk_proj T);
       
  1184 
  1189 
  1185             (* TODO: Avoid these complications; cf. corec case *)
  1190             (* TODO: Avoid these complications; cf. corec case *)
  1186             fun mk_U proj (Type (s as @{type_name prod}, Ts as [T', U])) =
  1191             fun mk_U proj (Type (s as @{type_name prod}, Ts as [T', U])) =
  1187                 if member (op =) fpTs T' then proj (T', U) else Type (s, map (mk_U proj) Ts)
  1192                 if member (op =) fpTs T' then proj (T', U) else Type (s, map (mk_U proj) Ts)
  1188               | mk_U proj (Type (s, Ts)) = Type (s, map (mk_U proj) Ts)
  1193               | mk_U proj (Type (s, Ts)) = Type (s, map (mk_U proj) Ts)
  1231 
  1236 
  1232         fun define_unfold_corec no_defs_lthy =
  1237         fun define_unfold_corec no_defs_lthy =
  1233           let
  1238           let
  1234             val B_to_fpT = C --> fpT;
  1239             val B_to_fpT = C --> fpT;
  1235 
  1240 
  1236             fun build_sum_inj mk_inj (TU as (T, U)) =
  1241             fun build_sum_inj mk_inj = build_map' lthy (uncurry mk_inj o dest_sumT o snd);
  1237               if T = U then
       
  1238                 id_const T
       
  1239               else
       
  1240                 (case TU of
       
  1241                   (Type (s, _), Type (s', _)) =>
       
  1242                   if s = s' then build_map_step lthy (build_sum_inj mk_inj) TU
       
  1243                   else uncurry mk_inj (dest_sumT U)
       
  1244                 | _ => uncurry mk_inj (dest_sumT U));
       
  1245 
  1242 
  1246             fun build_dtor_coiter_arg _ [] [cf] = cf
  1243             fun build_dtor_coiter_arg _ [] [cf] = cf
  1247               | build_dtor_coiter_arg T [cq] [cf, cf'] =
  1244               | build_dtor_coiter_arg T [cq] [cf, cf'] =
  1248                 mk_If cq (build_sum_inj Inl_const (fastype_of cf, T) $ cf)
  1245                 mk_If cq (build_sum_inj Inl_const (fastype_of cf, T) $ cf)
  1249                   (build_sum_inj Inr_const (fastype_of cf', T) $ cf')
  1246                   (build_sum_inj Inr_const (fastype_of cf', T) $ cf')