src/HOL/Tools/BNF/bnf_util.ML
changeset 69593 3dda49e08b9d
parent 64413 c0d5e78eb647
child 72154 2b41b710f6ef
equal deleted inserted replaced
69592:a80d8ec6c998 69593:3dda49e08b9d
   121 struct
   121 struct
   122 
   122 
   123 open Ctr_Sugar_Util
   123 open Ctr_Sugar_Util
   124 open BNF_FP_Rec_Sugar_Util
   124 open BNF_FP_Rec_Sugar_Util
   125 
   125 
   126 val transfer_plugin = Plugin_Name.declare_setup @{binding transfer};
   126 val transfer_plugin = Plugin_Name.declare_setup \<^binding>\<open>transfer\<close>;
   127 
   127 
   128 
   128 
   129 (* Library proper *)
   129 (* Library proper *)
   130 
   130 
   131 fun unfla0 xs = fold_map (fn _ => fn (c :: cs) => (c, cs)) xs;
   131 fun unfla0 xs = fold_map (fn _ => fn (c :: cs) => (c, cs)) xs;
   135 
   135 
   136 fun unflatt xsss = fst o unflatt0 xsss;
   136 fun unflatt xsss = fst o unflatt0 xsss;
   137 fun unflattt xssss = fst o unflattt0 xssss;
   137 fun unflattt xssss = fst o unflattt0 xssss;
   138 
   138 
   139 val parse_type_arg_constrained =
   139 val parse_type_arg_constrained =
   140   Parse.type_ident -- Scan.option (@{keyword "::"} |-- Parse.!!! Parse.sort);
   140   Parse.type_ident -- Scan.option (\<^keyword>\<open>::\<close> |-- Parse.!!! Parse.sort);
   141 
   141 
   142 val parse_type_arg_named_constrained =
   142 val parse_type_arg_named_constrained =
   143    (Parse.reserved "dead" >> K NONE || parse_opt_binding_colon >> SOME) --
   143    (Parse.reserved "dead" >> K NONE || parse_opt_binding_colon >> SOME) --
   144    parse_type_arg_constrained;
   144    parse_type_arg_constrained;
   145 
   145 
   146 val parse_type_args_named_constrained =
   146 val parse_type_args_named_constrained =
   147   parse_type_arg_constrained >> (single o pair (SOME Binding.empty)) ||
   147   parse_type_arg_constrained >> (single o pair (SOME Binding.empty)) ||
   148   @{keyword "("} |-- Parse.!!! (Parse.list1 parse_type_arg_named_constrained --| @{keyword ")"}) ||
   148   \<^keyword>\<open>(\<close> |-- Parse.!!! (Parse.list1 parse_type_arg_named_constrained --| \<^keyword>\<open>)\<close>) ||
   149   Scan.succeed [];
   149   Scan.succeed [];
   150 
   150 
   151 val parse_map_rel_pred_binding = Parse.name --| @{keyword ":"} -- Parse.binding;
   151 val parse_map_rel_pred_binding = Parse.name --| \<^keyword>\<open>:\<close> -- Parse.binding;
   152 
   152 
   153 val no_map_rel = (Binding.empty, Binding.empty, Binding.empty);
   153 val no_map_rel = (Binding.empty, Binding.empty, Binding.empty);
   154 
   154 
   155 fun extract_map_rel_pred ("map", m) = (fn (_, r, p) => (m, r, p))
   155 fun extract_map_rel_pred ("map", m) = (fn (_, r, p) => (m, r, p))
   156   | extract_map_rel_pred ("rel", r) = (fn (m, _, p) => (m, r, p))
   156   | extract_map_rel_pred ("rel", r) = (fn (m, _, p) => (m, r, p))
   157   | extract_map_rel_pred ("pred", p) = (fn (m, r, _) => (m, r, p))
   157   | extract_map_rel_pred ("pred", p) = (fn (m, r, _) => (m, r, p))
   158   | extract_map_rel_pred (s, _) = error ("Unknown label " ^ quote s ^ " (expected \"map\" or \"rel\")");
   158   | extract_map_rel_pred (s, _) = error ("Unknown label " ^ quote s ^ " (expected \"map\" or \"rel\")");
   159 
   159 
   160 val parse_map_rel_pred_bindings =
   160 val parse_map_rel_pred_bindings =
   161   @{keyword "for"} |-- Scan.repeat parse_map_rel_pred_binding
   161   \<^keyword>\<open>for\<close> |-- Scan.repeat parse_map_rel_pred_binding
   162     >> (fn ps => fold extract_map_rel_pred ps no_map_rel)
   162     >> (fn ps => fold extract_map_rel_pred ps no_map_rel)
   163   || Scan.succeed no_map_rel;
   163   || Scan.succeed no_map_rel;
   164 
   164 
   165 fun typedef (b, Ts, mx) set opt_morphs tac lthy =
   165 fun typedef (b, Ts, mx) set opt_morphs tac lthy =
   166   let
   166   let
   202 
   202 
   203 (** Types **)
   203 (** Types **)
   204 
   204 
   205 (*maps [T1,...,Tn]--->T to ([T1,T2,...,Tn], T)*)
   205 (*maps [T1,...,Tn]--->T to ([T1,T2,...,Tn], T)*)
   206 fun strip_typeN 0 T = ([], T)
   206 fun strip_typeN 0 T = ([], T)
   207   | strip_typeN n (Type (@{type_name fun}, [T, T'])) = strip_typeN (n - 1) T' |>> cons T
   207   | strip_typeN n (Type (\<^type_name>\<open>fun\<close>, [T, T'])) = strip_typeN (n - 1) T' |>> cons T
   208   | strip_typeN _ T = raise TYPE ("strip_typeN", [T], []);
   208   | strip_typeN _ T = raise TYPE ("strip_typeN", [T], []);
   209 
   209 
   210 (*maps [T1,...,Tn]--->T-->U to ([T1,T2,...,Tn], T-->U), where U is not a function type*)
   210 (*maps [T1,...,Tn]--->T-->U to ([T1,T2,...,Tn], T-->U), where U is not a function type*)
   211 fun strip_fun_type T = strip_typeN (num_binder_types T - 1) T;
   211 fun strip_fun_type T = strip_typeN (num_binder_types T - 1) T;
   212 
   212 
   215 
   215 
   216 fun mk_pred2T T U = mk_predT [T, U];
   216 fun mk_pred2T T U = mk_predT [T, U];
   217 val mk_relT = HOLogic.mk_setT o HOLogic.mk_prodT;
   217 val mk_relT = HOLogic.mk_setT o HOLogic.mk_prodT;
   218 val dest_relT = HOLogic.dest_prodT o HOLogic.dest_setT;
   218 val dest_relT = HOLogic.dest_prodT o HOLogic.dest_setT;
   219 val dest_pred2T = apsnd Term.domain_type o Term.dest_funT;
   219 val dest_pred2T = apsnd Term.domain_type o Term.dest_funT;
   220 fun mk_sumT (LT, RT) = Type (@{type_name Sum_Type.sum}, [LT, RT]);
   220 fun mk_sumT (LT, RT) = Type (\<^type_name>\<open>Sum_Type.sum\<close>, [LT, RT]);
   221 
   221 
   222 
   222 
   223 (** Constants **)
   223 (** Constants **)
   224 
   224 
   225 fun fst_const T = Const (@{const_name fst}, T --> fst (HOLogic.dest_prodT T));
   225 fun fst_const T = Const (\<^const_name>\<open>fst\<close>, T --> fst (HOLogic.dest_prodT T));
   226 fun snd_const T = Const (@{const_name snd}, T --> snd (HOLogic.dest_prodT T));
   226 fun snd_const T = Const (\<^const_name>\<open>snd\<close>, T --> snd (HOLogic.dest_prodT T));
   227 fun Id_const T = Const (@{const_name Id}, mk_relT (T, T));
   227 fun Id_const T = Const (\<^const_name>\<open>Id\<close>, mk_relT (T, T));
   228 
   228 
   229 
   229 
   230 (** Operators **)
   230 (** Operators **)
   231 
   231 
   232 fun enforce_type ctxt get_T T t =
   232 fun enforce_type ctxt get_T T t =
   234 
   234 
   235 fun mk_converse R =
   235 fun mk_converse R =
   236   let
   236   let
   237     val RT = dest_relT (fastype_of R);
   237     val RT = dest_relT (fastype_of R);
   238     val RST = mk_relT (snd RT, fst RT);
   238     val RST = mk_relT (snd RT, fst RT);
   239   in Const (@{const_name converse}, fastype_of R --> RST) $ R end;
   239   in Const (\<^const_name>\<open>converse\<close>, fastype_of R --> RST) $ R end;
   240 
   240 
   241 fun mk_rel_comp (R, S) =
   241 fun mk_rel_comp (R, S) =
   242   let
   242   let
   243     val RT = fastype_of R;
   243     val RT = fastype_of R;
   244     val ST = fastype_of S;
   244     val ST = fastype_of S;
   245     val RST = mk_relT (fst (dest_relT RT), snd (dest_relT ST));
   245     val RST = mk_relT (fst (dest_relT RT), snd (dest_relT ST));
   246   in Const (@{const_name relcomp}, RT --> ST --> RST) $ R $ S end;
   246   in Const (\<^const_name>\<open>relcomp\<close>, RT --> ST --> RST) $ R $ S end;
   247 
   247 
   248 fun mk_Gr A f =
   248 fun mk_Gr A f =
   249   let val ((AT, BT), FT) = `dest_funT (fastype_of f);
   249   let val ((AT, BT), FT) = `dest_funT (fastype_of f);
   250   in Const (@{const_name Gr}, HOLogic.mk_setT AT --> FT --> mk_relT (AT, BT)) $ A $ f end;
   250   in Const (\<^const_name>\<open>Gr\<close>, HOLogic.mk_setT AT --> FT --> mk_relT (AT, BT)) $ A $ f end;
   251 
   251 
   252 fun mk_conversep R =
   252 fun mk_conversep R =
   253   let
   253   let
   254     val RT = dest_pred2T (fastype_of R);
   254     val RT = dest_pred2T (fastype_of R);
   255     val RST = mk_pred2T (snd RT) (fst RT);
   255     val RST = mk_pred2T (snd RT) (fst RT);
   256   in Const (@{const_name conversep}, fastype_of R --> RST) $ R end;
   256   in Const (\<^const_name>\<open>conversep\<close>, fastype_of R --> RST) $ R end;
   257 
   257 
   258 fun mk_rel_compp (R, S) =
   258 fun mk_rel_compp (R, S) =
   259   let
   259   let
   260     val RT = fastype_of R;
   260     val RT = fastype_of R;
   261     val ST = fastype_of S;
   261     val ST = fastype_of S;
   262     val RST = mk_pred2T (fst (dest_pred2T RT)) (snd (dest_pred2T ST));
   262     val RST = mk_pred2T (fst (dest_pred2T RT)) (snd (dest_pred2T ST));
   263   in Const (@{const_name relcompp}, RT --> ST --> RST) $ R $ S end;
   263   in Const (\<^const_name>\<open>relcompp\<close>, RT --> ST --> RST) $ R $ S end;
   264 
   264 
   265 fun mk_Grp A f =
   265 fun mk_Grp A f =
   266   let val ((AT, BT), FT) = `dest_funT (fastype_of f);
   266   let val ((AT, BT), FT) = `dest_funT (fastype_of f);
   267   in Const (@{const_name Grp}, HOLogic.mk_setT AT --> FT --> mk_pred2T AT BT) $ A $ f end;
   267   in Const (\<^const_name>\<open>Grp\<close>, HOLogic.mk_setT AT --> FT --> mk_pred2T AT BT) $ A $ f end;
   268 
   268 
   269 fun mk_image f =
   269 fun mk_image f =
   270   let val (T, U) = dest_funT (fastype_of f);
   270   let val (T, U) = dest_funT (fastype_of f);
   271   in Const (@{const_name image}, (T --> U) --> HOLogic.mk_setT T --> HOLogic.mk_setT U) $ f end;
   271   in Const (\<^const_name>\<open>image\<close>, (T --> U) --> HOLogic.mk_setT T --> HOLogic.mk_setT U) $ f end;
   272 
   272 
   273 fun mk_Ball X f =
   273 fun mk_Ball X f =
   274   Const (@{const_name Ball}, fastype_of X --> fastype_of f --> HOLogic.boolT) $ X $ f;
   274   Const (\<^const_name>\<open>Ball\<close>, fastype_of X --> fastype_of f --> HOLogic.boolT) $ X $ f;
   275 
   275 
   276 fun mk_Bex X f =
   276 fun mk_Bex X f =
   277   Const (@{const_name Bex}, fastype_of X --> fastype_of f --> HOLogic.boolT) $ X $ f;
   277   Const (\<^const_name>\<open>Bex\<close>, fastype_of X --> fastype_of f --> HOLogic.boolT) $ X $ f;
   278 
   278 
   279 fun mk_UNION X f =
   279 fun mk_UNION X f =
   280   let
   280   let
   281     val (T, U) = dest_funT (fastype_of f);
   281     val (T, U) = dest_funT (fastype_of f);
   282   in
   282   in
   283     Const (@{const_name Sup}, HOLogic.mk_setT U --> U)
   283     Const (\<^const_name>\<open>Sup\<close>, HOLogic.mk_setT U --> U)
   284       $ (Const (@{const_name image}, (T --> U) --> fastype_of X --> HOLogic.mk_setT U) $ f $ X)
   284       $ (Const (\<^const_name>\<open>image\<close>, (T --> U) --> fastype_of X --> HOLogic.mk_setT U) $ f $ X)
   285   end;
   285   end;
   286 
   286 
   287 fun mk_Union T =
   287 fun mk_Union T =
   288   Const (@{const_name Sup}, HOLogic.mk_setT (HOLogic.mk_setT T) --> HOLogic.mk_setT T);
   288   Const (\<^const_name>\<open>Sup\<close>, HOLogic.mk_setT (HOLogic.mk_setT T) --> HOLogic.mk_setT T);
   289 
   289 
   290 val mk_union = HOLogic.mk_binop @{const_name sup};
   290 val mk_union = HOLogic.mk_binop \<^const_name>\<open>sup\<close>;
   291 
   291 
   292 fun mk_Field r =
   292 fun mk_Field r =
   293   let val T = fst (dest_relT (fastype_of r));
   293   let val T = fst (dest_relT (fastype_of r));
   294   in Const (@{const_name Field}, mk_relT (T, T) --> HOLogic.mk_setT T) $ r end;
   294   in Const (\<^const_name>\<open>Field\<close>, mk_relT (T, T) --> HOLogic.mk_setT T) $ r end;
   295 
   295 
   296 fun mk_card_order bd =
   296 fun mk_card_order bd =
   297   let
   297   let
   298     val T = fastype_of bd;
   298     val T = fastype_of bd;
   299     val AT = fst (dest_relT T);
   299     val AT = fst (dest_relT T);
   300   in
   300   in
   301     Const (@{const_name card_order_on}, HOLogic.mk_setT AT --> T --> HOLogic.boolT) $
   301     Const (\<^const_name>\<open>card_order_on\<close>, HOLogic.mk_setT AT --> T --> HOLogic.boolT) $
   302       HOLogic.mk_UNIV AT $ bd
   302       HOLogic.mk_UNIV AT $ bd
   303   end;
   303   end;
   304 
   304 
   305 fun mk_Card_order bd =
   305 fun mk_Card_order bd =
   306   let
   306   let
   307     val T = fastype_of bd;
   307     val T = fastype_of bd;
   308     val AT = fst (dest_relT T);
   308     val AT = fst (dest_relT T);
   309   in
   309   in
   310     Const (@{const_name card_order_on}, HOLogic.mk_setT AT --> T --> HOLogic.boolT) $
   310     Const (\<^const_name>\<open>card_order_on\<close>, HOLogic.mk_setT AT --> T --> HOLogic.boolT) $
   311       mk_Field bd $ bd
   311       mk_Field bd $ bd
   312   end;
   312   end;
   313 
   313 
   314 fun mk_cinfinite bd = Const (@{const_name cinfinite}, fastype_of bd --> HOLogic.boolT) $ bd;
   314 fun mk_cinfinite bd = Const (\<^const_name>\<open>cinfinite\<close>, fastype_of bd --> HOLogic.boolT) $ bd;
   315 
   315 
   316 fun mk_ordLeq t1 t2 =
   316 fun mk_ordLeq t1 t2 =
   317   HOLogic.mk_mem (HOLogic.mk_prod (t1, t2),
   317   HOLogic.mk_mem (HOLogic.mk_prod (t1, t2),
   318     Const (@{const_name ordLeq}, mk_relT (fastype_of t1, fastype_of t2)));
   318     Const (\<^const_name>\<open>ordLeq\<close>, mk_relT (fastype_of t1, fastype_of t2)));
   319 
   319 
   320 fun mk_card_of A =
   320 fun mk_card_of A =
   321   let
   321   let
   322     val AT = fastype_of A;
   322     val AT = fastype_of A;
   323     val T = HOLogic.dest_setT AT;
   323     val T = HOLogic.dest_setT AT;
   324   in
   324   in
   325     Const (@{const_name card_of}, AT --> mk_relT (T, T)) $ A
   325     Const (\<^const_name>\<open>card_of\<close>, AT --> mk_relT (T, T)) $ A
   326   end;
   326   end;
   327 
   327 
   328 fun mk_dir_image r f =
   328 fun mk_dir_image r f =
   329   let val (T, U) = dest_funT (fastype_of f);
   329   let val (T, U) = dest_funT (fastype_of f);
   330   in Const (@{const_name dir_image}, mk_relT (T, T) --> (T --> U) --> mk_relT (U, U)) $ r $ f end;
   330   in Const (\<^const_name>\<open>dir_image\<close>, mk_relT (T, T) --> (T --> U) --> mk_relT (U, U)) $ r $ f end;
   331 
   331 
   332 fun mk_rel_fun R S =
   332 fun mk_rel_fun R S =
   333   let
   333   let
   334     val ((RA, RB), RT) = `dest_pred2T (fastype_of R);
   334     val ((RA, RB), RT) = `dest_pred2T (fastype_of R);
   335     val ((SA, SB), ST) = `dest_pred2T (fastype_of S);
   335     val ((SA, SB), ST) = `dest_pred2T (fastype_of S);
   336   in Const (@{const_name rel_fun}, RT --> ST --> mk_pred2T (RA --> SA) (RB --> SB)) $ R $ S end;
   336   in Const (\<^const_name>\<open>rel_fun\<close>, RT --> ST --> mk_pred2T (RA --> SA) (RB --> SB)) $ R $ S end;
   337 
   337 
   338 (*FIXME: "x"?*)
   338 (*FIXME: "x"?*)
   339 (*(nth sets i) must be of type "T --> 'ai set"*)
   339 (*(nth sets i) must be of type "T --> 'ai set"*)
   340 fun mk_in As sets T =
   340 fun mk_in As sets T =
   341   let
   341   let
   342     fun in_single set A =
   342     fun in_single set A =
   343       let val AT = fastype_of A;
   343       let val AT = fastype_of A;
   344       in Const (@{const_name less_eq}, AT --> AT --> HOLogic.boolT) $ (set $ Free ("x", T)) $ A end;
   344       in Const (\<^const_name>\<open>less_eq\<close>, AT --> AT --> HOLogic.boolT) $ (set $ Free ("x", T)) $ A end;
   345   in
   345   in
   346     if null sets then HOLogic.mk_UNIV T
   346     if null sets then HOLogic.mk_UNIV T
   347     else HOLogic.mk_Collect ("x", T, foldr1 (HOLogic.mk_conj) (map2 in_single sets As))
   347     else HOLogic.mk_Collect ("x", T, foldr1 (HOLogic.mk_conj) (map2 in_single sets As))
   348   end;
   348   end;
   349 
   349 
   350 fun mk_inj t =
   350 fun mk_inj t =
   351   let val T as Type (@{type_name fun}, [domT, _]) = fastype_of t in
   351   let val T as Type (\<^type_name>\<open>fun\<close>, [domT, _]) = fastype_of t in
   352     Const (@{const_name inj_on}, T --> HOLogic.mk_setT domT --> HOLogic.boolT) $ t
   352     Const (\<^const_name>\<open>inj_on\<close>, T --> HOLogic.mk_setT domT --> HOLogic.boolT) $ t
   353       $ HOLogic.mk_UNIV domT
   353       $ HOLogic.mk_UNIV domT
   354   end;
   354   end;
   355 
   355 
   356 fun mk_leq t1 t2 =
   356 fun mk_leq t1 t2 =
   357   Const (@{const_name less_eq}, fastype_of t1 --> fastype_of t2 --> HOLogic.boolT) $ t1 $ t2;
   357   Const (\<^const_name>\<open>less_eq\<close>, fastype_of t1 --> fastype_of t2 --> HOLogic.boolT) $ t1 $ t2;
   358 
   358 
   359 fun mk_card_binop binop typop t1 t2 =
   359 fun mk_card_binop binop typop t1 t2 =
   360   let
   360   let
   361     val (T1, relT1) = `(fst o dest_relT) (fastype_of t1);
   361     val (T1, relT1) = `(fst o dest_relT) (fastype_of t1);
   362     val (T2, relT2) = `(fst o dest_relT) (fastype_of t2);
   362     val (T2, relT2) = `(fst o dest_relT) (fastype_of t2);
   363   in Const (binop, relT1 --> relT2 --> mk_relT (typop (T1, T2), typop (T1, T2))) $ t1 $ t2 end;
   363   in Const (binop, relT1 --> relT2 --> mk_relT (typop (T1, T2), typop (T1, T2))) $ t1 $ t2 end;
   364 
   364 
   365 val mk_csum = mk_card_binop @{const_name csum} mk_sumT;
   365 val mk_csum = mk_card_binop \<^const_name>\<open>csum\<close> mk_sumT;
   366 val mk_cprod = mk_card_binop @{const_name cprod} HOLogic.mk_prodT;
   366 val mk_cprod = mk_card_binop \<^const_name>\<open>cprod\<close> HOLogic.mk_prodT;
   367 val mk_cexp = mk_card_binop @{const_name cexp} (op --> o swap);
   367 val mk_cexp = mk_card_binop \<^const_name>\<open>cexp\<close> (op --> o swap);
   368 val ctwo = @{term ctwo};
   368 val ctwo = \<^term>\<open>ctwo\<close>;
   369 
   369 
   370 fun mk_collect xs defT =
   370 fun mk_collect xs defT =
   371   let val T = (case xs of [] => defT | (x::_) => fastype_of x);
   371   let val T = (case xs of [] => defT | (x::_) => fastype_of x);
   372   in Const (@{const_name collect}, HOLogic.mk_setT T --> T) $ (HOLogic.mk_set T xs) end;
   372   in Const (\<^const_name>\<open>collect\<close>, HOLogic.mk_setT T --> T) $ (HOLogic.mk_set T xs) end;
   373 
   373 
   374 fun mk_vimage2p f g =
   374 fun mk_vimage2p f g =
   375   let
   375   let
   376     val (T1, T2) = dest_funT (fastype_of f);
   376     val (T1, T2) = dest_funT (fastype_of f);
   377     val (U1, U2) = dest_funT (fastype_of g);
   377     val (U1, U2) = dest_funT (fastype_of g);
   378   in
   378   in
   379     Const (@{const_name vimage2p},
   379     Const (\<^const_name>\<open>vimage2p\<close>,
   380       (T1 --> T2) --> (U1 --> U2) --> mk_pred2T T2 U2 --> mk_pred2T T1 U1) $ f $ g
   380       (T1 --> T2) --> (U1 --> U2) --> mk_pred2T T2 U2 --> mk_pred2T T1 U1) $ f $ g
   381   end;
   381   end;
   382 
   382 
   383 fun mk_eq_onp P =
   383 fun mk_eq_onp P =
   384   let
   384   let
   385     val T = domain_type (fastype_of P);
   385     val T = domain_type (fastype_of P);
   386   in
   386   in
   387     Const (@{const_name eq_onp}, (T --> HOLogic.boolT) --> T --> T --> HOLogic.boolT) $ P
   387     Const (\<^const_name>\<open>eq_onp\<close>, (T --> HOLogic.boolT) --> T --> T --> HOLogic.boolT) $ P
   388   end;
   388   end;
   389 
   389 
   390 fun mk_pred name R =
   390 fun mk_pred name R =
   391   Const (name, uncurry mk_pred2T (fastype_of R |> dest_pred2T) --> HOLogic.boolT) $ R;
   391   Const (name, uncurry mk_pred2T (fastype_of R |> dest_pred2T) --> HOLogic.boolT) $ R;
   392 val mk_reflp = mk_pred @{const_name reflp};
   392 val mk_reflp = mk_pred \<^const_name>\<open>reflp\<close>;
   393 val mk_symp = mk_pred @{const_name symp};
   393 val mk_symp = mk_pred \<^const_name>\<open>symp\<close>;
   394 val mk_transp =  mk_pred @{const_name transp};
   394 val mk_transp =  mk_pred \<^const_name>\<open>transp\<close>;
   395 
   395 
   396 fun mk_trans thm1 thm2 = trans OF [thm1, thm2];
   396 fun mk_trans thm1 thm2 = trans OF [thm1, thm2];
   397 fun mk_sym thm = thm RS sym;
   397 fun mk_sym thm = thm RS sym;
   398 
   398 
   399 val prod_injectD = @{thm iffD1[OF prod.inject]};
   399 val prod_injectD = @{thm iffD1[OF prod.inject]};