src/HOL/BNF/Tools/bnf_fp_def_sugar.ML
changeset 52209 8b2c3e548a20
parent 52208 ff8725b21a43
child 52213 f4c5c6320cce
--- a/src/HOL/BNF/Tools/bnf_fp_def_sugar.ML	Tue May 28 22:20:25 2013 +0200
+++ b/src/HOL/BNF/Tools/bnf_fp_def_sugar.ML	Tue May 28 23:01:28 2013 +0200
@@ -248,18 +248,18 @@
 fun meta_unzip_rec getT proj1 proj2 fpTs y =
   if exists_subtype_in fpTs (getT y) then ([proj1 y], [proj2 y]) else ([y], []);
 
-fun unzip_recT fpTs T =
+fun project_co_recT special_Tname fpTs proj =
   let
-    fun project_recT proj =
-      let
-        fun project (Type (s as @{type_name prod}, Ts as [T, U])) =
-            if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts)
-          | project (Type (s, Ts)) = Type (s, map project Ts)
-          | project T = T;
-      in project end;
-  in
-    meta_unzip_rec I (project_recT fst) (project_recT snd) fpTs T
-  end;
+    fun project (Type (s, Ts as T :: Ts')) =
+        if s = special_Tname andalso member (op =) fpTs T then proj (hd Ts, hd Ts')
+        else Type (s, map project Ts)
+      | project T = T;
+  in project end;
+
+val project_recT = project_co_recT @{type_name prod};
+val project_corecT = project_co_recT @{type_name sum};
+
+fun unzip_recT fpTs = meta_unzip_rec I (project_recT fpTs fst) (project_recT fpTs snd) fpTs;
 
 fun mk_fold_fun_typess y_Tsss Cs = map2 (fn C => map (fn y_Ts => y_Ts ---> C)) Cs y_Tsss;
 val mk_rec_fun_typess = mk_fold_fun_typess oo map o map o flat_rec o unzip_recT;
@@ -296,16 +296,9 @@
     fun repair_arity [0] = [1]
       | repair_arity ms = ms;
 
-    fun project_corecT proj =
-      let
-        fun project (Type (s as @{type_name sum}, Ts as [T, U])) =
-            if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts)
-          | project (Type (s, Ts)) = Type (s, map project Ts)
-          | project T = T;
-      in project end;
-
     fun unzip_corecT T =
-      if exists_subtype_in fpTs T then [project_corecT fst T, project_corecT snd T] else [T];
+      if exists_subtype_in fpTs T then [project_corecT fpTs fst T, project_corecT fpTs snd T]
+      else [T];
 
     val p_Tss = map2 (fn n => replicate (Int.max (0, n - 1)) o mk_pred1T) ns Cs;
 
@@ -447,18 +440,12 @@
 
 fun mk_iter_body lthy fpTs ctor_iter fss xsss =
   let
-    fun build_prod_proj mk_proj = build_map lthy (mk_proj o fst);
+    fun build_proj sel sel_const (x as Free (_, T)) =
+      build_map lthy (sel_const o fst) (T, project_recT fpTs sel T) $ x;
 
     (* TODO: Avoid these complications; cf. corec case *)
-    fun mk_U proj (Type (s as @{type_name prod}, Ts as [T', U])) =
-        if member (op =) fpTs T' then proj (T', U) else Type (s, map (mk_U proj) Ts)
-      | mk_U proj (Type (s, Ts)) = Type (s, map (mk_U proj) Ts)
-      | mk_U _ T = T;
-
-    val unzip_rec =
-      meta_unzip_rec (snd o dest_Free)
-        (fn x as Free (_, T) => build_prod_proj fst_const (T, mk_U fst T) $ x)
-        (fn x as Free (_, T) => build_prod_proj snd_const (T, mk_U snd T) $ x) fpTs;
+    val unzip_rec = meta_unzip_rec (snd o dest_Free) (build_proj fst fst_const)
+      (build_proj snd snd_const) fpTs;
 
     fun mk_iter_arg f xs = mk_tupled_fun (HOLogic.mk_tuple xs) f (flat_rec unzip_rec xs);
   in