src/HOL/Tools/record.ML
changeset 33055 5a733f325939
parent 33053 dabf9d1bb552
parent 33049 c38f02fdf35d
child 33063 4d462963a7db
equal deleted inserted replaced
33054:dd1192a96968 33055:5a733f325939
    24 
    24 
    25 signature RECORD =
    25 signature RECORD =
    26 sig
    26 sig
    27   include BASIC_RECORD
    27   include BASIC_RECORD
    28   val timing: bool Unsynchronized.ref
    28   val timing: bool Unsynchronized.ref
    29   val record_quick_and_dirty_sensitive: bool Unsynchronized.ref
       
    30   val updateN: string
    29   val updateN: string
    31   val updN: string
       
    32   val ext_typeN: string
    30   val ext_typeN: string
    33   val extN: string
    31   val extN: string
    34   val makeN: string
    32   val makeN: string
    35   val moreN: string
    33   val moreN: string
    36   val ext_dest: string
       
    37 
       
    38   val last_extT: typ -> (string * typ list) option
    34   val last_extT: typ -> (string * typ list) option
    39   val dest_recTs : typ -> (string * typ list) list
    35   val dest_recTs: typ -> (string * typ list) list
    40   val get_extT_fields: theory -> typ -> (string * typ) list * (string * typ)
    36   val get_extT_fields: theory -> typ -> (string * typ) list * (string * typ)
    41   val get_recT_fields: theory -> typ -> (string * typ) list * (string * typ)
    37   val get_recT_fields: theory -> typ -> (string * typ) list * (string * typ)
    42   val get_parent: theory -> string -> (typ list * string) option
    38   val get_parent: theory -> string -> (typ list * string) option
    43   val get_extension: theory -> string -> (string * typ list) option
    39   val get_extension: theory -> string -> (string * typ list) option
    44   val get_extinjects: theory -> thm list
    40   val get_extinjects: theory -> thm list
    54 end;
    50 end;
    55 
    51 
    56 
    52 
    57 signature ISTUPLE_SUPPORT =
    53 signature ISTUPLE_SUPPORT =
    58 sig
    54 sig
    59   val add_istuple_type: bstring * string list -> (typ * typ) -> theory -> term * term * theory
    55   val add_istuple_type: bstring * string list -> typ * typ -> theory -> (term * term) * theory
    60 
       
    61   val mk_cons_tuple: term * term -> term
    56   val mk_cons_tuple: term * term -> term
    62   val dest_cons_tuple: term -> term * term
    57   val dest_cons_tuple: term -> term * term
    63 
    58   val istuple_intros_tac: int -> tactic
    64   val istuple_intros_tac: theory -> int -> tactic
       
    65 
       
    66   val named_cterm_instantiate: (string * cterm) list -> thm -> thm
    59   val named_cterm_instantiate: (string * cterm) list -> thm -> thm
    67 end;
    60 end;
    68 
    61 
    69 structure IsTupleSupport: ISTUPLE_SUPPORT =
    62 structure IsTupleSupport: ISTUPLE_SUPPORT =
    70 struct
    63 struct
    71 
    64 
    72 val isomN = "_TupleIsom";
    65 val isomN = "_TupleIsom";
    73 val defN = "_def";
    66 
    74 
    67 val istuple_intro = @{thm isomorphic_tuple_intro};
    75 val istuple_UNIV_I = @{thm "istuple_UNIV_I"};
    68 val istuple_intros = Tactic.build_net @{thms isomorphic_tuple.intros};
    76 val istuple_True_simp = @{thm "istuple_True_simp"};
    69 
    77 
    70 val tuple_istuple = (@{const_name tuple_istuple}, @{thm tuple_istuple});
    78 val istuple_intro = @{thm "isomorphic_tuple_intro"};
       
    79 val istuple_intros = build_net (@{thms "isomorphic_tuple.intros"});
       
    80 
       
    81 val constname = fst o dest_Const;
       
    82 val tuple_istuple = (constname @{term tuple_istuple}, @{thm tuple_istuple});
       
    83 
       
    84 val istuple_constN = constname @{term isomorphic_tuple};
       
    85 val istuple_consN = constname @{term istuple_cons};
       
    86 
       
    87 val tup_isom_typeN = fst (dest_Type @{typ "('a, 'b, 'c) tuple_isomorphism"});
       
    88 
    71 
    89 fun named_cterm_instantiate values thm =
    72 fun named_cterm_instantiate values thm =
    90   let
    73   let
    91     fun match name ((name', _), _) = name = name'
    74     fun match name ((name', _), _) = name = name'
    92       | match name _ = false;
    75       | match name _ = false;
   109 
    92 
   110 fun do_typedef name repT alphas thy =
    93 fun do_typedef name repT alphas thy =
   111   let
    94   let
   112     fun get_thms thy name =
    95     fun get_thms thy name =
   113       let
    96       let
   114         val SOME { Rep_inject=rep_inject, Abs_name=absN, abs_type=absT,
    97         val SOME {Rep_inject = rep_inject, Abs_name = absN, abs_type = absT,
   115           Abs_inverse=abs_inverse, ...} = Typedef.get_info thy name;
    98           Abs_inverse = abs_inverse, ...} = Typedef.get_info thy name;
   116         val rewrite_rule = MetaSimplifier.rewrite_rule [istuple_UNIV_I, istuple_True_simp];
    99         val rewrite_rule =
   117       in (map rewrite_rule [rep_inject, abs_inverse],
   100           MetaSimplifier.rewrite_rule [@{thm istuple_UNIV_I}, @{thm istuple_True_simp}];
   118             Const (absN, repT --> absT), absT) end;
   101       in
       
   102         (map rewrite_rule [rep_inject, abs_inverse], Const (absN, repT --> absT), absT)
       
   103       end;
   119   in
   104   in
   120     thy
   105     thy
   121     |> Typecopy.typecopy (Binding.name name, alphas) repT NONE
   106     |> Typecopy.typecopy (Binding.name name, alphas) repT NONE
   122     |-> (fn (name, _) => `(fn thy => get_thms thy name))
   107     |-> (fn (name, _) => `(fn thy => get_thms thy name))
   123   end;
   108   end;
   124 
   109 
   125 fun mk_cons_tuple (left, right) =
   110 fun mk_cons_tuple (left, right) =
   126   let
   111   let
   127     val (leftT, rightT) = (fastype_of left, fastype_of right);
   112     val (leftT, rightT) = (fastype_of left, fastype_of right);
   128     val prodT = HOLogic.mk_prodT (leftT, rightT);
   113     val prodT = HOLogic.mk_prodT (leftT, rightT);
   129     val isomT = Type (tup_isom_typeN, [prodT, leftT, rightT]);
   114     val isomT = Type (@{type_name tuple_isomorphism}, [prodT, leftT, rightT]);
   130   in
   115   in
   131     Const (istuple_consN, isomT --> leftT --> rightT --> prodT) $
   116     Const (@{const_name istuple_cons}, isomT --> leftT --> rightT --> prodT) $
   132       Const (fst tuple_istuple, isomT) $ left $ right
   117       Const (fst tuple_istuple, isomT) $ left $ right
   133   end;
   118   end;
   134 
   119 
   135 fun dest_cons_tuple (v as Const (ic, _) $ Const _ $ left $ right) =
   120 fun dest_cons_tuple (Const (@{const_name istuple_cons}, _) $ Const _ $ t $ u) = (t, u)
   136       if ic = istuple_consN then (left, right)
   121   | dest_cons_tuple t = raise TERM ("dest_cons_tuple", [t]);
   137       else raise TERM ("dest_cons_tuple", [v])
       
   138   | dest_cons_tuple v = raise TERM ("dest_cons_tuple", [v]);
       
   139 
   122 
   140 fun add_istuple_type (name, alphas) (leftT, rightT) thy =
   123 fun add_istuple_type (name, alphas) (leftT, rightT) thy =
   141   let
   124   let
   142     val repT = HOLogic.mk_prodT (leftT, rightT);
   125     val repT = HOLogic.mk_prodT (leftT, rightT);
   143 
   126 
   151     val intro_inst =
   134     val intro_inst =
   152       rep_inject RS named_cterm_instantiate [("abst", cterm_of typ_thy absC)] istuple_intro;
   135       rep_inject RS named_cterm_instantiate [("abst", cterm_of typ_thy absC)] istuple_intro;
   153     val (_, body) = Logic.dest_equals (List.last (prems_of intro_inst));
   136     val (_, body) = Logic.dest_equals (List.last (prems_of intro_inst));
   154     val isomT = fastype_of body;
   137     val isomT = fastype_of body;
   155     val isom_bind = Binding.name (name ^ isomN);
   138     val isom_bind = Binding.name (name ^ isomN);
   156     val isom = Const (Sign.full_name typ_thy isom_bind, isomT);
   139     val isom_name = Sign.full_name typ_thy isom_bind;
   157     val isom_spec = (name ^ isomN ^ defN, Logic.mk_equals (isom, body));
   140     val isom = Const (isom_name, isomT);
       
   141     val isom_spec = (Thm.def_name (name ^ isomN), Logic.mk_equals (isom, body));
   158 
   142 
   159     val ([isom_def], cdef_thy) =
   143     val ([isom_def], cdef_thy) =
   160       typ_thy
   144       typ_thy
   161       |> Sign.add_consts_i [Syntax.no_syn (isom_bind, isomT)]
   145       |> Sign.add_consts_i [Syntax.no_syn (isom_bind, isomT)]
   162       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name isom_spec)];
   146       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name isom_spec)];
   163 
   147 
   164     val istuple = isom_def RS (abs_inverse RS (rep_inject RS istuple_intro));
   148     val istuple = isom_def RS (abs_inverse RS (rep_inject RS istuple_intro));
   165     val cons = Const (istuple_consN, isomT --> leftT --> rightT --> absT);
   149     val cons = Const (@{const_name istuple_cons}, isomT --> leftT --> rightT --> absT);
   166 
   150 
   167     val thm_thy =
   151     val thm_thy =
   168       cdef_thy
   152       cdef_thy
   169       |> IsTupleThms.map (Symtab.insert Thm.eq_thm_prop (constname isom, istuple))
   153       |> IsTupleThms.map (Symtab.insert Thm.eq_thm_prop (isom_name, istuple))
   170       |> Sign.parent_path;
   154       |> Sign.parent_path;
   171   in
   155   in
   172     (isom, cons $ isom, thm_thy)
   156     ((isom, cons $ isom), thm_thy)
   173   end;
   157   end;
   174 
   158 
   175 fun istuple_intros_tac thy =
   159 val istuple_intros_tac = resolve_from_net_tac istuple_intros THEN'
   176   let
   160   CSUBGOAL (fn (cgoal, i) =>
   177     val isthms = IsTupleThms.get thy;
   161     let
   178     fun err s t = raise TERM ("istuple_intros_tac: " ^ s, [t]);
   162       val thy = Thm.theory_of_cterm cgoal;
   179     val use_istuple_thm_tac = SUBGOAL (fn (goal, n) =>
   163       val goal = Thm.term_of cgoal;
   180       let
   164 
   181         val goal' = Envir.beta_eta_contract goal;
   165       val isthms = IsTupleThms.get thy;
   182         val isom =
   166       fun err s t = raise TERM ("istuple_intros_tac: " ^ s, [t]);
   183           (case goal' of
   167 
   184             Const tp $ (Const pr $ Const is) =>
   168       val goal' = Envir.beta_eta_contract goal;
   185               if fst tp = "Trueprop" andalso fst pr = istuple_constN
   169       val is =
   186               then Const is
   170         (case goal' of
   187               else err "unexpected goal predicate" goal'
   171           Const (@{const_name Trueprop}, _) $
   188           | _ => err "unexpected goal format" goal');
   172             (Const (@{const_name isomorphic_tuple}, _) $ Const is) => is
   189         val isthm =
   173         | _ => err "unexpected goal format" goal');
   190           (case Symtab.lookup isthms (constname isom) of
   174       val isthm =
   191             SOME isthm => isthm
   175         (case Symtab.lookup isthms (#1 is) of
   192           | NONE => err "no thm found for constant" isom);
   176           SOME isthm => isthm
   193       in rtac isthm n end);
   177         | NONE => err "no thm found for constant" (Const is));
   194   in
   178     in rtac isthm i end);
   195     fn n => resolve_from_net_tac istuple_intros n THEN use_istuple_thm_tac n
       
   196   end;
       
   197 
   179 
   198 end;
   180 end;
   199 
   181 
   200 
   182 
   201 structure Record: RECORD =
   183 structure Record: RECORD =
   244 val moreN = "more";
   226 val moreN = "more";
   245 val schemeN = "_scheme";
   227 val schemeN = "_scheme";
   246 val ext_typeN = "_ext_type";
   228 val ext_typeN = "_ext_type";
   247 val inner_typeN = "_inner_type";
   229 val inner_typeN = "_inner_type";
   248 val extN ="_ext";
   230 val extN ="_ext";
   249 val ext_dest = "_sel";
       
   250 val updateN = "_update";
   231 val updateN = "_update";
   251 val updN = "_upd";
       
   252 val makeN = "make";
   232 val makeN = "make";
   253 val fields_selN = "fields";
   233 val fields_selN = "fields";
   254 val extendN = "extend";
   234 val extendN = "extend";
   255 val truncateN = "truncate";
   235 val truncateN = "truncate";
   256 
   236 
   271 fun timeit_msg s x = if ! timing then (warning s; timeit x) else x ();
   251 fun timeit_msg s x = if ! timing then (warning s; timeit x) else x ();
   272 fun timing_msg s = if ! timing then warning s else ();
   252 fun timing_msg s = if ! timing then warning s else ();
   273 
   253 
   274 
   254 
   275 (* syntax *)
   255 (* syntax *)
   276 
       
   277 fun prune n xs = Library.drop (n, xs);
       
   278 
   256 
   279 val Trueprop = HOLogic.mk_Trueprop;
   257 val Trueprop = HOLogic.mk_Trueprop;
   280 fun All xs t = Term.list_all_free (xs, t);
   258 fun All xs t = Term.list_all_free (xs, t);
   281 
   259 
   282 infix 9 $$;
   260 infix 9 $$;
   324       (case try (unsuffix ext_typeN) c_ext_type of
   302       (case try (unsuffix ext_typeN) c_ext_type of
   325         NONE => raise TYPE ("Record.dest_recT", [typ], [])
   303         NONE => raise TYPE ("Record.dest_recT", [typ], [])
   326       | SOME c => ((c, Ts), List.last Ts))
   304       | SOME c => ((c, Ts), List.last Ts))
   327   | dest_recT typ = raise TYPE ("Record.dest_recT", [typ], []);
   305   | dest_recT typ = raise TYPE ("Record.dest_recT", [typ], []);
   328 
   306 
   329 fun is_recT T =
   307 val is_recT = can dest_recT;
   330   (case try dest_recT T of NONE => false | SOME _ => true);
       
   331 
   308 
   332 fun dest_recTs T =
   309 fun dest_recTs T =
   333   let val ((c, Ts), U) = dest_recT T
   310   let val ((c, Ts), U) = dest_recT T
   334   in (c, Ts) :: dest_recTs U
   311   in (c, Ts) :: dest_recTs U
   335   end handle TYPE _ => [];
   312   end handle TYPE _ => [];
   771                  (let
   748                  (let
   772                     val flds' = but_last flds;
   749                     val flds' = but_last flds;
   773                     val types = map snd flds';
   750                     val types = map snd flds';
   774                     val (args, rest) = splitargs (map fst flds') fargs;
   751                     val (args, rest) = splitargs (map fst flds') fargs;
   775                     val argtypes = map (Sign.certify_typ thy o decode_type thy) args;
   752                     val argtypes = map (Sign.certify_typ thy o decode_type thy) args;
   776                     val midx = fold (fn T => fn i => Int.max (maxidx_of_typ T, i)) argtypes 0;
   753                     val midx = fold Term.maxidx_typ argtypes 0;
   777                     val varifyT = varifyT midx;
   754                     val varifyT = varifyT midx;
   778                     val vartypes = map varifyT types;
   755                     val vartypes = map varifyT types;
   779 
   756 
   780                     val subst = fold (Sign.typ_match thy) (vartypes ~~ argtypes) Vartab.empty;
   757                     val subst = fold (Sign.typ_match thy) (vartypes ~~ argtypes) Vartab.empty;
   781                     val alphas' =
   758                     val alphas' =
  1031 
  1008 
  1032 
  1009 
  1033 
  1010 
  1034 (** record simprocs **)
  1011 (** record simprocs **)
  1035 
  1012 
  1036 val record_quick_and_dirty_sensitive = Unsynchronized.ref false;
       
  1037 
       
  1038 
       
  1039 fun quick_and_dirty_prove stndrd thy asms prop tac =
  1013 fun quick_and_dirty_prove stndrd thy asms prop tac =
  1040   if ! record_quick_and_dirty_sensitive andalso ! quick_and_dirty then
  1014   if ! quick_and_dirty then
  1041     Goal.prove (ProofContext.init thy) [] []
  1015     Goal.prove (ProofContext.init thy) [] []
  1042       (Logic.list_implies (map Logic.varify asms, Logic.varify prop))
  1016       (Logic.list_implies (map Logic.varify asms, Logic.varify prop))
  1043       (K (SkipProof.cheat_tac @{theory HOL}))
  1017       (K (Skip_Proof.cheat_tac @{theory HOL}))
  1044       (*Drule.standard can take quite a while for large records, thats why
  1018       (*Drule.standard can take quite a while for large records, thats why
  1045         we varify the proposition manually here.*)
  1019         we varify the proposition manually here.*)
  1046   else
  1020   else
  1047     let val prf = Goal.prove (ProofContext.init thy) [] asms prop tac
  1021     let val prf = Goal.prove (ProofContext.init thy) [] asms prop tac
  1048     in if stndrd then standard prf else prf end;
  1022     in if stndrd then Drule.standard prf else prf end;
  1049 
  1023 
  1050 fun quick_and_dirty_prf noopt opt () =
  1024 fun quick_and_dirty_prf noopt opt () =
  1051   if ! record_quick_and_dirty_sensitive andalso ! quick_and_dirty
  1025   if ! quick_and_dirty then noopt () else opt ();
  1052   then noopt ()
       
  1053   else opt ();
       
  1054 
  1026 
  1055 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) =
  1027 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) =
  1056   (case get_updates thy u of
  1028   (case get_updates thy u of
  1057     SOME u_name => u_name = s
  1029     SOME u_name => u_name = s
  1058   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
  1030   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
  1059 
  1031 
  1060 fun mk_comp f g =
  1032 fun mk_comp f g =
  1061   let
  1033   let
  1062     val x = fastype_of g;
  1034     val X = fastype_of g;
  1063     val a = domain_type x;
  1035     val A = domain_type X;
  1064     val b = range_type x;
  1036     val B = range_type X;
  1065     val c = range_type (fastype_of f);
  1037     val C = range_type (fastype_of f);
  1066     val T = (b --> c) --> ((a --> b) --> (a --> c))
  1038     val T = (B --> C) --> (A --> B) --> A --> C;
  1067   in Const ("Fun.comp", T) $ f $ g end;
  1039   in Const ("Fun.comp", T) $ f $ g end;
  1068 
  1040 
  1069 fun mk_comp_id f =
  1041 fun mk_comp_id f =
  1070   let val T = range_type (fastype_of f)
  1042   let val T = range_type (fastype_of f)
  1071   in mk_comp (Const ("Fun.id", T --> T)) f end;
  1043   in mk_comp (Const ("Fun.id", T --> T)) f end;
  1072 
  1044 
  1073 fun get_upd_funs (upd $ _ $ t) = upd :: get_upd_funs t
  1045 fun get_upd_funs (upd $ _ $ t) = upd :: get_upd_funs t
  1074   | get_upd_funs _ = [];
  1046   | get_upd_funs _ = [];
  1075 
  1047 
  1076 fun get_accupd_simps thy term defset intros_tac =
  1048 fun get_accupd_simps thy term defset =
  1077   let
  1049   let
  1078     val (acc, [body]) = strip_comb term;
  1050     val (acc, [body]) = strip_comb term;
  1079     val upd_funs = sort_distinct TermOrd.fast_term_ord (get_upd_funs body);
  1051     val upd_funs = sort_distinct TermOrd.fast_term_ord (get_upd_funs body);
  1080     fun get_simp upd =
  1052     fun get_simp upd =
  1081       let
  1053       let
  1087           else mk_comp_id acc;
  1059           else mk_comp_id acc;
  1088         val prop = lhs === rhs;
  1060         val prop = lhs === rhs;
  1089         val othm =
  1061         val othm =
  1090           Goal.prove (ProofContext.init thy) [] [] prop
  1062           Goal.prove (ProofContext.init thy) [] [] prop
  1091             (fn _ =>
  1063             (fn _ =>
  1092               EVERY
  1064               simp_tac defset 1 THEN
  1093                [simp_tac defset 1,
  1065               REPEAT_DETERM (IsTupleSupport.istuple_intros_tac 1) THEN
  1094                 REPEAT_DETERM (intros_tac 1),
  1066               TRY (simp_tac (HOL_ss addsimps id_o_apps) 1));
  1095                 TRY (simp_tac (HOL_ss addsimps id_o_apps) 1)]);
       
  1096         val dest =
  1067         val dest =
  1097           if is_sel_upd_pair thy acc upd
  1068           if is_sel_upd_pair thy acc upd
  1098           then o_eq_dest
  1069           then o_eq_dest
  1099           else o_eq_id_dest;
  1070           else o_eq_id_dest;
  1100       in standard (othm RS dest) end;
  1071       in Drule.standard (othm RS dest) end;
  1101   in map get_simp upd_funs end;
  1072   in map get_simp upd_funs end;
  1102 
  1073 
  1103 fun get_updupd_simp thy defset intros_tac u u' comp =
  1074 fun get_updupd_simp thy defset u u' comp =
  1104   let
  1075   let
  1105     val f = Free ("f", domain_type (fastype_of u));
  1076     val f = Free ("f", domain_type (fastype_of u));
  1106     val f' = Free ("f'", domain_type (fastype_of u'));
  1077     val f' = Free ("f'", domain_type (fastype_of u'));
  1107     val lhs = mk_comp (u $ f) (u' $ f');
  1078     val lhs = mk_comp (u $ f) (u' $ f');
  1108     val rhs =
  1079     val rhs =
  1111       else mk_comp (u' $ f') (u $ f);
  1082       else mk_comp (u' $ f') (u $ f);
  1112     val prop = lhs === rhs;
  1083     val prop = lhs === rhs;
  1113     val othm =
  1084     val othm =
  1114       Goal.prove (ProofContext.init thy) [] [] prop
  1085       Goal.prove (ProofContext.init thy) [] [] prop
  1115         (fn _ =>
  1086         (fn _ =>
  1116           EVERY
  1087           simp_tac defset 1 THEN
  1117            [simp_tac defset 1,
  1088           REPEAT_DETERM (IsTupleSupport.istuple_intros_tac 1) THEN
  1118             REPEAT_DETERM (intros_tac 1),
  1089           TRY (simp_tac (HOL_ss addsimps [id_apply]) 1));
  1119             TRY (simp_tac (HOL_ss addsimps [id_apply]) 1)]);
       
  1120     val dest = if comp then o_eq_dest_lhs else o_eq_dest;
  1090     val dest = if comp then o_eq_dest_lhs else o_eq_dest;
  1121   in standard (othm RS dest) end;
  1091   in Drule.standard (othm RS dest) end;
  1122 
  1092 
  1123 fun get_updupd_simps thy term defset intros_tac =
  1093 fun get_updupd_simps thy term defset =
  1124   let
  1094   let
  1125     val upd_funs = get_upd_funs term;
  1095     val upd_funs = get_upd_funs term;
  1126     val cname = fst o dest_Const;
  1096     val cname = fst o dest_Const;
  1127     fun getswap u u' = get_updupd_simp thy defset intros_tac u u' (cname u = cname u');
  1097     fun getswap u u' = get_updupd_simp thy defset u u' (cname u = cname u');
  1128     fun build_swaps_to_eq _ [] swaps = swaps
  1098     fun build_swaps_to_eq _ [] swaps = swaps
  1129       | build_swaps_to_eq upd (u :: us) swaps =
  1099       | build_swaps_to_eq upd (u :: us) swaps =
  1130           let
  1100           let
  1131             val key = (cname u, cname upd);
  1101             val key = (cname u, cname upd);
  1132             val newswaps =
  1102             val newswaps =
  1146 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate;
  1116 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate;
  1147 
  1117 
  1148 fun prove_unfold_defs thy ex_simps ex_simprs prop =
  1118 fun prove_unfold_defs thy ex_simps ex_simprs prop =
  1149   let
  1119   let
  1150     val defset = get_sel_upd_defs thy;
  1120     val defset = get_sel_upd_defs thy;
  1151     val in_tac = IsTupleSupport.istuple_intros_tac thy;
       
  1152     val prop' = Envir.beta_eta_contract prop;
  1121     val prop' = Envir.beta_eta_contract prop;
  1153     val (lhs, _) = Logic.dest_equals (Logic.strip_assums_concl prop');
  1122     val (lhs, _) = Logic.dest_equals (Logic.strip_assums_concl prop');
  1154     val (_, args) = strip_comb lhs;
  1123     val (_, args) = strip_comb lhs;
  1155     val simps =
  1124     val simps = (if length args = 1 then get_accupd_simps else get_updupd_simps) thy lhs defset;
  1156       if length args = 1
       
  1157       then get_accupd_simps thy lhs defset in_tac
       
  1158       else get_updupd_simps thy lhs defset in_tac;
       
  1159   in
  1125   in
  1160     Goal.prove (ProofContext.init thy) [] [] prop'
  1126     Goal.prove (ProofContext.init thy) [] [] prop'
  1161       (fn _ =>
  1127       (fn _ =>
  1162         simp_tac (HOL_basic_ss addsimps (simps @ [K_record_comp])) 1 THEN
  1128         simp_tac (HOL_basic_ss addsimps (simps @ [K_record_comp])) 1 THEN
  1163         TRY (simp_tac (HOL_basic_ss addsimps ex_simps addsimprocs ex_simprs) 1))
  1129         TRY (simp_tac (HOL_basic_ss addsimps ex_simps addsimprocs ex_simprs) 1))
  1244           else NONE
  1210           else NONE
  1245       | _ => NONE));
  1211       | _ => NONE));
  1246 
  1212 
  1247 fun get_upd_acc_cong_thm upd acc thy simpset =
  1213 fun get_upd_acc_cong_thm upd acc thy simpset =
  1248   let
  1214   let
  1249     val in_tac = IsTupleSupport.istuple_intros_tac thy;
  1215     val insts = [("upd", cterm_of thy upd), ("acc", cterm_of thy acc)];
  1250 
  1216     val prop = Thm.concl_of (named_cterm_instantiate insts updacc_cong_triv);
  1251     val insts = [("upd", cterm_of thy upd), ("acc", cterm_of thy acc)]
       
  1252     val prop = concl_of (named_cterm_instantiate insts updacc_cong_triv);
       
  1253   in
  1217   in
  1254     Goal.prove (ProofContext.init thy) [] [] prop
  1218     Goal.prove (ProofContext.init thy) [] [] prop
  1255       (fn _ =>
  1219       (fn _ =>
  1256         EVERY
  1220         simp_tac simpset 1 THEN
  1257          [simp_tac simpset 1,
  1221         REPEAT_DETERM (IsTupleSupport.istuple_intros_tac 1) THEN
  1258           REPEAT_DETERM (in_tac 1),
  1222         TRY (resolve_tac [updacc_cong_idI] 1))
  1259           TRY (resolve_tac [updacc_cong_idI] 1)])
       
  1260   end;
  1223   end;
  1261 
  1224 
  1262 
  1225 
  1263 (* record_upd_simproc *)
  1226 (* record_upd_simproc *)
  1264 
  1227 
  1310         fun get_noop_simps (upd as Const _) (Abs (_, _, (acc as Const _) $ _)) =
  1273         fun get_noop_simps (upd as Const _) (Abs (_, _, (acc as Const _) $ _)) =
  1311           let
  1274           let
  1312             val ss = get_sel_upd_defs thy;
  1275             val ss = get_sel_upd_defs thy;
  1313             val uathm = get_upd_acc_cong_thm upd acc thy ss;
  1276             val uathm = get_upd_acc_cong_thm upd acc thy ss;
  1314           in
  1277           in
  1315             [standard (uathm RS updacc_noopE), standard (uathm RS updacc_noop_compE)]
  1278            [Drule.standard (uathm RS updacc_noopE),
       
  1279             Drule.standard (uathm RS updacc_noop_compE)]
  1316           end;
  1280           end;
  1317 
  1281 
  1318         (*If f is constant then (f o g) = f. we know that K_skeleton
  1282         (*If f is constant then (f o g) = f.  We know that K_skeleton
  1319           only returns constant abstractions thus when we see an
  1283           only returns constant abstractions thus when we see an
  1320           abstraction we can discard inner updates.*)
  1284           abstraction we can discard inner updates.*)
  1321         fun add_upd (f as Abs _) fs = [f]
  1285         fun add_upd (f as Abs _) fs = [f]
  1322           | add_upd f fs = (f :: fs);
  1286           | add_upd f fs = (f :: fs);
  1323 
  1287 
  1374 end;
  1338 end;
  1375 
  1339 
  1376 
  1340 
  1377 (* record_eq_simproc *)
  1341 (* record_eq_simproc *)
  1378 
  1342 
  1379 (*Looks up the most specific record-equality.
  1343 (*Look up the most specific record-equality.
  1380 
  1344 
  1381  Note on efficiency:
  1345  Note on efficiency:
  1382  Testing equality of records boils down to the test of equality of all components.
  1346  Testing equality of records boils down to the test of equality of all components.
  1383  Therefore the complexity is: #components * complexity for single component.
  1347  Therefore the complexity is: #components * complexity for single component.
  1384  Especially if a record has a lot of components it may be better to split up
  1348  Especially if a record has a lot of components it may be better to split up
  1480   P can peek on the whole subterm (including the quantifier); for free variables P
  1444   P can peek on the whole subterm (including the quantifier); for free variables P
  1481   can only peek on the variable itself.
  1445   can only peek on the variable itself.
  1482   P t = 0: do not split
  1446   P t = 0: do not split
  1483   P t = ~1: completely split
  1447   P t = ~1: completely split
  1484   P t > 0: split up to given bound of record extensions.*)
  1448   P t > 0: split up to given bound of record extensions.*)
  1485 fun record_split_simp_tac thms P i st =
  1449 fun record_split_simp_tac thms P = CSUBGOAL (fn (cgoal, i) =>
  1486   let
  1450   let
  1487     val thy = Thm.theory_of_thm st;
  1451     val thy = Thm.theory_of_cterm cgoal;
       
  1452 
       
  1453     val goal = term_of cgoal;
       
  1454     val frees = filter (is_recT o #2) (Term.add_frees goal []);
  1488 
  1455 
  1489     val has_rec = exists_Const
  1456     val has_rec = exists_Const
  1490       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1457       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1491           (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T
  1458           (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T
  1492         | _ => false);
  1459         | _ => false);
  1493 
       
  1494     val goal = nth (Thm.prems_of st) (i - 1);    (* FIXME SUBGOAL *)
       
  1495     val frees = filter (is_recT o type_of) (OldTerm.term_frees goal);
       
  1496 
  1460 
  1497     fun mk_split_free_tac free induct_thm i =
  1461     fun mk_split_free_tac free induct_thm i =
  1498       let
  1462       let
  1499         val cfree = cterm_of thy free;
  1463         val cfree = cterm_of thy free;
  1500         val _$ (_ $ r) = concl_of induct_thm;
  1464         val _$ (_ $ r) = concl_of induct_thm;
  1501         val crec = cterm_of thy r;
  1465         val crec = cterm_of thy r;
  1502         val thm = cterm_instantiate [(crec, cfree)] induct_thm;
  1466         val thm = cterm_instantiate [(crec, cfree)] induct_thm;
  1503       in
  1467       in
  1504         EVERY
  1468         simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i THEN
  1505          [simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i,
  1469         rtac thm i THEN
  1506           rtac thm i,
  1470         simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i
  1507           simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i]
       
  1508       end;
  1471       end;
  1509 
  1472 
  1510     fun split_free_tac P i (free as Free (_, T)) =
  1473     val split_frees_tacs =
  1511           (case rec_id ~1 T of
  1474       frees |> map_filter (fn (x, T) =>
  1512             "" => NONE
  1475         (case rec_id ~1 T of
  1513           | _ =>
  1476           "" => NONE
  1514               let val split = P free in
  1477         | _ =>
  1515                 if split <> 0 then
  1478             let
  1516                   (case get_splits thy (rec_id split T) of
  1479               val free = Free (x, T);
  1517                     NONE => NONE
  1480               val split = P free;
  1518                   | SOME (_, _, _, induct_thm) =>
  1481             in
  1519                       SOME (mk_split_free_tac free induct_thm i))
  1482               if split <> 0 then
  1520                 else NONE
  1483                 (case get_splits thy (rec_id split T) of
  1521               end)
  1484                   NONE => NONE
  1522       | split_free_tac _ _ _ = NONE;
  1485                 | SOME (_, _, _, induct_thm) =>
  1523 
  1486                     SOME (mk_split_free_tac free induct_thm i))
  1524     val split_frees_tacs = map_filter (split_free_tac P i) frees;
  1487               else NONE
       
  1488             end));
  1525 
  1489 
  1526     val simprocs = if has_rec goal then [record_split_simproc P] else [];
  1490     val simprocs = if has_rec goal then [record_split_simproc P] else [];
  1527     val thms' = K_comp_convs @ thms;
  1491     val thms' = K_comp_convs @ thms;
  1528   in
  1492   in
  1529     st |>
  1493     EVERY split_frees_tacs THEN
  1530       (EVERY split_frees_tacs THEN
  1494     Simplifier.full_simp_tac (get_simpset thy addsimps thms' addsimprocs simprocs) i
  1531         Simplifier.full_simp_tac (get_simpset thy addsimps thms' addsimprocs simprocs) i)
  1495   end);
  1532   end handle Empty => Seq.empty;
       
  1533 
  1496 
  1534 
  1497 
  1535 (* record_split_tac *)
  1498 (* record_split_tac *)
  1536 
  1499 
  1537 (*Split all records in the goal, which are quantified by ! or !!.*)
  1500 (*Split all records in the goal, which are quantified by ! or !!.*)
  1538 fun record_split_tac i st =
  1501 val record_split_tac = CSUBGOAL (fn (cgoal, i) =>
  1539   let
  1502   let
       
  1503     val goal = term_of cgoal;
       
  1504 
  1540     val has_rec = exists_Const
  1505     val has_rec = exists_Const
  1541       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1506       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1542           (s = "all" orelse s = "All") andalso is_recT T
  1507           (s = "all" orelse s = "All") andalso is_recT T
  1543         | _ => false);
  1508         | _ => false);
  1544 
       
  1545     val goal = nth (Thm.prems_of st) (i - 1);  (* FIXME SUBGOAL *)
       
  1546 
  1509 
  1547     fun is_all t =
  1510     fun is_all t =
  1548       (case t of
  1511       (case t of
  1549         Const (quantifier, _) $ _ =>
  1512         Const (quantifier, _) $ _ =>
  1550           if quantifier = "All" orelse quantifier = "all" then ~1 else 0
  1513           if quantifier = "All" orelse quantifier = "all" then ~1 else 0
  1551       | _ => 0);
  1514       | _ => 0);
  1552 
       
  1553   in
  1515   in
  1554     if has_rec goal then
  1516     if has_rec goal then
  1555       Simplifier.full_simp_tac
  1517       Simplifier.full_simp_tac (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i
  1556         (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i st
  1518     else no_tac
  1557     else Seq.empty
  1519   end);
  1558   end handle Subscript => Seq.empty;     (* FIXME SUBGOAL *)
       
  1559 
  1520 
  1560 
  1521 
  1561 (* wrapper *)
  1522 (* wrapper *)
  1562 
  1523 
  1563 val record_split_name = "record_split_tac";
  1524 val record_split_name = "record_split_tac";
  1603 
  1564 
  1604 (*Do case analysis / induction according to rule on last parameter of ith subgoal
  1565 (*Do case analysis / induction according to rule on last parameter of ith subgoal
  1605   (or on s if there are no parameters).
  1566   (or on s if there are no parameters).
  1606   Instatiation of record variable (and predicate) in rule is calculated to
  1567   Instatiation of record variable (and predicate) in rule is calculated to
  1607   avoid problems with higher order unification.*)
  1568   avoid problems with higher order unification.*)
  1608 fun try_param_tac s rule i st =
  1569 fun try_param_tac s rule = CSUBGOAL (fn (cgoal, i) =>
  1609   let
  1570   let
  1610     val cert = cterm_of (Thm.theory_of_thm st);
  1571     val cert = Thm.cterm_of (Thm.theory_of_cterm cgoal);
  1611     val g = nth (prems_of st) (i - 1);   (* FIXME SUBGOAL *)
  1572 
       
  1573     val g = Thm.term_of cgoal;
  1612     val params = Logic.strip_params g;
  1574     val params = Logic.strip_params g;
  1613     val concl = HOLogic.dest_Trueprop (Logic.strip_assums_concl g);
  1575     val concl = HOLogic.dest_Trueprop (Logic.strip_assums_concl g);
  1614     val rule' = Thm.lift_rule (Thm.cprem_of st i) rule;
  1576     val rule' = Thm.lift_rule cgoal rule;
  1615     val (P, ys) = strip_comb (HOLogic.dest_Trueprop
  1577     val (P, ys) = strip_comb (HOLogic.dest_Trueprop
  1616       (Logic.strip_assums_concl (prop_of rule')));
  1578       (Logic.strip_assums_concl (prop_of rule')));
  1617     (*ca indicates if rule is a case analysis or induction rule*)
  1579     (*ca indicates if rule is a case analysis or induction rule*)
  1618     val (x, ca) =
  1580     val (x, ca) =
  1619       (case rev (Library.drop (length params, ys)) of
  1581       (case rev (Library.drop (length params, ys)) of
  1620         [] => (head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop
  1582         [] => (head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop
  1621           (hd (rev (Logic.strip_assums_hyp (hd (prems_of rule')))))))), true)
  1583           (hd (rev (Logic.strip_assums_hyp (hd (prems_of rule')))))))), true)
  1622       | [x] => (head_of x, false));
  1584       | [x] => (head_of x, false));
  1623     val rule'' = cterm_instantiate (map (pairself cert)
  1585     val rule'' = cterm_instantiate (map (pairself cert)
  1624       (case (rev params) of
  1586       (case rev params of
  1625         [] =>
  1587         [] =>
  1626           (case AList.lookup (op =) (map dest_Free (OldTerm.term_frees (prop_of st))) s of
  1588           (case AList.lookup (op =) (Term.add_frees g []) s of
  1627             NONE => sys_error "try_param_tac: no such variable"
  1589             NONE => sys_error "try_param_tac: no such variable"
  1628           | SOME T => [(P, if ca then concl else lambda (Free (s, T)) concl), (x, Free (s, T))])
  1590           | SOME T => [(P, if ca then concl else lambda (Free (s, T)) concl), (x, Free (s, T))])
  1629       | (_, T) :: _ =>
  1591       | (_, T) :: _ =>
  1630           [(P, list_abs (params, if ca then concl else incr_boundvars 1 (Abs (s, T, concl)))),
  1592           [(P, list_abs (params, if ca then concl else incr_boundvars 1 (Abs (s, T, concl)))),
  1631             (x, list_abs (params, Bound 0))])) rule';
  1593             (x, list_abs (params, Bound 0))])) rule';
  1632   in compose_tac (false, rule'', nprems_of rule) i st end;
  1594   in compose_tac (false, rule'', nprems_of rule) i end);
  1633 
  1595 
  1634 
  1596 
  1635 fun extension_definition name fields alphas zeta moreT more vars thy =
  1597 fun extension_definition name fields alphas zeta moreT more vars thy =
  1636   let
  1598   let
  1637     val base = Long_Name.base_name;
  1599     val base = Long_Name.base_name;
  1638     val fieldTs = (map snd fields);
  1600     val fieldTs = map snd fields;
  1639     val alphas_zeta = alphas @ [zeta];
  1601     val alphas_zeta = alphas @ [zeta];
  1640     val alphas_zetaTs = map (fn n => TFree (n, HOLogic.typeS)) alphas_zeta;
  1602     val alphas_zetaTs = map (fn a => TFree (a, HOLogic.typeS)) alphas_zeta;
  1641     val extT_name = suffix ext_typeN name
  1603     val extT_name = suffix ext_typeN name
  1642     val extT = Type (extT_name, alphas_zetaTs);
  1604     val extT = Type (extT_name, alphas_zetaTs);
  1643     val fields_moreTs = fieldTs @ [moreT];
  1605     val fields_moreTs = fieldTs @ [moreT];
  1644 
  1606 
  1645 
  1607 
  1650 
  1612 
  1651     fun mk_istuple (left, right) (thy, i) =
  1613     fun mk_istuple (left, right) (thy, i) =
  1652       let
  1614       let
  1653         val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i;
  1615         val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i;
  1654         val nm = suffix suff (Long_Name.base_name name);
  1616         val nm = suffix suff (Long_Name.base_name name);
  1655         val (_, cons, thy') =
  1617         val ((_, cons), thy') =
  1656           IsTupleSupport.add_istuple_type
  1618           IsTupleSupport.add_istuple_type
  1657             (nm, alphas_zeta) (fastype_of left, fastype_of right) thy;
  1619             (nm, alphas_zeta) (fastype_of left, fastype_of right) thy;
  1658       in
  1620       in
  1659         (cons $ left $ right, (thy', i + 1))
  1621         (cons $ left $ right, (thy', i + 1))
  1660       end;
  1622       end;
  1715     val vars_more = vars @ [more];
  1677     val vars_more = vars @ [more];
  1716     val variants = map (fn Free (x, _) => x) vars_more;
  1678     val variants = map (fn Free (x, _) => x) vars_more;
  1717     val ext = mk_ext vars_more;
  1679     val ext = mk_ext vars_more;
  1718     val s = Free (rN, extT);
  1680     val s = Free (rN, extT);
  1719     val P = Free (Name.variant variants "P", extT --> HOLogic.boolT);
  1681     val P = Free (Name.variant variants "P", extT --> HOLogic.boolT);
  1720     val intros_tac = IsTupleSupport.istuple_intros_tac defs_thy;
       
  1721 
  1682 
  1722     val inject_prop =
  1683     val inject_prop =
  1723       let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in
  1684       let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in
  1724         HOLogic.mk_conj (HOLogic.eq_const extT $
  1685         HOLogic.mk_conj (HOLogic.eq_const extT $
  1725           mk_ext vars_more $ mk_ext vars_more', HOLogic.true_const)
  1686           mk_ext vars_more $ mk_ext vars_more', HOLogic.true_const)
  1741 
  1702 
  1742     fun inject_prf () =
  1703     fun inject_prf () =
  1743       simplify HOL_ss
  1704       simplify HOL_ss
  1744         (prove_standard [] inject_prop
  1705         (prove_standard [] inject_prop
  1745           (fn _ =>
  1706           (fn _ =>
  1746             EVERY
  1707             simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1747              [simp_tac (HOL_basic_ss addsimps [ext_def]) 1,
  1708             REPEAT_DETERM
  1748               REPEAT_DETERM (resolve_tac [refl_conj_eq] 1 ORELSE
  1709               (rtac refl_conj_eq 1 ORELSE
  1749                 intros_tac 1 ORELSE
  1710                 IsTupleSupport.istuple_intros_tac 1 ORELSE
  1750                 resolve_tac [refl] 1)]));
  1711                 rtac refl 1)));
  1751 
  1712 
  1752     val inject = timeit_msg "record extension inject proof:" inject_prf;
  1713     val inject = timeit_msg "record extension inject proof:" inject_prf;
  1753 
  1714 
  1754     (*We need a surjection property r = (| f = f r, g = g r ... |)
  1715     (*We need a surjection property r = (| f = f r, g = g r ... |)
  1755       to prove other theorems. We haven't given names to the accessors
  1716       to prove other theorems. We haven't given names to the accessors
  1756       f, g etc yet however, so we generate an ext structure with
  1717       f, g etc yet however, so we generate an ext structure with
  1757       free variables as all arguments and allow the introduction tactic to
  1718       free variables as all arguments and allow the introduction tactic to
  1758       operate on it as far as it can. We then use standard to convert
  1719       operate on it as far as it can. We then use Drule.standard to convert
  1759       the free variables into unifiable variables and unify them with
  1720       the free variables into unifiable variables and unify them with
  1760       (roughly) the definition of the accessor.*)
  1721       (roughly) the definition of the accessor.*)
  1761     fun surject_prf () =
  1722     fun surject_prf () =
  1762       let
  1723       let
  1763         val cterm_ext = cterm_of defs_thy ext;
  1724         val cterm_ext = cterm_of defs_thy ext;
  1764         val start = named_cterm_instantiate [("y", cterm_ext)] surject_assist_idE;
  1725         val start = named_cterm_instantiate [("y", cterm_ext)] surject_assist_idE;
  1765         val tactic1 =
  1726         val tactic1 =
  1766           simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1727           simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1767           REPEAT_ALL_NEW intros_tac 1;
  1728           REPEAT_ALL_NEW IsTupleSupport.istuple_intros_tac 1;
  1768         val tactic2 = REPEAT (rtac surject_assistI 1 THEN rtac refl 1);
  1729         val tactic2 = REPEAT (rtac surject_assistI 1 THEN rtac refl 1);
  1769         val [halfway] = Seq.list_of (tactic1 start);    (* FIXME Seq.lift_of ?? *)
  1730         val [halfway] = Seq.list_of (tactic1 start);
  1770         val [surject] = Seq.list_of (tactic2 (standard halfway));    (* FIXME Seq.lift_of ?? *)
  1731         val [surject] = Seq.list_of (tactic2 (Drule.standard halfway));
  1771       in
  1732       in
  1772         surject
  1733         surject
  1773       end;
  1734       end;
  1774     val surject = timeit_msg "record extension surjective proof:" surject_prf;
  1735     val surject = timeit_msg "record extension surjective proof:" surject_prf;
  1775 
  1736 
  1776     fun split_meta_prf () =
  1737     fun split_meta_prf () =
  1777       prove_standard [] split_meta_prop
  1738       prove_standard [] split_meta_prop
  1778         (fn _ =>
  1739         (fn _ =>
  1779           EVERY
  1740           EVERY1
  1780            [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1,
  1741            [rtac equal_intr_rule, Goal.norm_hhf_tac,
  1781             etac meta_allE 1, atac 1,
  1742             etac meta_allE, atac,
  1782             rtac (prop_subst OF [surject]) 1,
  1743             rtac (prop_subst OF [surject]),
  1783             REPEAT (etac meta_allE 1), atac 1]);
  1744             REPEAT o etac meta_allE, atac]);
  1784     val split_meta = timeit_msg "record extension split_meta proof:" split_meta_prf;
  1745     val split_meta = timeit_msg "record extension split_meta proof:" split_meta_prf;
  1785 
  1746 
  1786     fun induct_prf () =
  1747     fun induct_prf () =
  1787       let val (assm, concl) = induct_prop in
  1748       let val (assm, concl) = induct_prop in
  1788         prove_standard [assm] concl
  1749         prove_standard [assm] concl
  1789           (fn {prems, ...} =>
  1750           (fn {prems, ...} =>
  1790             EVERY
  1751             cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1 THEN
  1791              [cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1,
  1752             resolve_tac prems 2 THEN
  1792               resolve_tac prems 2,
  1753             asm_simp_tac HOL_ss 1)
  1793               asm_simp_tac HOL_ss 1])
       
  1794       end;
  1754       end;
  1795     val induct = timeit_msg "record extension induct proof:" induct_prf;
  1755     val induct = timeit_msg "record extension induct proof:" induct_prf;
  1796 
  1756 
  1797     val ([inject', induct', surjective', split_meta'], thm_thy) =
  1757     val ([inject', induct', surjective', split_meta'], thm_thy) =
  1798       defs_thy
  1758       defs_thy
  1871 
  1831 
  1872     val fields = map (apfst full) bfields;
  1832     val fields = map (apfst full) bfields;
  1873     val names = map fst fields;
  1833     val names = map fst fields;
  1874     val extN = full bname;
  1834     val extN = full bname;
  1875     val types = map snd fields;
  1835     val types = map snd fields;
  1876     val alphas_fields = List.foldr OldTerm.add_typ_tfree_names [] types;
  1836     val alphas_fields = fold Term.add_tfree_namesT types [];
  1877     val alphas_ext = alphas inter alphas_fields;
  1837     val alphas_ext = inter (op =) alphas_fields alphas;
  1878     val len = length fields;
  1838     val len = length fields;
  1879     val variants =
  1839     val variants =
  1880       Name.variant_list (moreN :: rN :: (rN ^ "'") :: wN :: parent_variants)
  1840       Name.variant_list (moreN :: rN :: (rN ^ "'") :: wN :: parent_variants)
  1881         (map fst bfields);
  1841         (map fst bfields);
  1882     val vars = ListPair.map Free (variants, types);
  1842     val vars = ListPair.map Free (variants, types);
  1913     val extension_name = unsuffix ext_typeN (fst extension_scheme);
  1873     val extension_name = unsuffix ext_typeN (fst extension_scheme);
  1914     val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end;
  1874     val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end;
  1915     val extension_names = map (unsuffix ext_typeN o fst o #extension) parents @ [extN];
  1875     val extension_names = map (unsuffix ext_typeN o fst o #extension) parents @ [extN];
  1916     val extension_id = implode extension_names;
  1876     val extension_id = implode extension_names;
  1917 
  1877 
  1918     fun rec_schemeT n = mk_recordT (map #extension (prune n parents)) extT;
  1878     fun rec_schemeT n = mk_recordT (map #extension (Library.drop (n, parents))) extT;
  1919     val rec_schemeT0 = rec_schemeT 0;
  1879     val rec_schemeT0 = rec_schemeT 0;
  1920 
  1880 
  1921     fun recT n =
  1881     fun recT n =
  1922       let val (c, Ts) = extension
  1882       let val (c, Ts) = extension in
  1923       in mk_recordT (map #extension (prune n parents)) (Type (c, subst_last HOLogic.unitT Ts)) end;
  1883         mk_recordT (map #extension (Library.drop (n, parents)))
       
  1884           (Type (c, subst_last HOLogic.unitT Ts))
       
  1885       end;
  1924     val recT0 = recT 0;
  1886     val recT0 = recT 0;
  1925 
  1887 
  1926     fun mk_rec args n =
  1888     fun mk_rec args n =
  1927       let
  1889       let
  1928         val (args', more) = chop_last args;
  1890         val (args', more) = chop_last args;
  1929         fun mk_ext' (((name, T), args), more) = mk_ext (name, T) (args @ [more]);
  1891         fun mk_ext' ((name, T), args) more = mk_ext (name, T) (args @ [more]);
  1930         fun build Ts =
  1892         fun build Ts =
  1931           List.foldr mk_ext' more (prune n (extension_names ~~ Ts ~~ (chunks parent_chunks args')));
  1893           fold_rev mk_ext' (Library.drop (n, (extension_names ~~ Ts) ~~ chunks parent_chunks args'))
       
  1894             more;
  1932       in
  1895       in
  1933         if more = HOLogic.unit
  1896         if more = HOLogic.unit
  1934         then build (map recT (0 upto parent_len))
  1897         then build (map recT (0 upto parent_len))
  1935         else build (map rec_schemeT (0 upto parent_len))
  1898         else build (map rec_schemeT (0 upto parent_len))
  1936       end;
  1899       end;
  1982     val recordT_specs =
  1945     val recordT_specs =
  1983       [(Binding.name (suffix schemeN bname), alphas @ [zeta], rec_schemeT0, Syntax.NoSyn),
  1946       [(Binding.name (suffix schemeN bname), alphas @ [zeta], rec_schemeT0, Syntax.NoSyn),
  1984         (Binding.name bname, alphas, recT0, Syntax.NoSyn)];
  1947         (Binding.name bname, alphas, recT0, Syntax.NoSyn)];
  1985 
  1948 
  1986     val ext_defs = ext_def :: map #extdef parents;
  1949     val ext_defs = ext_def :: map #extdef parents;
  1987     val intros_tac = IsTupleSupport.istuple_intros_tac extension_thy;
       
  1988 
  1950 
  1989     (*Theorems from the istuple intros.
  1951     (*Theorems from the istuple intros.
  1990       This is complex enough to deserve a full comment.
  1952       This is complex enough to deserve a full comment.
  1991       By unfolding ext_defs from r_rec0 we create a tree of constructor
  1953       By unfolding ext_defs from r_rec0 we create a tree of constructor
  1992       calls (many of them Pair, but others as well). The introduction
  1954       calls (many of them Pair, but others as well). The introduction
  2009         val insts = [("v", cterm_rec), ("v'", cterm_vrs)];
  1971         val insts = [("v", cterm_rec), ("v'", cterm_vrs)];
  2010         val init_thm = named_cterm_instantiate insts updacc_eq_triv;
  1972         val init_thm = named_cterm_instantiate insts updacc_eq_triv;
  2011         val terminal = rtac updacc_eq_idI 1 THEN rtac refl 1;
  1973         val terminal = rtac updacc_eq_idI 1 THEN rtac refl 1;
  2012         val tactic =
  1974         val tactic =
  2013           simp_tac (HOL_basic_ss addsimps ext_defs) 1 THEN
  1975           simp_tac (HOL_basic_ss addsimps ext_defs) 1 THEN
  2014           REPEAT (intros_tac 1 ORELSE terminal);
  1976           REPEAT (IsTupleSupport.istuple_intros_tac 1 ORELSE terminal);
  2015         val updaccs = Seq.list_of (tactic init_thm);  (* FIXME Seq.lift_of *)
  1977         val updaccs = Seq.list_of (tactic init_thm);
  2016       in
  1978       in
  2017         (updaccs RL [updacc_accessor_eqE],
  1979         (updaccs RL [updacc_accessor_eqE],
  2018          updaccs RL [updacc_updator_eqE],
  1980          updaccs RL [updacc_updator_eqE],
  2019          updaccs RL [updacc_cong_from_eq])
  1981          updaccs RL [updacc_cong_from_eq])
  2020       end;
  1982       end;
  2021     val (accessor_thms, updator_thms, upd_acc_cong_assists) =
  1983     val (accessor_thms, updator_thms, upd_acc_cong_assists) =
  2022       timeit_msg "record getting tree access/updates:" get_access_update_thms;
  1984       timeit_msg "record getting tree access/updates:" get_access_update_thms;
  2023 
  1985 
  2024     fun lastN xs = List.drop (xs, parent_fields_len);
  1986     fun lastN xs = Library.drop (parent_fields_len, xs);
  2025 
  1987 
  2026     (*selectors*)
  1988     (*selectors*)
  2027     fun mk_sel_spec ((c, T), thm) =
  1989     fun mk_sel_spec ((c, T), thm) =
  2028       let
  1990       let
  2029         val acc $ arg =
  1991         val acc $ arg =
  2133       let val P = Free (Name.variant all_variants "P", rec_schemeT0-->Term.propT) in
  2095       let val P = Free (Name.variant all_variants "P", rec_schemeT0-->Term.propT) in
  2134         Logic.mk_equals
  2096         Logic.mk_equals
  2135          (All [dest_Free r0] (P $ r0), All (map dest_Free all_vars_more) (P $ r_rec0))
  2097          (All [dest_Free r0] (P $ r0), All (map dest_Free all_vars_more) (P $ r_rec0))
  2136       end;
  2098       end;
  2137 
  2099 
  2138     (* FIXME eliminate old List.foldr *)
       
  2139 
       
  2140     val split_object_prop =
  2100     val split_object_prop =
  2141       let fun ALL vs t = List.foldr (fn ((v, T), t) => HOLogic.mk_all (v, T, t)) t vs
  2101       let val ALL = fold_rev (fn (v, T) => fn t => HOLogic.mk_all (v, T, t))
  2142       in (ALL [dest_Free r0] (P $ r0)) === (ALL (map dest_Free all_vars_more) (P $ r_rec0)) end;
  2102       in ALL [dest_Free r0] (P $ r0) === ALL (map dest_Free all_vars_more) (P $ r_rec0) end;
  2143 
  2103 
  2144     val split_ex_prop =
  2104     val split_ex_prop =
  2145       let fun EX vs t = List.foldr (fn ((v, T), t) => HOLogic.mk_exists (v, T, t)) t vs
  2105       let val EX = fold_rev (fn (v, T) => fn t => HOLogic.mk_exists (v, T, t))
  2146       in (EX [dest_Free r0] (P $ r0)) === (EX (map dest_Free all_vars_more) (P $ r_rec0)) end;
  2106       in EX [dest_Free r0] (P $ r0) === EX (map dest_Free all_vars_more) (P $ r_rec0) end;
  2147 
  2107 
  2148     (*equality*)
  2108     (*equality*)
  2149     val equality_prop =
  2109     val equality_prop =
  2150       let
  2110       let
  2151         val s' = Free (rN ^ "'", rec_schemeT0);
  2111         val s' = Free (rN ^ "'", rec_schemeT0);
  2166     val ss = get_simpset defs_thy;
  2126     val ss = get_simpset defs_thy;
  2167 
  2127 
  2168     fun sel_convs_prf () =
  2128     fun sel_convs_prf () =
  2169       map (prove_simp false ss (sel_defs @ accessor_thms)) sel_conv_props;
  2129       map (prove_simp false ss (sel_defs @ accessor_thms)) sel_conv_props;
  2170     val sel_convs = timeit_msg "record sel_convs proof:" sel_convs_prf;
  2130     val sel_convs = timeit_msg "record sel_convs proof:" sel_convs_prf;
  2171     fun sel_convs_standard_prf () = map standard sel_convs
  2131     fun sel_convs_standard_prf () = map Drule.standard sel_convs
  2172     val sel_convs_standard =
  2132     val sel_convs_standard =
  2173       timeit_msg "record sel_convs_standard proof:" sel_convs_standard_prf;
  2133       timeit_msg "record sel_convs_standard proof:" sel_convs_standard_prf;
  2174 
  2134 
  2175     fun upd_convs_prf () =
  2135     fun upd_convs_prf () =
  2176       map (prove_simp false ss (upd_defs @ updator_thms)) upd_conv_props;
  2136       map (prove_simp false ss (upd_defs @ updator_thms)) upd_conv_props;
  2177     val upd_convs = timeit_msg "record upd_convs proof:" upd_convs_prf;
  2137     val upd_convs = timeit_msg "record upd_convs proof:" upd_convs_prf;
  2178     fun upd_convs_standard_prf () = map standard upd_convs
  2138     fun upd_convs_standard_prf () = map Drule.standard upd_convs
  2179     val upd_convs_standard =
  2139     val upd_convs_standard =
  2180       timeit_msg "record upd_convs_standard proof:" upd_convs_standard_prf;
  2140       timeit_msg "record upd_convs_standard proof:" upd_convs_standard_prf;
  2181 
  2141 
  2182     fun get_upd_acc_congs () =
  2142     fun get_upd_acc_congs () =
  2183       let
  2143       let
  2184         val symdefs = map symmetric (sel_defs @ upd_defs);
  2144         val symdefs = map symmetric (sel_defs @ upd_defs);
  2185         val fold_ss = HOL_basic_ss addsimps symdefs;
  2145         val fold_ss = HOL_basic_ss addsimps symdefs;
  2186         val ua_congs = map (standard o simplify fold_ss) upd_acc_cong_assists;
  2146         val ua_congs = map (Drule.standard o simplify fold_ss) upd_acc_cong_assists;
  2187       in (ua_congs RL [updacc_foldE], ua_congs RL [updacc_unfoldE]) end;
  2147       in (ua_congs RL [updacc_foldE], ua_congs RL [updacc_unfoldE]) end;
  2188     val (fold_congs, unfold_congs) =
  2148     val (fold_congs, unfold_congs) =
  2189       timeit_msg "record upd fold/unfold congs:" get_upd_acc_congs;
  2149       timeit_msg "record upd fold/unfold congs:" get_upd_acc_congs;
  2190 
  2150 
  2191     val parent_induct = if null parents then [] else [#induct (hd (rev parents))];
  2151     val parent_induct = if null parents then [] else [#induct (hd (rev parents))];
  2192 
  2152 
  2193     fun induct_scheme_prf () =
  2153     fun induct_scheme_prf () =
  2194       prove_standard [] induct_scheme_prop
  2154       prove_standard [] induct_scheme_prop
  2195         (fn _ =>
  2155         (fn _ =>
  2196           EVERY
  2156           EVERY
  2197            [if null parent_induct
  2157            [if null parent_induct then all_tac else try_param_tac rN (hd parent_induct) 1,
  2198             then all_tac else try_param_tac rN (hd parent_induct) 1,
       
  2199             try_param_tac rN ext_induct 1,
  2158             try_param_tac rN ext_induct 1,
  2200             asm_simp_tac HOL_basic_ss 1]);
  2159             asm_simp_tac HOL_basic_ss 1]);
  2201     val induct_scheme = timeit_msg "record induct_scheme proof:" induct_scheme_prf;
  2160     val induct_scheme = timeit_msg "record induct_scheme proof:" induct_scheme_prf;
  2202 
  2161 
  2203     fun induct_prf () =
  2162     fun induct_prf () =
  2215         val ind =
  2174         val ind =
  2216           cterm_instantiate
  2175           cterm_instantiate
  2217             [(cterm_of defs_thy Pvar, cterm_of defs_thy
  2176             [(cterm_of defs_thy Pvar, cterm_of defs_thy
  2218               (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))]
  2177               (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))]
  2219             induct_scheme;
  2178             induct_scheme;
  2220         in standard (ObjectLogic.rulify (mp OF [ind, refl])) end;
  2179         in Drule.standard (ObjectLogic.rulify (mp OF [ind, refl])) end;
  2221 
  2180 
  2222     fun cases_scheme_prf_noopt () =
  2181     fun cases_scheme_prf_noopt () =
  2223       prove_standard [] cases_scheme_prop
  2182       prove_standard [] cases_scheme_prop
  2224         (fn _ =>
  2183         (fn _ =>
  2225           EVERY
  2184           EVERY1
  2226            [asm_full_simp_tac (HOL_basic_ss addsimps [atomize_all, atomize_imp]) 1,
  2185            [asm_full_simp_tac (HOL_basic_ss addsimps [atomize_all, atomize_imp]),
  2227             try_param_tac rN induct_scheme 1,
  2186             try_param_tac rN induct_scheme,
  2228             rtac impI 1,
  2187             rtac impI,
  2229             REPEAT (etac allE 1),
  2188             REPEAT o etac allE,
  2230             etac mp 1,
  2189             etac mp,
  2231             rtac refl 1]);
  2190             rtac refl]);
  2232     val cases_scheme_prf = quick_and_dirty_prf cases_scheme_prf_noopt cases_scheme_prf_opt;
  2191     val cases_scheme_prf = quick_and_dirty_prf cases_scheme_prf_noopt cases_scheme_prf_opt;
  2233     val cases_scheme = timeit_msg "record cases_scheme proof:" cases_scheme_prf;
  2192     val cases_scheme = timeit_msg "record cases_scheme proof:" cases_scheme_prf;
  2234 
  2193 
  2235     fun cases_prf () =
  2194     fun cases_prf () =
  2236       prove_standard [] cases_prop
  2195       prove_standard [] cases_prop
  2247         prove_standard [] surjective_prop
  2206         prove_standard [] surjective_prop
  2248           (fn _ =>
  2207           (fn _ =>
  2249             EVERY
  2208             EVERY
  2250              [rtac surject_assist_idE 1,
  2209              [rtac surject_assist_idE 1,
  2251               simp_tac init_ss 1,
  2210               simp_tac init_ss 1,
  2252               REPEAT (intros_tac 1 ORELSE (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))])
  2211               REPEAT
       
  2212                 (IsTupleSupport.istuple_intros_tac 1 ORELSE
       
  2213                   (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))])
  2253       end;
  2214       end;
  2254     val surjective = timeit_msg "record surjective proof:" surjective_prf;
  2215     val surjective = timeit_msg "record surjective proof:" surjective_prf;
  2255 
  2216 
  2256     fun split_meta_prf () =
  2217     fun split_meta_prf () =
  2257       prove false [] split_meta_prop
  2218       prove false [] split_meta_prop
  2258         (fn _ =>
  2219         (fn _ =>
  2259           EVERY
  2220           EVERY1
  2260            [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1,
  2221            [rtac equal_intr_rule, Goal.norm_hhf_tac,
  2261             etac meta_allE 1, atac 1,
  2222             etac meta_allE, atac,
  2262             rtac (prop_subst OF [surjective]) 1,
  2223             rtac (prop_subst OF [surjective]),
  2263             REPEAT (etac meta_allE 1), atac 1]);
  2224             REPEAT o etac meta_allE, atac]);
  2264     val split_meta = timeit_msg "record split_meta proof:" split_meta_prf;
  2225     val split_meta = timeit_msg "record split_meta proof:" split_meta_prf;
  2265     fun split_meta_standardise () = standard split_meta;
  2226     fun split_meta_standardise () = Drule.standard split_meta;
  2266     val split_meta_standard =
  2227     val split_meta_standard =
  2267       timeit_msg "record split_meta standard:" split_meta_standardise;
  2228       timeit_msg "record split_meta standard:" split_meta_standardise;
  2268 
  2229 
  2269     fun split_object_prf_opt () =
  2230     fun split_object_prf_opt () =
  2270       let
  2231       let
  2285           assume cr                             (*All n m more. P (ext n m more)*)
  2246           assume cr                             (*All n m more. P (ext n m more)*)
  2286           |> obj_to_meta_all                    (*!!n m more. P (ext n m more)*)
  2247           |> obj_to_meta_all                    (*!!n m more. P (ext n m more)*)
  2287           |> equal_elim (symmetric split_meta') (*!!r. P r*)
  2248           |> equal_elim (symmetric split_meta') (*!!r. P r*)
  2288           |> meta_to_obj_all                    (*All r. P r*)
  2249           |> meta_to_obj_all                    (*All r. P r*)
  2289           |> implies_intr cr                    (* 2 ==> 1 *)
  2250           |> implies_intr cr                    (* 2 ==> 1 *)
  2290      in standard (thr COMP (thl COMP iffI)) end;
  2251      in Drule.standard (thr COMP (thl COMP iffI)) end;
  2291 
  2252 
  2292     fun split_object_prf_noopt () =
  2253     fun split_object_prf_noopt () =
  2293       prove_standard [] split_object_prop
  2254       prove_standard [] split_object_prop
  2294         (fn _ =>
  2255         (fn _ =>
  2295           EVERY
  2256           EVERY1
  2296            [rtac iffI 1,
  2257            [rtac iffI,
  2297             REPEAT (rtac allI 1), etac allE 1, atac 1,
  2258             REPEAT o rtac allI, etac allE, atac,
  2298             rtac allI 1, rtac induct_scheme 1, REPEAT (etac allE 1), atac 1]);
  2259             rtac allI, rtac induct_scheme, REPEAT o etac allE, atac]);
  2299 
  2260 
  2300     val split_object_prf = quick_and_dirty_prf split_object_prf_noopt split_object_prf_opt;
  2261     val split_object_prf = quick_and_dirty_prf split_object_prf_noopt split_object_prf_opt;
  2301     val split_object = timeit_msg "record split_object proof:" split_object_prf;
  2262     val split_object = timeit_msg "record split_object proof:" split_object_prf;
  2302 
  2263 
  2303 
  2264 
  2398     val parents = add_parents thy parent [];
  2359     val parents = add_parents thy parent [];
  2399 
  2360 
  2400     val init_env =
  2361     val init_env =
  2401       (case parent of
  2362       (case parent of
  2402         NONE => []
  2363         NONE => []
  2403       | SOME (types, _) => List.foldr OldTerm.add_typ_tfrees [] types);
  2364       | SOME (types, _) => fold Term.add_tfreesT types []);
  2404 
  2365 
  2405 
  2366 
  2406     (* fields *)
  2367     (* fields *)
  2407 
  2368 
  2408     fun prep_field (c, raw_T, mx) env =
  2369     fun prep_field (c, raw_T, mx) env =