src/HOL/Tools/record.ML
changeset 32799 7478ea535416
parent 32770 c6e6a4665ff5
child 32808 0059238fe4bc
equal deleted inserted replaced
32798:4b85b59a9f66 32799:7478ea535416
   200 
   200 
   201 structure Record: RECORD =
   201 structure Record: RECORD =
   202 struct
   202 struct
   203 
   203 
   204 val eq_reflection = @{thm eq_reflection};
   204 val eq_reflection = @{thm eq_reflection};
   205 val Pair_eq = @{thm Product_Type.prod.inject};
       
   206 val atomize_all = @{thm HOL.atomize_all};
   205 val atomize_all = @{thm HOL.atomize_all};
   207 val atomize_imp = @{thm HOL.atomize_imp};
   206 val atomize_imp = @{thm HOL.atomize_imp};
   208 val meta_allE = @{thm Pure.meta_allE};
   207 val meta_allE = @{thm Pure.meta_allE};
   209 val prop_subst = @{thm prop_subst};
   208 val prop_subst = @{thm prop_subst};
   210 val Pair_sel_convs = [fst_conv, snd_conv];
       
   211 val K_record_comp = @{thm K_record_comp};
   209 val K_record_comp = @{thm K_record_comp};
   212 val K_comp_convs = [@{thm o_apply}, K_record_comp]
   210 val K_comp_convs = [@{thm o_apply}, K_record_comp]
   213 val transitive_thm = @{thm transitive};
       
   214 val o_assoc = @{thm o_assoc};
   211 val o_assoc = @{thm o_assoc};
   215 val id_apply = @{thm id_apply};
   212 val id_apply = @{thm id_apply};
   216 val id_o_apps = [@{thm id_apply}, @{thm id_o}, @{thm o_id}];
   213 val id_o_apps = [@{thm id_apply}, @{thm id_o}, @{thm o_id}];
   217 val Not_eq_iff = @{thm Not_eq_iff};
   214 val Not_eq_iff = @{thm Not_eq_iff};
   218 
   215 
   219 val refl_conj_eq = @{thm refl_conj_eq};
   216 val refl_conj_eq = @{thm refl_conj_eq};
   220 val meta_all_sameI = @{thm meta_all_sameI};
       
   221 
   217 
   222 val surject_assistI = @{thm "istuple_surjective_proof_assistI"};
   218 val surject_assistI = @{thm "istuple_surjective_proof_assistI"};
   223 val surject_assist_idE = @{thm "istuple_surjective_proof_assist_idE"};
   219 val surject_assist_idE = @{thm "istuple_surjective_proof_assist_idE"};
   224 
   220 
   225 val updacc_accessor_eqE = @{thm "update_accessor_accessor_eqE"};
   221 val updacc_accessor_eqE = @{thm "update_accessor_accessor_eqE"};
   248 val moreN = "more";
   244 val moreN = "more";
   249 val schemeN = "_scheme";
   245 val schemeN = "_scheme";
   250 val ext_typeN = "_ext_type";
   246 val ext_typeN = "_ext_type";
   251 val inner_typeN = "_inner_type";
   247 val inner_typeN = "_inner_type";
   252 val extN ="_ext";
   248 val extN ="_ext";
   253 val casesN = "_cases";
       
   254 val ext_dest = "_sel";
   249 val ext_dest = "_sel";
   255 val updateN = "_update";
   250 val updateN = "_update";
   256 val updN = "_upd";
   251 val updN = "_upd";
   257 val makeN = "make";
   252 val makeN = "make";
   258 val fields_selN = "fields";
   253 val fields_selN = "fields";
   259 val extendN = "extend";
   254 val extendN = "extend";
   260 val truncateN = "truncate";
   255 val truncateN = "truncate";
   261 
   256 
   262 (*see typedef.ML*)
       
   263 val RepN = "Rep_";
       
   264 val AbsN = "Abs_";
       
   265 
       
   266 
   257 
   267 
   258 
   268 (*** utilities ***)
   259 (*** utilities ***)
   269 
   260 
   270 fun but_last xs = fst (split_last xs);
   261 fun but_last xs = fst (split_last xs);
   271 
   262 
   272 fun varifyT midx =
   263 fun varifyT midx =
   273   let fun varify (a, S) = TVar ((a, midx + 1), S);
   264   let fun varify (a, S) = TVar ((a, midx + 1), S);
   274   in map_type_tfree varify end;
   265   in map_type_tfree varify end;
   275 
   266 
   276 fun domain_type' T =
       
   277   domain_type T handle Match => T;
       
   278 
       
   279 fun range_type' T =
       
   280   range_type T handle Match => T;
       
   281 
       
   282 
       
   283 (* messages *)  (* FIXME proper context *)
       
   284 
       
   285 fun trace_thm str thm =
       
   286   tracing (str ^ Pretty.string_of (Display.pretty_thm_without_context thm));
       
   287 
       
   288 fun trace_thms str thms =
       
   289   (tracing str; map (trace_thm "") thms);
       
   290 
       
   291 fun trace_term str t =
       
   292   tracing (str ^ Syntax.string_of_term_global Pure.thy t);
       
   293 
       
   294 
   267 
   295 (* timing *)
   268 (* timing *)
   296 
   269 
   297 val timing = Unsynchronized.ref false;
   270 val timing = Unsynchronized.ref false;
   298 fun timeit_msg s x = if ! timing then (warning s; timeit x) else x ();
   271 fun timeit_msg s x = if ! timing then (warning s; timeit x) else x ();
   300 
   273 
   301 
   274 
   302 (* syntax *)
   275 (* syntax *)
   303 
   276 
   304 fun prune n xs = Library.drop (n, xs);
   277 fun prune n xs = Library.drop (n, xs);
   305 fun prefix_base s = Long_Name.map_base_name (fn bname => s ^ bname);
       
   306 
   278 
   307 val Trueprop = HOLogic.mk_Trueprop;
   279 val Trueprop = HOLogic.mk_Trueprop;
   308 fun All xs t = Term.list_all_free (xs, t);
   280 fun All xs t = Term.list_all_free (xs, t);
   309 
   281 
   310 infix 9 $$;
   282 infix 9 $$;
   311 infix 0 :== ===;
   283 infix 0 :== ===;
   312 infixr 0 ==>;
   284 infixr 0 ==>;
   313 
   285 
   314 val (op $$) = Term.list_comb;
   286 val op $$ = Term.list_comb;
   315 val (op :==) = PrimitiveDefs.mk_defpair;
   287 val op :== = PrimitiveDefs.mk_defpair;
   316 val (op ===) = Trueprop o HOLogic.mk_eq;
   288 val op === = Trueprop o HOLogic.mk_eq;
   317 val (op ==>) = Logic.mk_implies;
   289 val op ==> = Logic.mk_implies;
   318 
       
   319 
       
   320 (* morphisms *)
       
   321 
       
   322 fun mk_RepN name = suffix ext_typeN (prefix_base RepN name);
       
   323 fun mk_AbsN name = suffix ext_typeN (prefix_base AbsN name);
       
   324 
       
   325 fun mk_Rep name repT absT =
       
   326   Const (suffix ext_typeN (prefix_base RepN name), absT --> repT);
       
   327 
       
   328 fun mk_Abs name repT absT =
       
   329   Const (mk_AbsN name, repT --> absT);
       
   330 
   290 
   331 
   291 
   332 (* constructor *)
   292 (* constructor *)
   333 
   293 
   334 fun mk_extC (name, T) Ts = (suffix extN name, Ts ---> T);
   294 fun mk_extC (name, T) Ts = (suffix extN name, Ts ---> T);
   336 fun mk_ext (name, T) ts =
   296 fun mk_ext (name, T) ts =
   337   let val Ts = map fastype_of ts
   297   let val Ts = map fastype_of ts
   338   in list_comb (Const (mk_extC (name, T) Ts), ts) end;
   298   in list_comb (Const (mk_extC (name, T) Ts), ts) end;
   339 
   299 
   340 
   300 
   341 (* cases *)
       
   342 
       
   343 fun mk_casesC (name, T, vT) Ts = (suffix casesN name, (Ts ---> vT) --> T --> vT);
       
   344 
       
   345 fun mk_cases (name, T, vT) f =
       
   346   let val Ts = binder_types (fastype_of f)
       
   347   in Const (mk_casesC (name, T, vT) Ts) $ f end;
       
   348 
       
   349 
       
   350 (* selector *)
   301 (* selector *)
   351 
   302 
   352 fun mk_selC sT (c, T) = (c, sT --> T);
   303 fun mk_selC sT (c, T) = (c, sT --> T);
   353 
   304 
   354 fun mk_sel s (c, T) =
   305 fun mk_sel s (c, T) =
   367 fun mk_upd sfx c v s = mk_upd' sfx c v (fastype_of s) $ s;
   318 fun mk_upd sfx c v s = mk_upd' sfx c v (fastype_of s) $ s;
   368 
   319 
   369 
   320 
   370 (* types *)
   321 (* types *)
   371 
   322 
   372 fun dest_recT (typ as Type (c_ext_type, Ts as (T :: _))) =
   323 fun dest_recT (typ as Type (c_ext_type, Ts as (_ :: _))) =
   373       (case try (unsuffix ext_typeN) c_ext_type of
   324       (case try (unsuffix ext_typeN) c_ext_type of
   374         NONE => raise TYPE ("Record.dest_recT", [typ], [])
   325         NONE => raise TYPE ("Record.dest_recT", [typ], [])
   375       | SOME c => ((c, Ts), List.last Ts))
   326       | SOME c => ((c, Ts), List.last Ts))
   376   | dest_recT typ = raise TYPE ("Record.dest_recT", [typ], []);
   327   | dest_recT typ = raise TYPE ("Record.dest_recT", [typ], []);
   377 
   328 
   547 val get_updates = Symtab.lookup o #updates o get_sel_upd;
   498 val get_updates = Symtab.lookup o #updates o get_sel_upd;
   548 fun get_ss_with_context getss thy = Simplifier.theory_context thy (getss (get_sel_upd thy));
   499 fun get_ss_with_context getss thy = Simplifier.theory_context thy (getss (get_sel_upd thy));
   549 
   500 
   550 val get_simpset = get_ss_with_context #simpset;
   501 val get_simpset = get_ss_with_context #simpset;
   551 val get_sel_upd_defs = get_ss_with_context #defset;
   502 val get_sel_upd_defs = get_ss_with_context #defset;
   552 val get_foldcong_ss = get_ss_with_context #foldcong;
       
   553 val get_unfoldcong_ss = get_ss_with_context #unfoldcong;
       
   554 
   503 
   555 fun get_update_details u thy =
   504 fun get_update_details u thy =
   556   let val sel_upd = get_sel_upd thy in
   505   let val sel_upd = get_sel_upd thy in
   557     (case Symtab.lookup (#updates sel_upd) u of
   506     (case Symtab.lookup (#updates sel_upd) u of
   558       SOME s =>
   507       SOME s =>
   616     val data = make_record_data records sel_upd
   565     val data = make_record_data records sel_upd
   617       equalities extinjects (Symtab.update_new (name, thm) extsplit) splits
   566       equalities extinjects (Symtab.update_new (name, thm) extsplit) splits
   618       extfields fieldext;
   567       extfields fieldext;
   619   in RecordsData.put data thy end;
   568   in RecordsData.put data thy end;
   620 
   569 
   621 val get_extsplit = Symtab.lookup o #extsplit o RecordsData.get;
       
   622 
       
   623 
   570 
   624 (* access 'splits' *)
   571 (* access 'splits' *)
   625 
   572 
   626 fun add_record_splits name thmP thy =
   573 fun add_record_splits name thmP thy =
   627   let
   574   let
   657 
   604 
   658 fun get_extT_fields thy T =
   605 fun get_extT_fields thy T =
   659   let
   606   let
   660     val ((name, Ts), moreT) = dest_recT T;
   607     val ((name, Ts), moreT) = dest_recT T;
   661     val recname =
   608     val recname =
   662       let val (nm :: recn :: rst) = rev (Long_Name.explode name)
   609       let val (nm :: _ :: rst) = rev (Long_Name.explode name)   (* FIXME !? *)
   663       in Long_Name.implode (rev (nm :: rst)) end;
   610       in Long_Name.implode (rev (nm :: rst)) end;
   664     val midx = maxidx_of_typs (moreT :: Ts);
   611     val midx = maxidx_of_typs (moreT :: Ts);
   665     val varifyT = varifyT midx;
   612     val varifyT = varifyT midx;
   666     val {records, extfields, ...} = RecordsData.get thy;
   613     val {records, extfields, ...} = RecordsData.get thy;
   667     val (flds, (more, _)) = split_last (Symtab.lookup_list extfields name);
   614     val (flds, (more, _)) = split_last (Symtab.lookup_list extfields name);
   696 val get_fieldext = Symtab.lookup o #fieldext o RecordsData.get;
   643 val get_fieldext = Symtab.lookup o #fieldext o RecordsData.get;
   697 
   644 
   698 
   645 
   699 (* parent records *)
   646 (* parent records *)
   700 
   647 
   701 fun add_parents thy NONE parents = parents
   648 fun add_parents _ NONE parents = parents
   702   | add_parents thy (SOME (types, name)) parents =
   649   | add_parents thy (SOME (types, name)) parents =
   703       let
   650       let
   704         fun err msg = error (msg ^ " parent record " ^ quote name);
   651         fun err msg = error (msg ^ " parent record " ^ quote name);
   705 
   652 
   706         val {args, parent, fields, extension, induct, extdef} =
   653         val {args, parent, fields, extension, induct, extdef} =
   785           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   732           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   786       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   733       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   787       | splitargs (_ :: _) [] = raise TERM (msg ^ "expecting more fields", [t])
   734       | splitargs (_ :: _) [] = raise TERM (msg ^ "expecting more fields", [t])
   788       | splitargs _ _ = ([], []);
   735       | splitargs _ _ = ([], []);
   789 
   736 
   790     fun mk_ext (fargs as (name, arg) :: _) =
   737     fun mk_ext (fargs as (name, _) :: _) =
   791           (case get_fieldext thy (Sign.intern_const thy name) of
   738           (case get_fieldext thy (Sign.intern_const thy name) of
   792             SOME (ext, _) =>
   739             SOME (ext, _) =>
   793               (case get_extfields thy ext of
   740               (case get_extfields thy ext of
   794                 SOME flds =>
   741                 SOME flds =>
   795                   let
   742                   let
   814           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   761           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   815       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   762       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   816       | splitargs (_ :: _) [] = raise TERM (msg ^ "expecting more fields", [t])
   763       | splitargs (_ :: _) [] = raise TERM (msg ^ "expecting more fields", [t])
   817       | splitargs _ _ = ([], []);
   764       | splitargs _ _ = ([], []);
   818 
   765 
   819     fun mk_ext (fargs as (name, arg) :: _) =
   766     fun mk_ext (fargs as (name, _) :: _) =
   820           (case get_fieldext thy (Sign.intern_const thy name) of
   767           (case get_fieldext thy (Sign.intern_const thy name) of
   821             SOME (ext, alphas) =>
   768             SOME (ext, alphas) =>
   822               (case get_extfields thy ext of
   769               (case get_extfields thy ext of
   823                 SOME flds =>
   770                 SOME flds =>
   824                  (let
   771                  (let
   836                         (but_last alphas);
   783                         (but_last alphas);
   837 
   784 
   838                     val more' = mk_ext rest;
   785                     val more' = mk_ext rest;
   839                   in
   786                   in
   840                     list_comb (Syntax.const (suffix sfx ext), alphas' @ [more'])
   787                     list_comb (Syntax.const (suffix sfx ext), alphas' @ [more'])
   841                   end handle TYPE_MATCH =>
   788                   end handle Type.TYPE_MATCH =>
   842                     raise TERM (msg ^ "type is no proper record (extension)", [t]))
   789                     raise TERM (msg ^ "type is no proper record (extension)", [t]))
   843               | NONE => raise TERM (msg ^ "no fields defined for " ^ ext, [t]))
   790               | NONE => raise TERM (msg ^ "no fields defined for " ^ ext, [t]))
   844           | NONE => raise TERM (msg ^ name ^" is no proper field", [t]))
   791           | NONE => raise TERM (msg ^ name ^" is no proper field", [t]))
   845       | mk_ext [] = more;
   792       | mk_ext [] = more;
   846 
   793 
   894       let
   841       let
   895         val t =
   842         val t =
   896           (case k of
   843           (case k of
   897             Abs (_, _, Abs (_, _, t) $ Bound 0) =>
   844             Abs (_, _, Abs (_, _, t) $ Bound 0) =>
   898               if null (loose_bnos t) then t else raise Match
   845               if null (loose_bnos t) then t else raise Match
   899           | Abs (x, _, t) =>
   846           | Abs (_, _, t) =>
   900               if null (loose_bnos t) then t else raise Match
   847               if null (loose_bnos t) then t else raise Match
   901           | _ => raise Match);
   848           | _ => raise Match);
   902 
   849 
   903           (* FIXME ? *)
   850           (* FIXME ? *)
   904           (* (case k of (Const ("K_record", _) $ t) => t
   851           (* (case k of (Const ("K_record", _) $ t) => t
  1010           if name = lastExt then
   957           if name = lastExt then
  1011            (let val subst = match schemeT T in
   958            (let val subst = match schemeT T in
  1012               if HOLogic.is_unitT (Envir.norm_type subst (varifyT (TFree (zeta, Sign.defaultS thy))))
   959               if HOLogic.is_unitT (Envir.norm_type subst (varifyT (TFree (zeta, Sign.defaultS thy))))
  1013               then mk_type_abbr subst abbr alphas
   960               then mk_type_abbr subst abbr alphas
  1014               else mk_type_abbr subst (suffix schemeN abbr) (alphas @ [zeta])
   961               else mk_type_abbr subst (suffix schemeN abbr) (alphas @ [zeta])
  1015             end handle TYPE_MATCH => default_tr' ctxt tm)
   962             end handle Type.TYPE_MATCH => default_tr' ctxt tm)
  1016           else raise Match (*give print translation of specialised record a chance*)
   963           else raise Match (*give print translation of specialised record a chance*)
  1017       | _ => raise Match)
   964       | _ => raise Match)
  1018     else default_tr' ctxt tm
   965     else default_tr' ctxt tm
  1019   end;
   966   end;
  1020 
   967 
  1043                         val (args', more) = split_last args;
   990                         val (args', more) = split_last args;
  1044                         val alphavars = map varifyT (but_last alphas);
   991                         val alphavars = map varifyT (but_last alphas);
  1045                         val subst = fold2 (curry (Sign.typ_match thy)) alphavars args' Vartab.empty;
   992                         val subst = fold2 (curry (Sign.typ_match thy)) alphavars args' Vartab.empty;
  1046                         val flds'' = (map o apsnd) (Envir.norm_type subst o varifyT) flds';
   993                         val flds'' = (map o apsnd) (Envir.norm_type subst o varifyT) flds';
  1047                       in flds'' @ field_lst more end
   994                       in flds'' @ field_lst more end
  1048                       handle TYPE_MATCH => [("", T)]
   995                       handle Type.TYPE_MATCH => [("", T)] | Library.UnequalLengths => [("", T)])
  1049                         | Library.UnequalLengths => [("", T)])
       
  1050                   | NONE => [("", T)])
   996                   | NONE => [("", T)])
  1051               | NONE => [("", T)])
   997               | NONE => [("", T)])
  1052           | NONE => [("", T)])
   998           | NONE => [("", T)])
  1053       | _ => [("", T)]);
   999       | _ => [("", T)]);
  1054 
  1000 
  1104 fun quick_and_dirty_prf noopt opt () =
  1050 fun quick_and_dirty_prf noopt opt () =
  1105   if ! record_quick_and_dirty_sensitive andalso ! quick_and_dirty
  1051   if ! record_quick_and_dirty_sensitive andalso ! quick_and_dirty
  1106   then noopt ()
  1052   then noopt ()
  1107   else opt ();
  1053   else opt ();
  1108 
  1054 
  1109 fun is_sel_upd_pair thy (Const (s, t)) (Const (u, t')) =
  1055 (* FIXME non-standard name for partial identity; rename to check_... (??) *)
       
  1056 fun is_sel_upd_pair thy (Const (s, _)) (Const (u, t')) =
  1110   (case get_updates thy u of
  1057   (case get_updates thy u of
  1111     SOME u_name => u_name = s
  1058     SOME u_name => u_name = s
  1112   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
  1059   | NONE => raise TERM ("is_sel_upd_pair: not update", [Const (u, t')]));
  1113 
  1060 
  1114 fun mk_comp f g =
  1061 fun mk_comp f g =
  1128   | get_upd_funs _ = [];
  1075   | get_upd_funs _ = [];
  1129 
  1076 
  1130 fun get_accupd_simps thy term defset intros_tac =
  1077 fun get_accupd_simps thy term defset intros_tac =
  1131   let
  1078   let
  1132     val (acc, [body]) = strip_comb term;
  1079     val (acc, [body]) = strip_comb term;
  1133     val recT = domain_type (fastype_of acc);
       
  1134     val upd_funs = sort_distinct TermOrd.fast_term_ord (get_upd_funs body);
  1080     val upd_funs = sort_distinct TermOrd.fast_term_ord (get_upd_funs body);
  1135     fun get_simp upd =
  1081     fun get_simp upd =
  1136       let
  1082       let
  1137         val T = domain_type (fastype_of upd);
  1083         val T = domain_type (fastype_of upd);
  1138         val lhs = mk_comp acc (upd $ Free ("f", T));
  1084         val lhs = mk_comp acc (upd $ Free ("f", T));
  1139         val rhs =
  1085         val rhs =
  1140           if is_sel_upd_pair thy acc upd
  1086           if is_sel_upd_pair thy acc upd
  1141           then mk_comp (Free ("f", T)) acc
  1087           then mk_comp (Free ("f", T)) acc
  1142           else mk_comp_id acc;
  1088           else mk_comp_id acc;
  1143         val prop = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
  1089         val prop = lhs === rhs;
  1144         val othm =
  1090         val othm =
  1145           Goal.prove (ProofContext.init thy) [] [] prop
  1091           Goal.prove (ProofContext.init thy) [] [] prop
  1146             (fn prems =>
  1092             (fn _ =>
  1147               EVERY
  1093               EVERY
  1148                [simp_tac defset 1,
  1094                [simp_tac defset 1,
  1149                 REPEAT_DETERM (intros_tac 1),
  1095                 REPEAT_DETERM (intros_tac 1),
  1150                 TRY (simp_tac (HOL_ss addsimps id_o_apps) 1)]);
  1096                 TRY (simp_tac (HOL_ss addsimps id_o_apps) 1)]);
  1151         val dest =
  1097         val dest =
  1162     val lhs = mk_comp (u $ f) (u' $ f');
  1108     val lhs = mk_comp (u $ f) (u' $ f');
  1163     val rhs =
  1109     val rhs =
  1164       if comp
  1110       if comp
  1165       then u $ mk_comp f f'
  1111       then u $ mk_comp f f'
  1166       else mk_comp (u' $ f') (u $ f);
  1112       else mk_comp (u' $ f') (u $ f);
  1167     val prop = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
  1113     val prop = lhs === rhs;
  1168     val othm =
  1114     val othm =
  1169       Goal.prove (ProofContext.init thy) [] [] prop
  1115       Goal.prove (ProofContext.init thy) [] [] prop
  1170         (fn prems =>
  1116         (fn _ =>
  1171           EVERY
  1117           EVERY
  1172            [simp_tac defset 1,
  1118            [simp_tac defset 1,
  1173             REPEAT_DETERM (intros_tac 1),
  1119             REPEAT_DETERM (intros_tac 1),
  1174             TRY (simp_tac (HOL_ss addsimps [id_apply]) 1)]);
  1120             TRY (simp_tac (HOL_ss addsimps [id_apply]) 1)]);
  1175     val dest = if comp then o_eq_dest_lhs else o_eq_dest;
  1121     val dest = if comp then o_eq_dest_lhs else o_eq_dest;
  1176   in standard (othm RS dest) end;
  1122   in standard (othm RS dest) end;
  1177 
  1123 
  1178 fun get_updupd_simps thy term defset intros_tac =
  1124 fun get_updupd_simps thy term defset intros_tac =
  1179   let
  1125   let
  1180     val recT = fastype_of term;
       
  1181     val upd_funs = get_upd_funs term;
  1126     val upd_funs = get_upd_funs term;
  1182     val cname = fst o dest_Const;
  1127     val cname = fst o dest_Const;
  1183     fun getswap u u' = get_updupd_simp thy defset intros_tac u u' (cname u = cname u');
  1128     fun getswap u u' = get_updupd_simp thy defset intros_tac u u' (cname u = cname u');
  1184     fun build_swaps_to_eq upd [] swaps = swaps
  1129     fun build_swaps_to_eq _ [] swaps = swaps
  1185       | build_swaps_to_eq upd (u :: us) swaps =
  1130       | build_swaps_to_eq upd (u :: us) swaps =
  1186           let
  1131           let
  1187             val key = (cname u, cname upd);
  1132             val key = (cname u, cname upd);
  1188             val newswaps =
  1133             val newswaps =
  1189               if Symreltab.defined swaps key then swaps
  1134               if Symreltab.defined swaps key then swaps
  1190               else Symreltab.insert (K true) (key, getswap u upd) swaps;
  1135               else Symreltab.insert (K true) (key, getswap u upd) swaps;
  1191           in
  1136           in
  1192             if cname u = cname upd then newswaps
  1137             if cname u = cname upd then newswaps
  1193             else build_swaps_to_eq upd us newswaps
  1138             else build_swaps_to_eq upd us newswaps
  1194           end;
  1139           end;
  1195     fun swaps_needed [] prev seen swaps = map snd (Symreltab.dest swaps)
  1140     fun swaps_needed [] _ _ swaps = map snd (Symreltab.dest swaps)
  1196       | swaps_needed (u :: us) prev seen swaps =
  1141       | swaps_needed (u :: us) prev seen swaps =
  1197           if Symtab.defined seen (cname u)
  1142           if Symtab.defined seen (cname u)
  1198           then swaps_needed us prev seen (build_swaps_to_eq u prev swaps)
  1143           then swaps_needed us prev seen (build_swaps_to_eq u prev swaps)
  1199           else swaps_needed us (u :: prev) (Symtab.insert (K true) (cname u, ()) seen) swaps;
  1144           else swaps_needed us (u :: prev) (Symtab.insert (K true) (cname u, ()) seen) swaps;
  1200   in swaps_needed upd_funs [] Symtab.empty Symreltab.empty end;
  1145   in swaps_needed upd_funs [] Symtab.empty Symreltab.empty end;
  1201 
  1146 
  1202 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate;
  1147 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate;
  1203 
  1148 
  1204 fun prove_unfold_defs thy ss T ex_simps ex_simprs prop =
  1149 fun prove_unfold_defs thy ex_simps ex_simprs prop =
  1205   let
  1150   let
  1206     val defset = get_sel_upd_defs thy;
  1151     val defset = get_sel_upd_defs thy;
  1207     val in_tac = IsTupleSupport.istuple_intros_tac thy;
  1152     val in_tac = IsTupleSupport.istuple_intros_tac thy;
  1208     val prop' = Envir.beta_eta_contract prop;
  1153     val prop' = Envir.beta_eta_contract prop;
  1209     val (lhs, rhs) = Logic.dest_equals (Logic.strip_assums_concl prop');
  1154     val (lhs, _) = Logic.dest_equals (Logic.strip_assums_concl prop');
  1210     val (head, args) = strip_comb lhs;
  1155     val (_, args) = strip_comb lhs;
  1211     val simps =
  1156     val simps =
  1212       if length args = 1
  1157       if length args = 1
  1213       then get_accupd_simps thy lhs defset in_tac
  1158       then get_accupd_simps thy lhs defset in_tac
  1214       else get_updupd_simps thy lhs defset in_tac;
  1159       else get_updupd_simps thy lhs defset in_tac;
  1215   in
  1160   in
  1216     Goal.prove (ProofContext.init thy) [] [] prop'
  1161     Goal.prove (ProofContext.init thy) [] [] prop'
  1217       (fn prems =>
  1162       (fn _ =>
  1218         simp_tac (HOL_basic_ss addsimps (simps @ [K_record_comp])) 1 THEN
  1163         simp_tac (HOL_basic_ss addsimps (simps @ [K_record_comp])) 1 THEN
  1219         TRY (simp_tac (HOL_basic_ss addsimps ex_simps addsimprocs ex_simprs) 1))
  1164         TRY (simp_tac (HOL_basic_ss addsimps ex_simps addsimprocs ex_simprs) 1))
  1220   end;
  1165   end;
  1221 
  1166 
  1222 
  1167 
  1249   - If X is a more-selector we have to make sure that S is not in the updated
  1194   - If X is a more-selector we have to make sure that S is not in the updated
  1250     subrecord.
  1195     subrecord.
  1251 *)
  1196 *)
  1252 val record_simproc =
  1197 val record_simproc =
  1253   Simplifier.simproc @{theory HOL} "record_simp" ["x"]
  1198   Simplifier.simproc @{theory HOL} "record_simp" ["x"]
  1254     (fn thy => fn ss => fn t =>
  1199     (fn thy => fn _ => fn t =>
  1255       (case t of
  1200       (case t of
  1256         (sel as Const (s, Type (_, [domS, rangeS]))) $
  1201         (sel as Const (s, Type (_, [_, rangeS]))) $
  1257             ((upd as Const (u, Type (_, [_, Type (_, [rT, _])]))) $ k $ r) =>
  1202             ((upd as Const (u, Type (_, [_, Type (_, [rT, _])]))) $ k $ r) =>
  1258           if is_selector thy s then
  1203           if is_selector thy s andalso is_some (get_updates thy u) then
  1259             (case get_updates thy u of
  1204             let
  1260               SOME u_name =>
  1205               val {sel_upd = {updates, ...}, extfields, ...} = RecordsData.get thy;
  1261                 let
  1206 
  1262                   val {sel_upd = {updates, ...}, extfields, ...} = RecordsData.get thy;
  1207               fun mk_eq_terms ((upd as Const (u, Type(_, [kT, _]))) $ k $ r) =
  1263 
  1208                     (case Symtab.lookup updates u of
  1264                   fun mk_eq_terms ((upd as Const (u, Type(_, [kT, _]))) $ k $ r) =
  1209                       NONE => NONE
  1265                         (case Symtab.lookup updates u of
  1210                     | SOME u_name =>
  1266                           NONE => NONE
  1211                         if u_name = s then
  1267                         | SOME u_name =>
  1212                           (case mk_eq_terms r of
  1268                             if u_name = s then
  1213                             NONE =>
  1269                               (case mk_eq_terms r of
  1214                               let
  1270                                 NONE =>
  1215                                 val rv = ("r", rT);
  1271                                   let
  1216                                 val rb = Bound 0;
  1272                                     val rv = ("r", rT);
  1217                                 val (kv, kb) = K_skeleton "k" kT (Bound 1) k;
  1273                                     val rb = Bound 0;
  1218                               in SOME (upd $ kb $ rb, kb $ (sel $ rb), [kv, rv]) end
  1274                                     val (kv, kb) = K_skeleton "k" kT (Bound 1) k;
  1219                           | SOME (trm, trm', vars) =>
  1275                                   in SOME (upd $ kb $ rb, kb $ (sel $ rb), [kv, rv]) end
  1220                               let
  1276                               | SOME (trm, trm', vars) =>
  1221                                 val (kv, kb) = K_skeleton "k" kT (Bound (length vars)) k;
  1277                                   let
  1222                               in SOME (upd $ kb $ trm, kb $ trm', kv :: vars) end)
  1278                                     val (kv, kb) = K_skeleton "k" kT (Bound (length vars)) k;
  1223                         else if has_field extfields u_name rangeS orelse
  1279                                   in SOME (upd $ kb $ trm, kb $ trm', kv :: vars) end)
  1224                           has_field extfields s (domain_type kT) then NONE
  1280                             else if has_field extfields u_name rangeS orelse
  1225                         else
  1281                               has_field extfields s (domain_type kT) then NONE
  1226                           (case mk_eq_terms r of
  1282                             else
  1227                             SOME (trm, trm', vars) =>
  1283                               (case mk_eq_terms r of
  1228                               let val (kv, kb) = K_skeleton "k" kT (Bound (length vars)) k
  1284                                 SOME (trm, trm', vars) =>
  1229                               in SOME (upd $ kb $ trm, trm', kv :: vars) end
  1285                                   let val (kv, kb) = K_skeleton "k" kT (Bound (length vars)) k
  1230                           | NONE =>
  1286                                   in SOME (upd $ kb $ trm, trm', kv :: vars) end
  1231                               let
  1287                               | NONE =>
  1232                                 val rv = ("r", rT);
  1288                                   let
  1233                                 val rb = Bound 0;
  1289                                     val rv = ("r", rT);
  1234                                 val (kv, kb) = K_skeleton "k" kT (Bound 1) k;
  1290                                     val rb = Bound 0;
  1235                               in SOME (upd $ kb $ rb, sel $ rb, [kv, rv]) end))
  1291                                     val (kv, kb) = K_skeleton "k" kT (Bound 1) k;
  1236                 | mk_eq_terms _ = NONE;
  1292                                   in SOME (upd $ kb $ rb, sel $ rb, [kv, rv]) end))
  1237             in
  1293                     | mk_eq_terms r = NONE;
  1238               (case mk_eq_terms (upd $ k $ r) of
  1294                 in
  1239                 SOME (trm, trm', vars) =>
  1295                   (case mk_eq_terms (upd $ k $ r) of
  1240                   SOME
  1296                     SOME (trm, trm', vars) =>
  1241                     (prove_unfold_defs thy [] []
  1297                       SOME
  1242                       (list_all (vars, Logic.mk_equals (sel $ trm, trm'))))
  1298                         (prove_unfold_defs thy ss domS [] []
  1243               | NONE => NONE)
  1299                           (list_all (vars, Logic.mk_equals (sel $ trm, trm'))))
  1244             end
  1300                   | NONE => NONE)
       
  1301                 end
       
  1302             | NONE => NONE)
       
  1303           else NONE
  1245           else NONE
  1304       | _ => NONE));
  1246       | _ => NONE));
  1305 
  1247 
  1306 fun get_upd_acc_cong_thm upd acc thy simpset =
  1248 fun get_upd_acc_cong_thm upd acc thy simpset =
  1307   let
  1249   let
  1309 
  1251 
  1310     val insts = [("upd", cterm_of thy upd), ("acc", cterm_of thy acc)]
  1252     val insts = [("upd", cterm_of thy upd), ("acc", cterm_of thy acc)]
  1311     val prop = concl_of (named_cterm_instantiate insts updacc_cong_triv);
  1253     val prop = concl_of (named_cterm_instantiate insts updacc_cong_triv);
  1312   in
  1254   in
  1313     Goal.prove (ProofContext.init thy) [] [] prop
  1255     Goal.prove (ProofContext.init thy) [] [] prop
  1314       (fn prems =>
  1256       (fn _ =>
  1315         EVERY
  1257         EVERY
  1316          [simp_tac simpset 1,
  1258          [simp_tac simpset 1,
  1317           REPEAT_DETERM (in_tac 1),
  1259           REPEAT_DETERM (in_tac 1),
  1318           TRY (resolve_tac [updacc_cong_idI] 1)])
  1260           TRY (resolve_tac [updacc_cong_idI] 1)])
  1319   end;
  1261   end;
  1329   In both cases "more" updates complicate matters: for this reason
  1271   In both cases "more" updates complicate matters: for this reason
  1330   we omit considering further updates if doing so would introduce
  1272   we omit considering further updates if doing so would introduce
  1331   both a more update and an update to a field within it.*)
  1273   both a more update and an update to a field within it.*)
  1332 val record_upd_simproc =
  1274 val record_upd_simproc =
  1333   Simplifier.simproc @{theory HOL} "record_upd_simp" ["x"]
  1275   Simplifier.simproc @{theory HOL} "record_upd_simp" ["x"]
  1334     (fn thy => fn ss => fn t =>
  1276     (fn thy => fn _ => fn t =>
  1335       let
  1277       let
  1336         (*We can use more-updators with other updators as long
  1278         (*We can use more-updators with other updators as long
  1337           as none of the other updators go deeper than any more
  1279           as none of the other updators go deeper than any more
  1338           updator. min here is the depth of the deepest other
  1280           updator. min here is the depth of the deepest other
  1339           updator, max the depth of the shallowest more updator.*)
  1281           updator, max the depth of the shallowest more updator.*)
  1344           | include_depth (dep, false) (min, max) =
  1286           | include_depth (dep, false) (min, max) =
  1345               if dep <= max orelse max = ~1
  1287               if dep <= max orelse max = ~1
  1346               then SOME (if min <= dep then dep else min, max)
  1288               then SOME (if min <= dep then dep else min, max)
  1347               else NONE;
  1289               else NONE;
  1348 
  1290 
  1349         fun getupdseq (term as (upd as Const (u, T)) $ f $ tm) min max =
  1291         fun getupdseq (term as (upd as Const (u, _)) $ f $ tm) min max =
  1350               (case get_update_details u thy of
  1292               (case get_update_details u thy of
  1351                 SOME (s, dep, ismore) =>
  1293                 SOME (s, dep, ismore) =>
  1352                   (case include_depth (dep, ismore) (min, max) of
  1294                   (case include_depth (dep, ismore) (min, max) of
  1353                     SOME (min', max') =>
  1295                     SOME (min', max') =>
  1354                       let val (us, bs, _) = getupdseq tm min' max'
  1296                       let val (us, bs, _) = getupdseq tm min' max'
  1357               | NONE => ([], term, HOLogic.unitT))
  1299               | NONE => ([], term, HOLogic.unitT))
  1358           | getupdseq term _ _ = ([], term, HOLogic.unitT);
  1300           | getupdseq term _ _ = ([], term, HOLogic.unitT);
  1359 
  1301 
  1360         val (upds, base, baseT) = getupdseq t 0 ~1;
  1302         val (upds, base, baseT) = getupdseq t 0 ~1;
  1361 
  1303 
  1362         fun is_upd_noop s (f as Abs (n, T, Const (s', T') $ tm')) tm =
  1304         fun is_upd_noop s (Abs (n, T, Const (s', T') $ tm')) tm =
  1363               if s = s' andalso null (loose_bnos tm')
  1305               if s = s' andalso null (loose_bnos tm')
  1364                 andalso subst_bound (HOLogic.unit, tm') = tm
  1306                 andalso subst_bound (HOLogic.unit, tm') = tm
  1365               then (true, Abs (n, T, Const (s', T') $ Bound 1))
  1307               then (true, Abs (n, T, Const (s', T') $ Bound 1))
  1366               else (false, HOLogic.unit)
  1308               else (false, HOLogic.unit)
  1367           | is_upd_noop s f tm = (false, HOLogic.unit);
  1309           | is_upd_noop _ _ _ = (false, HOLogic.unit);
  1368 
  1310 
  1369         fun get_noop_simps (upd as Const (u, T))
  1311         fun get_noop_simps (upd as Const _) (Abs (_, _, (acc as Const _) $ _)) =
  1370             (f as Abs (n, T', (acc as Const (s, T'')) $ _)) =
       
  1371           let
  1312           let
  1372             val ss = get_sel_upd_defs thy;
  1313             val ss = get_sel_upd_defs thy;
  1373             val uathm = get_upd_acc_cong_thm upd acc thy ss;
  1314             val uathm = get_upd_acc_cong_thm upd acc thy ss;
  1374           in
  1315           in
  1375             [standard (uathm RS updacc_noopE), standard (uathm RS updacc_noop_compE)]
  1316             [standard (uathm RS updacc_noopE), standard (uathm RS updacc_noop_compE)]
  1415                      (upd $ skelf $ lhs,
  1356                      (upd $ skelf $ lhs,
  1416                       upd $ foldr1 mk_comp_local (add_upd skelf fs) $ rhs,
  1357                       upd $ foldr1 mk_comp_local (add_upd skelf fs) $ rhs,
  1417                       fvar :: vars, dups, true, noops)
  1358                       fvar :: vars, dups, true, noops)
  1418                   | NONE => (upd $ skelf $ lhs, upd $ skelf $ rhs, fvar :: vars, dups, simp, noops))
  1359                   | NONE => (upd $ skelf $ lhs, upd $ skelf $ rhs, fvar :: vars, dups, simp, noops))
  1419               end
  1360               end
  1420           | mk_updterm [] above term =
  1361           | mk_updterm [] _ _ =
  1421               (Bound 0, Bound 0, [("r", baseT)], Symtab.empty, false, Symtab.empty)
  1362               (Bound 0, Bound 0, [("r", baseT)], Symtab.empty, false, Symtab.empty)
  1422           | mk_updterm us above term =
  1363           | mk_updterm us _ _ = raise TERM ("mk_updterm match", map (fn (x, _, _) => x) us);
  1423               raise TERM ("mk_updterm match", map (fn (x, y, z) => x) us);
  1364 
  1424 
  1365         val (lhs, rhs, vars, _, simp, noops) = mk_updterm upds Symtab.empty base;
  1425         val (lhs, rhs, vars, dups, simp, noops) = mk_updterm upds Symtab.empty base;
       
  1426         val noops' = flat (map snd (Symtab.dest noops));
  1366         val noops' = flat (map snd (Symtab.dest noops));
  1427       in
  1367       in
  1428         if simp then
  1368         if simp then
  1429           SOME
  1369           SOME
  1430             (prove_unfold_defs thy ss baseT noops' [record_simproc]
  1370             (prove_unfold_defs thy noops' [record_simproc]
  1431               (list_all (vars, Logic.mk_equals (lhs, rhs))))
  1371               (list_all (vars, Logic.mk_equals (lhs, rhs))))
  1432         else NONE
  1372         else NONE
  1433       end);
  1373       end);
  1434 
  1374 
  1435 end;
  1375 end;
  1471     P t > 0: split up to given bound of record extensions.*)
  1411     P t > 0: split up to given bound of record extensions.*)
  1472 fun record_split_simproc P =
  1412 fun record_split_simproc P =
  1473   Simplifier.simproc @{theory HOL} "record_split_simp" ["x"]
  1413   Simplifier.simproc @{theory HOL} "record_split_simp" ["x"]
  1474     (fn thy => fn _ => fn t =>
  1414     (fn thy => fn _ => fn t =>
  1475       (case t of
  1415       (case t of
  1476         Const (quantifier, Type (_, [Type (_, [T, _]), _])) $ trm =>
  1416         Const (quantifier, Type (_, [Type (_, [T, _]), _])) $ _ =>
  1477           if quantifier = "All" orelse quantifier = "all" orelse quantifier = "Ex" then
  1417           if quantifier = "All" orelse quantifier = "all" orelse quantifier = "Ex" then
  1478             (case rec_id ~1 T of
  1418             (case rec_id ~1 T of
  1479               "" => NONE
  1419               "" => NONE
  1480             | name =>
  1420             | _ =>
  1481                 let val split = P t in
  1421                 let val split = P t in
  1482                   if split <> 0 then
  1422                   if split <> 0 then
  1483                     (case get_splits thy (rec_id split T) of
  1423                     (case get_splits thy (rec_id split T) of
  1484                       NONE => NONE
  1424                       NONE => NONE
  1485                     | SOME (all_thm, All_thm, Ex_thm, _) =>
  1425                     | SOME (all_thm, All_thm, Ex_thm, _) =>
  1566          [simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i,
  1506          [simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i,
  1567           rtac thm i,
  1507           rtac thm i,
  1568           simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i]
  1508           simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i]
  1569       end;
  1509       end;
  1570 
  1510 
  1571     fun split_free_tac P i (free as Free (n, T)) =
  1511     fun split_free_tac P i (free as Free (_, T)) =
  1572           (case rec_id ~1 T of
  1512           (case rec_id ~1 T of
  1573             "" => NONE
  1513             "" => NONE
  1574           | name =>
  1514           | _ =>
  1575               let val split = P free in
  1515               let val split = P free in
  1576                 if split <> 0 then
  1516                 if split <> 0 then
  1577                   (case get_splits thy (rec_id split T) of
  1517                   (case get_splits thy (rec_id split T) of
  1578                     NONE => NONE
  1518                     NONE => NONE
  1579                   | SOME (_, _, _, induct_thm) =>
  1519                   | SOME (_, _, _, induct_thm) =>
  1596 (* record_split_tac *)
  1536 (* record_split_tac *)
  1597 
  1537 
  1598 (*Split all records in the goal, which are quantified by ! or !!.*)
  1538 (*Split all records in the goal, which are quantified by ! or !!.*)
  1599 fun record_split_tac i st =
  1539 fun record_split_tac i st =
  1600   let
  1540   let
  1601     val thy = Thm.theory_of_thm st;
       
  1602 
       
  1603     val has_rec = exists_Const
  1541     val has_rec = exists_Const
  1604       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1542       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1605           (s = "all" orelse s = "All") andalso is_recT T
  1543           (s = "all" orelse s = "All") andalso is_recT T
  1606         | _ => false);
  1544         | _ => false);
  1607 
  1545 
  1693           [(P, list_abs (params, if ca then concl else incr_boundvars 1 (Abs (s, T, concl)))),
  1631           [(P, list_abs (params, if ca then concl else incr_boundvars 1 (Abs (s, T, concl)))),
  1694             (x, list_abs (params, Bound 0))])) rule';
  1632             (x, list_abs (params, Bound 0))])) rule';
  1695   in compose_tac (false, rule'', nprems_of rule) i st end;
  1633   in compose_tac (false, rule'', nprems_of rule) i st end;
  1696 
  1634 
  1697 
  1635 
  1698 (*!!x1 ... xn. ... ==> EX x1 ... xn. P x1 ... xn;
  1636 fun extension_definition name fields alphas zeta moreT more vars thy =
  1699   instantiates x1 ... xn with parameters x1 ... xn*)
       
  1700 fun ex_inst_tac i st =
       
  1701   let
       
  1702     val thy = Thm.theory_of_thm st;
       
  1703     val g = nth (prems_of st) (i - 1);   (* FIXME SUBGOAL *)
       
  1704     val params = Logic.strip_params g;
       
  1705     val exI' = Thm.lift_rule (Thm.cprem_of st i) exI;
       
  1706     val _ $ (_ $ x) = Logic.strip_assums_concl (hd (prems_of exI'));
       
  1707     val cx = cterm_of thy (fst (strip_comb x));
       
  1708   in
       
  1709     Seq.single (Library.foldl (fn (st, v) =>
       
  1710       Seq.hd
       
  1711         (compose_tac
       
  1712           (false,
       
  1713             cterm_instantiate [(cx, cterm_of thy (list_abs (params, Bound v)))] exI', 1) i st))
       
  1714         (st, (length params - 1) downto 0))
       
  1715   end;
       
  1716 
       
  1717 fun extension_definition full name fields names alphas zeta moreT more vars thy =
       
  1718   let
  1637   let
  1719     val base = Long_Name.base_name;
  1638     val base = Long_Name.base_name;
  1720     val fieldTs = (map snd fields);
  1639     val fieldTs = (map snd fields);
  1721     val alphas_zeta = alphas @ [zeta];
  1640     val alphas_zeta = alphas @ [zeta];
  1722     val alphas_zetaTs = map (fn n => TFree (n, HOLogic.typeS)) alphas_zeta;
  1641     val alphas_zetaTs = map (fn n => TFree (n, HOLogic.typeS)) alphas_zeta;
  1723     val vT = TFree (Name.variant alphas_zeta "'v", HOLogic.typeS);
       
  1724     val extT_name = suffix ext_typeN name
  1642     val extT_name = suffix ext_typeN name
  1725     val extT = Type (extT_name, alphas_zetaTs);
  1643     val extT = Type (extT_name, alphas_zetaTs);
  1726     val fields_more = fields @ [(full moreN, moreT)];
       
  1727     val fields_moreTs = fieldTs @ [moreT];
  1644     val fields_moreTs = fieldTs @ [moreT];
  1728     val bfields_more = map (apfst base) fields_more;
  1645 
  1729     val r = Free (rN, extT);
       
  1730     val len = length fields;
       
  1731     val idxms = 0 upto len;
       
  1732 
  1646 
  1733     (*before doing anything else, create the tree of new types
  1647     (*before doing anything else, create the tree of new types
  1734       that will back the record extension*)
  1648       that will back the record extension*)
  1735 
  1649 
  1736     val mktreeV = Balanced_Tree.make IsTupleSupport.mk_cons_tuple;
  1650     val mktreeV = Balanced_Tree.make IsTupleSupport.mk_cons_tuple;
  1737 
  1651 
  1738     fun mk_istuple (left, right) (thy, i) =
  1652     fun mk_istuple (left, right) (thy, i) =
  1739       let
  1653       let
  1740         val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i;
  1654         val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i;
  1741         val nm = suffix suff (Long_Name.base_name name);
  1655         val nm = suffix suff (Long_Name.base_name name);
  1742         val (isom, cons, thy') =
  1656         val (_, cons, thy') =
  1743           IsTupleSupport.add_istuple_type
  1657           IsTupleSupport.add_istuple_type
  1744             (nm, alphas_zeta) (fastype_of left, fastype_of right) thy;
  1658             (nm, alphas_zeta) (fastype_of left, fastype_of right) thy;
  1745       in
  1659       in
  1746         (cons $ left $ right, (thy', i + 1))
  1660         (cons $ left $ right, (thy', i + 1))
  1747       end;
  1661       end;
  1761             val (composites, (thy', i')) = fold_map mk_even_istuple vars' (thy, i);
  1675             val (composites, (thy', i')) = fold_map mk_even_istuple vars' (thy, i);
  1762           in
  1676           in
  1763             build_meta_tree_type i' thy' composites more
  1677             build_meta_tree_type i' thy' composites more
  1764           end
  1678           end
  1765         else
  1679         else
  1766           let val (term, (thy', i')) = mk_istuple (mktreeV vars, more) (thy, 0)
  1680           let val (term, (thy', _)) = mk_istuple (mktreeV vars, more) (thy, 0)
  1767           in (term, thy') end
  1681           in (term, thy') end
  1768       end;
  1682       end;
  1769 
  1683 
  1770     val _ = timing_msg "record extension preparing definitions";
  1684     val _ = timing_msg "record extension preparing definitions";
  1771 
  1685 
  1793       |> Sign.add_consts_i [Syntax.no_syn (apfst (Binding.name o base) ext_decl)]
  1707       |> Sign.add_consts_i [Syntax.no_syn (apfst (Binding.name o base) ext_decl)]
  1794       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name ext_spec)]
  1708       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name ext_spec)]
  1795     val ([ext_def], defs_thy) =
  1709     val ([ext_def], defs_thy) =
  1796       timeit_msg "record extension constructor def:" mk_defs;
  1710       timeit_msg "record extension constructor def:" mk_defs;
  1797 
  1711 
       
  1712 
  1798     (* prepare propositions *)
  1713     (* prepare propositions *)
       
  1714 
  1799     val _ = timing_msg "record extension preparing propositions";
  1715     val _ = timing_msg "record extension preparing propositions";
  1800     val vars_more = vars @ [more];
  1716     val vars_more = vars @ [more];
  1801     val named_vars_more = (names @ [full moreN]) ~~ vars_more;
       
  1802     val variants = map (fn Free (x, _) => x) vars_more;
  1717     val variants = map (fn Free (x, _) => x) vars_more;
  1803     val ext = mk_ext vars_more;
  1718     val ext = mk_ext vars_more;
  1804     val s = Free (rN, extT);
  1719     val s = Free (rN, extT);
  1805     val w = Free (wN, extT);
       
  1806     val P = Free (Name.variant variants "P", extT --> HOLogic.boolT);
  1720     val P = Free (Name.variant variants "P", extT --> HOLogic.boolT);
  1807     val C = Free (Name.variant variants "C", HOLogic.boolT);
       
  1808     val intros_tac = IsTupleSupport.istuple_intros_tac defs_thy;
  1721     val intros_tac = IsTupleSupport.istuple_intros_tac defs_thy;
  1809 
  1722 
  1810     val inject_prop =
  1723     val inject_prop =
  1811       let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in
  1724       let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in
  1812         HOLogic.mk_conj (HOLogic.eq_const extT $
  1725         HOLogic.mk_conj (HOLogic.eq_const extT $
  1817       end;
  1730       end;
  1818 
  1731 
  1819     val induct_prop =
  1732     val induct_prop =
  1820       (All (map dest_Free vars_more) (Trueprop (P $ ext)), Trueprop (P $ s));
  1733       (All (map dest_Free vars_more) (Trueprop (P $ ext)), Trueprop (P $ s));
  1821 
  1734 
  1822     val cases_prop =
       
  1823       All (map dest_Free vars_more)
       
  1824         (Trueprop (HOLogic.mk_eq (s, ext)) ==> Trueprop C)
       
  1825       ==> Trueprop C;
       
  1826 
       
  1827     val split_meta_prop =
  1735     val split_meta_prop =
  1828       let val P = Free (Name.variant variants "P", extT-->Term.propT) in
  1736       let val P = Free (Name.variant variants "P", extT --> Term.propT) in
  1829         Logic.mk_equals
  1737         Logic.mk_equals
  1830          (All [dest_Free s] (P $ s), All (map dest_Free vars_more) (P $ ext))
  1738          (All [dest_Free s] (P $ s), All (map dest_Free vars_more) (P $ ext))
  1831       end;
  1739       end;
  1832 
  1740 
  1833     fun prove stndrd = quick_and_dirty_prove stndrd defs_thy;
       
  1834     val prove_standard = quick_and_dirty_prove true defs_thy;
  1741     val prove_standard = quick_and_dirty_prove true defs_thy;
  1835     fun prove_simp stndrd simps =
       
  1836       let val tac = simp_all_tac HOL_ss simps
       
  1837       in fn prop => prove stndrd [] prop (K tac) end;
       
  1838 
  1742 
  1839     fun inject_prf () =
  1743     fun inject_prf () =
  1840       simplify HOL_ss
  1744       simplify HOL_ss
  1841         (prove_standard [] inject_prop
  1745         (prove_standard [] inject_prop
  1842           (fn prems =>
  1746           (fn _ =>
  1843             EVERY
  1747             EVERY
  1844              [simp_tac (HOL_basic_ss addsimps [ext_def]) 1,
  1748              [simp_tac (HOL_basic_ss addsimps [ext_def]) 1,
  1845               REPEAT_DETERM (resolve_tac [refl_conj_eq] 1 ORELSE
  1749               REPEAT_DETERM (resolve_tac [refl_conj_eq] 1 ORELSE
  1846                 intros_tac 1 ORELSE
  1750                 intros_tac 1 ORELSE
  1847                 resolve_tac [refl] 1)]));
  1751                 resolve_tac [refl] 1)]));
  1870       end;
  1774       end;
  1871     val surject = timeit_msg "record extension surjective proof:" surject_prf;
  1775     val surject = timeit_msg "record extension surjective proof:" surject_prf;
  1872 
  1776 
  1873     fun split_meta_prf () =
  1777     fun split_meta_prf () =
  1874       prove_standard [] split_meta_prop
  1778       prove_standard [] split_meta_prop
  1875         (fn prems =>
  1779         (fn _ =>
  1876           EVERY
  1780           EVERY
  1877            [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1,
  1781            [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1,
  1878             etac meta_allE 1, atac 1,
  1782             etac meta_allE 1, atac 1,
  1879             rtac (prop_subst OF [surject]) 1,
  1783             rtac (prop_subst OF [surject]) 1,
  1880             REPEAT (etac meta_allE 1), atac 1]);
  1784             REPEAT (etac meta_allE 1), atac 1]);
  1907 
  1811 
  1908 fun chop_last [] = error "chop_last: list should not be empty"
  1812 fun chop_last [] = error "chop_last: list should not be empty"
  1909   | chop_last [x] = ([], x)
  1813   | chop_last [x] = ([], x)
  1910   | chop_last (x :: xs) = let val (tl, l) = chop_last xs in (x :: tl, l) end;
  1814   | chop_last (x :: xs) = let val (tl, l) = chop_last xs in (x :: tl, l) end;
  1911 
  1815 
  1912 fun subst_last s [] = error "subst_last: list should not be empty"
  1816 fun subst_last _ [] = error "subst_last: list should not be empty"
  1913   | subst_last s [x] = [s]
  1817   | subst_last s [_] = [s]
  1914   | subst_last s (x :: xs) = x :: subst_last s xs;
  1818   | subst_last s (x :: xs) = x :: subst_last s xs;
  1915 
  1819 
  1916 
  1820 
  1917 (* mk_recordT *)
  1821 (* mk_recordT *)
  1918 
  1822 
  1963     val parent_types = map snd parent_fields;
  1867     val parent_types = map snd parent_fields;
  1964     val parent_fields_len = length parent_fields;
  1868     val parent_fields_len = length parent_fields;
  1965     val parent_variants = Name.variant_list [moreN, rN, rN ^ "'", wN] (map base parent_names);
  1869     val parent_variants = Name.variant_list [moreN, rN, rN ^ "'", wN] (map base parent_names);
  1966     val parent_vars = ListPair.map Free (parent_variants, parent_types);
  1870     val parent_vars = ListPair.map Free (parent_variants, parent_types);
  1967     val parent_len = length parents;
  1871     val parent_len = length parents;
  1968     val parents_idx = (map #name parents) ~~ (0 upto (parent_len - 1));
       
  1969 
  1872 
  1970     val fields = map (apfst full) bfields;
  1873     val fields = map (apfst full) bfields;
  1971     val names = map fst fields;
  1874     val names = map fst fields;
  1972     val extN = full bname;
  1875     val extN = full bname;
  1973     val types = map snd fields;
  1876     val types = map snd fields;
  1977     val variants =
  1880     val variants =
  1978       Name.variant_list (moreN :: rN :: (rN ^ "'") :: wN :: parent_variants)
  1881       Name.variant_list (moreN :: rN :: (rN ^ "'") :: wN :: parent_variants)
  1979         (map fst bfields);
  1882         (map fst bfields);
  1980     val vars = ListPair.map Free (variants, types);
  1883     val vars = ListPair.map Free (variants, types);
  1981     val named_vars = names ~~ vars;
  1884     val named_vars = names ~~ vars;
  1982     val idxs = 0 upto (len - 1);
       
  1983     val idxms = 0 upto len;
  1885     val idxms = 0 upto len;
  1984 
  1886 
  1985     val all_fields = parent_fields @ fields;
  1887     val all_fields = parent_fields @ fields;
  1986     val all_names = parent_names @ names;
       
  1987     val all_types = parent_types @ types;
  1888     val all_types = parent_types @ types;
  1988     val all_len = parent_fields_len + len;
       
  1989     val all_variants = parent_variants @ variants;
  1889     val all_variants = parent_variants @ variants;
  1990     val all_vars = parent_vars @ vars;
  1890     val all_vars = parent_vars @ vars;
  1991     val all_named_vars = (parent_names ~~ parent_vars) @ named_vars;
  1891     val all_named_vars = (parent_names ~~ parent_vars) @ named_vars;
  1992 
  1892 
  1993 
  1893 
  1995     val moreT = TFree (zeta, HOLogic.typeS);
  1895     val moreT = TFree (zeta, HOLogic.typeS);
  1996     val more = Free (moreN, moreT);
  1896     val more = Free (moreN, moreT);
  1997     val full_moreN = full moreN;
  1897     val full_moreN = full moreN;
  1998     val bfields_more = bfields @ [(moreN, moreT)];
  1898     val bfields_more = bfields @ [(moreN, moreT)];
  1999     val fields_more = fields @ [(full_moreN, moreT)];
  1899     val fields_more = fields @ [(full_moreN, moreT)];
  2000     val vars_more = vars @ [more];
       
  2001     val named_vars_more = named_vars @ [(full_moreN, more)];
  1900     val named_vars_more = named_vars @ [(full_moreN, more)];
  2002     val all_vars_more = all_vars @ [more];
  1901     val all_vars_more = all_vars @ [more];
  2003     val all_named_vars_more = all_named_vars @ [(full_moreN, more)];
  1902     val all_named_vars_more = all_named_vars @ [(full_moreN, more)];
  2004 
  1903 
  2005 
  1904 
  2006     (* 1st stage: extension_thy *)
  1905     (* 1st stage: extension_thy *)
  2007 
  1906 
  2008     val (extension_thy, extT, ext_induct, ext_inject, ext_split, ext_def) =
  1907     val (extension_thy, extT, ext_induct, ext_inject, ext_split, ext_def) =
  2009       thy
  1908       thy
  2010       |> Sign.add_path bname
  1909       |> Sign.add_path bname
  2011       |> extension_definition full extN fields names alphas_ext zeta moreT more vars;
  1910       |> extension_definition extN fields alphas_ext zeta moreT more vars;
  2012 
  1911 
  2013     val _ = timing_msg "record preparing definitions";
  1912     val _ = timing_msg "record preparing definitions";
  2014     val Type extension_scheme = extT;
  1913     val Type extension_scheme = extT;
  2015     val extension_name = unsuffix ext_typeN (fst extension_scheme);
  1914     val extension_name = unsuffix ext_typeN (fst extension_scheme);
  2016     val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end;
  1915     val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end;
  2077     val fields_decl = (fields_selN, types ---> Type extension);
  1976     val fields_decl = (fields_selN, types ---> Type extension);
  2078     val extend_decl = (extendN, recT0 --> moreT --> rec_schemeT0);
  1977     val extend_decl = (extendN, recT0 --> moreT --> rec_schemeT0);
  2079     val truncate_decl = (truncateN, rec_schemeT0 --> recT0);
  1978     val truncate_decl = (truncateN, rec_schemeT0 --> recT0);
  2080 
  1979 
  2081     (* prepare definitions *)
  1980     (* prepare definitions *)
  2082 
       
  2083     fun parent_more s =
       
  2084       if null parents then s
       
  2085       else mk_sel s (Long_Name.qualify (#name (List.last parents)) moreN, extT);
       
  2086 
       
  2087     fun parent_more_upd v s =
       
  2088       if null parents then v $ s
       
  2089       else
       
  2090         let val mp = Long_Name.qualify (#name (List.last parents)) moreN;
       
  2091         in mk_upd updateN mp v s end;
       
  2092 
  1981 
  2093     (*record (scheme) type abbreviation*)
  1982     (*record (scheme) type abbreviation*)
  2094     val recordT_specs =
  1983     val recordT_specs =
  2095       [(Binding.name (suffix schemeN bname), alphas @ [zeta], rec_schemeT0, Syntax.NoSyn),
  1984       [(Binding.name (suffix schemeN bname), alphas @ [zeta], rec_schemeT0, Syntax.NoSyn),
  2096         (Binding.name bname, alphas, recT0, Syntax.NoSyn)];
  1985         (Binding.name bname, alphas, recT0, Syntax.NoSyn)];
  2231       let val args = map (fn (c, Free (_, T)) => mk_sel r0 (c, T)) all_named_vars_more
  2120       let val args = map (fn (c, Free (_, T)) => mk_sel r0 (c, T)) all_named_vars_more
  2232       in r0 === mk_rec args 0 end;
  2121       in r0 === mk_rec args 0 end;
  2233 
  2122 
  2234     (*cases*)
  2123     (*cases*)
  2235     val cases_scheme_prop =
  2124     val cases_scheme_prop =
  2236       (All (map dest_Free all_vars_more)
  2125       (All (map dest_Free all_vars_more) (r0 === r_rec0 ==> Trueprop C))
  2237         (Trueprop (HOLogic.mk_eq (r0, r_rec0)) ==> Trueprop C))
  2126         ==> Trueprop C;
  2238       ==> Trueprop C;
       
  2239 
  2127 
  2240     val cases_prop =
  2128     val cases_prop =
  2241       (All (map dest_Free all_vars)
  2129       (All (map dest_Free all_vars) (r_unit0 === r_rec_unit0 ==> Trueprop C))
  2242         (Trueprop (HOLogic.mk_eq (r_unit0, r_rec_unit0)) ==> Trueprop C))
  2130          ==> Trueprop C;
  2243        ==> Trueprop C;
       
  2244 
  2131 
  2245     (*split*)
  2132     (*split*)
  2246     val split_meta_prop =
  2133     val split_meta_prop =
  2247       let val P = Free (Name.variant all_variants "P", rec_schemeT0-->Term.propT) in
  2134       let val P = Free (Name.variant all_variants "P", rec_schemeT0-->Term.propT) in
  2248         Logic.mk_equals
  2135         Logic.mk_equals
  2357       let
  2244       let
  2358         val leaf_ss = get_sel_upd_defs defs_thy addsimps (sel_defs @ (o_assoc :: id_o_apps));
  2245         val leaf_ss = get_sel_upd_defs defs_thy addsimps (sel_defs @ (o_assoc :: id_o_apps));
  2359         val init_ss = HOL_basic_ss addsimps ext_defs;
  2246         val init_ss = HOL_basic_ss addsimps ext_defs;
  2360       in
  2247       in
  2361         prove_standard [] surjective_prop
  2248         prove_standard [] surjective_prop
  2362           (fn prems =>
  2249           (fn _ =>
  2363             EVERY
  2250             EVERY
  2364              [rtac surject_assist_idE 1,
  2251              [rtac surject_assist_idE 1,
  2365               simp_tac init_ss 1,
  2252               simp_tac init_ss 1,
  2366               REPEAT (intros_tac 1 ORELSE (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))])
  2253               REPEAT (intros_tac 1 ORELSE (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))])
  2367       end;
  2254       end;
  2368     val surjective = timeit_msg "record surjective proof:" surjective_prf;
  2255     val surjective = timeit_msg "record surjective proof:" surjective_prf;
  2369 
  2256 
  2370     fun split_meta_prf () =
  2257     fun split_meta_prf () =
  2371       prove false [] split_meta_prop
  2258       prove false [] split_meta_prop
  2372         (fn prems =>
  2259         (fn _ =>
  2373           EVERY
  2260           EVERY
  2374            [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1,
  2261            [rtac equal_intr_rule 1, Goal.norm_hhf_tac 1,
  2375             etac meta_allE 1, atac 1,
  2262             etac meta_allE 1, atac 1,
  2376             rtac (prop_subst OF [surjective]) 1,
  2263             rtac (prop_subst OF [surjective]) 1,
  2377             REPEAT (etac meta_allE 1), atac 1]);
  2264             REPEAT (etac meta_allE 1), atac 1]);
  2421         val P_nm = fst (dest_Free P);
  2308         val P_nm = fst (dest_Free P);
  2422         val not_P = cterm_of defs_thy (lambda r0 (HOLogic.mk_not (P $ r0)));
  2309         val not_P = cterm_of defs_thy (lambda r0 (HOLogic.mk_not (P $ r0)));
  2423         val so' = named_cterm_instantiate ([(P_nm, not_P)]) split_object;
  2310         val so' = named_cterm_instantiate ([(P_nm, not_P)]) split_object;
  2424         val so'' = simplify ss so';
  2311         val so'' = simplify ss so';
  2425       in
  2312       in
  2426         prove_standard [] split_ex_prop (fn prems => resolve_tac [so''] 1)
  2313         prove_standard [] split_ex_prop (fn _ => resolve_tac [so''] 1)
  2427       end;
  2314       end;
  2428     val split_ex = timeit_msg "record split_ex proof:" split_ex_prf;
  2315     val split_ex = timeit_msg "record split_ex proof:" split_ex_prf;
  2429 
  2316 
  2430     fun equality_tac thms =
  2317     fun equality_tac thms =
  2431       let
  2318       let