27 val record_quick_and_dirty_sensitive: bool ref |
27 val record_quick_and_dirty_sensitive: bool ref |
28 val updateN: string |
28 val updateN: string |
29 val ext_typeN: string |
29 val ext_typeN: string |
30 val last_extT: typ -> (string * typ list) option |
30 val last_extT: typ -> (string * typ list) option |
31 val dest_recTs : typ -> (string * typ list) list |
31 val dest_recTs : typ -> (string * typ list) list |
32 val get_extT_fields: Sign.sg -> typ -> ((string * typ) list * (string * typ)) |
32 val get_extT_fields: theory -> typ -> ((string * typ) list * (string * typ)) |
33 val get_recT_fields: Sign.sg -> typ -> ((string * typ) list * (string * typ)) |
33 val get_recT_fields: theory -> typ -> ((string * typ) list * (string * typ)) |
34 val get_extension: Sign.sg -> Symtab.key -> (string * typ list) option |
34 val get_extension: theory -> Symtab.key -> (string * typ list) option |
35 val get_extinjects: Sign.sg -> thm list |
35 val get_extinjects: theory -> thm list |
36 val get_simpset: Sign.sg -> simpset |
36 val get_simpset: theory -> simpset |
37 val print_records: theory -> unit |
37 val print_records: theory -> unit |
38 val add_record: string list * string -> string option -> (string * string * mixfix) list |
38 val add_record: string list * string -> string option -> (string * string * mixfix) list |
39 -> theory -> theory |
39 -> theory -> theory |
40 val add_record_i: string list * string -> (typ list * string) option |
40 val add_record_i: string list * string -> (typ list * string) option |
41 -> (string * typ * mixfix) list -> theory -> theory |
41 -> (string * typ * mixfix) list -> theory -> theory |
42 val setup: (theory -> theory) list |
42 val setup: (theory -> theory) list |
43 end; |
43 end; |
44 |
44 |
45 |
45 |
46 structure RecordPackage:RECORD_PACKAGE = |
46 structure RecordPackage:RECORD_PACKAGE = |
233 records sel_upd equalities extinjects extsplit splits extfields fieldext = |
233 records sel_upd equalities extinjects extsplit splits extfields fieldext = |
234 {records = records, sel_upd = sel_upd, |
234 {records = records, sel_upd = sel_upd, |
235 equalities = equalities, extinjects=extinjects, extsplit = extsplit, splits = splits, |
235 equalities = equalities, extinjects=extinjects, extsplit = extsplit, splits = splits, |
236 extfields = extfields, fieldext = fieldext }: record_data; |
236 extfields = extfields, fieldext = fieldext }: record_data; |
237 |
237 |
238 structure RecordsArgs = |
238 structure RecordsData = TheoryDataFun |
239 struct |
239 (struct |
240 val name = "HOL/records"; |
240 val name = "HOL/records"; |
241 type T = record_data; |
241 type T = record_data; |
242 |
242 |
243 val empty = |
243 val empty = |
244 make_record_data Symtab.empty |
244 make_record_data Symtab.empty |
245 {selectors = Symtab.empty, updates = Symtab.empty, simpset = HOL_basic_ss} |
245 {selectors = Symtab.empty, updates = Symtab.empty, simpset = HOL_basic_ss} |
246 Symtab.empty [] Symtab.empty Symtab.empty Symtab.empty Symtab.empty; |
246 Symtab.empty [] Symtab.empty Symtab.empty Symtab.empty Symtab.empty; |
247 |
247 |
248 val copy = I; |
248 val copy = I; |
249 val prep_ext = I; |
249 val extend = I; |
250 fun merge |
250 fun merge _ |
251 ({records = recs1, |
251 ({records = recs1, |
252 sel_upd = {selectors = sels1, updates = upds1, simpset = ss1}, |
252 sel_upd = {selectors = sels1, updates = upds1, simpset = ss1}, |
253 equalities = equalities1, |
253 equalities = equalities1, |
254 extinjects = extinjects1, |
254 extinjects = extinjects1, |
255 extsplit = extsplit1, |
255 extsplit = extsplit1, |
294 fun pretty_record (name, {args, parent, fields, ...}: record_info) = |
294 fun pretty_record (name, {args, parent, fields, ...}: record_info) = |
295 Pretty.block (Pretty.fbreaks (Pretty.block |
295 Pretty.block (Pretty.fbreaks (Pretty.block |
296 [prt_typ (Type (name, map TFree args)), Pretty.str " = "] :: |
296 [prt_typ (Type (name, map TFree args)), Pretty.str " = "] :: |
297 pretty_parent parent @ map pretty_field fields)); |
297 pretty_parent parent @ map pretty_field fields)); |
298 in map pretty_record (Symtab.dest recs) |> Pretty.chunks |> Pretty.writeln end; |
298 in map pretty_record (Symtab.dest recs) |> Pretty.chunks |> Pretty.writeln end; |
299 end; |
299 end); |
300 |
300 |
301 structure RecordsData = TheoryDataFun(RecordsArgs); |
|
302 val print_records = RecordsData.print; |
301 val print_records = RecordsData.print; |
|
302 |
303 |
303 |
304 (* access 'records' *) |
304 (* access 'records' *) |
305 |
305 |
306 fun get_record thy name = Symtab.lookup (#records (RecordsData.get thy), name); |
306 fun get_record thy name = Symtab.lookup (#records (RecordsData.get thy), name); |
307 |
307 |
313 sel_upd equalities extinjects extsplit splits extfields fieldext; |
313 sel_upd equalities extinjects extsplit splits extfields fieldext; |
314 in RecordsData.put data thy end; |
314 in RecordsData.put data thy end; |
315 |
315 |
316 (* access 'sel_upd' *) |
316 (* access 'sel_upd' *) |
317 |
317 |
318 fun get_sel_upd sg = #sel_upd (RecordsData.get_sg sg); |
318 val get_sel_upd = #sel_upd o RecordsData.get; |
319 |
319 |
320 fun get_selectors sg name = Symtab.lookup (#selectors (get_sel_upd sg), name); |
320 fun get_selectors sg name = Symtab.lookup (#selectors (get_sel_upd sg), name); |
321 fun is_selector sg name = |
321 fun is_selector sg name = |
322 case get_selectors sg (Sign.intern_const sg name) of |
322 case get_selectors sg (Sign.intern_const sg name) of |
323 NONE => false |
323 NONE => false |
351 (Symtab.update_new ((name, thm), equalities)) extinjects extsplit |
351 (Symtab.update_new ((name, thm), equalities)) extinjects extsplit |
352 splits extfields fieldext; |
352 splits extfields fieldext; |
353 in RecordsData.put data thy end; |
353 in RecordsData.put data thy end; |
354 |
354 |
355 fun get_equalities sg name = |
355 fun get_equalities sg name = |
356 Symtab.lookup (#equalities (RecordsData.get_sg sg), name); |
356 Symtab.lookup (#equalities (RecordsData.get sg), name); |
357 |
357 |
358 (* access 'extinjects' *) |
358 (* access 'extinjects' *) |
359 |
359 |
360 fun add_extinjects thm thy = |
360 fun add_extinjects thm thy = |
361 let |
361 let |
363 RecordsData.get thy; |
363 RecordsData.get thy; |
364 val data = make_record_data records sel_upd equalities (extinjects@[thm]) extsplit |
364 val data = make_record_data records sel_upd equalities (extinjects@[thm]) extsplit |
365 splits extfields fieldext; |
365 splits extfields fieldext; |
366 in RecordsData.put data thy end; |
366 in RecordsData.put data thy end; |
367 |
367 |
368 fun get_extinjects sg = #extinjects (RecordsData.get_sg sg); |
368 fun get_extinjects sg = #extinjects (RecordsData.get sg); |
369 |
369 |
370 (* access 'extsplit' *) |
370 (* access 'extsplit' *) |
371 |
371 |
372 fun add_extsplit name thm thy = |
372 fun add_extsplit name thm thy = |
373 let |
373 let |
377 equalities extinjects (Symtab.update_new ((name, thm), extsplit)) splits |
377 equalities extinjects (Symtab.update_new ((name, thm), extsplit)) splits |
378 extfields fieldext; |
378 extfields fieldext; |
379 in RecordsData.put data thy end; |
379 in RecordsData.put data thy end; |
380 |
380 |
381 fun get_extsplit sg name = |
381 fun get_extsplit sg name = |
382 Symtab.lookup (#extsplit (RecordsData.get_sg sg), name); |
382 Symtab.lookup (#extsplit (RecordsData.get sg), name); |
383 |
383 |
384 (* access 'splits' *) |
384 (* access 'splits' *) |
385 |
385 |
386 fun add_record_splits name thmP thy = |
386 fun add_record_splits name thmP thy = |
387 let |
387 let |
391 equalities extinjects extsplit (Symtab.update_new ((name, thmP), splits)) |
391 equalities extinjects extsplit (Symtab.update_new ((name, thmP), splits)) |
392 extfields fieldext; |
392 extfields fieldext; |
393 in RecordsData.put data thy end; |
393 in RecordsData.put data thy end; |
394 |
394 |
395 fun get_splits sg name = |
395 fun get_splits sg name = |
396 Symtab.lookup (#splits (RecordsData.get_sg sg), name); |
396 Symtab.lookup (#splits (RecordsData.get sg), name); |
397 |
397 |
398 |
398 |
399 |
399 |
400 (* extension of a record name *) |
400 (* extension of a record name *) |
401 fun get_extension sg name = |
401 fun get_extension sg name = |
402 case Symtab.lookup (#records (RecordsData.get_sg sg),name) of |
402 case Symtab.lookup (#records (RecordsData.get sg),name) of |
403 SOME s => SOME (#extension s) |
403 SOME s => SOME (#extension s) |
404 | NONE => NONE; |
404 | NONE => NONE; |
405 |
405 |
406 (* access 'extfields' *) |
406 (* access 'extfields' *) |
407 |
407 |
413 equalities extinjects extsplit splits |
413 equalities extinjects extsplit splits |
414 (Symtab.update_new ((name, fields), extfields)) fieldext; |
414 (Symtab.update_new ((name, fields), extfields)) fieldext; |
415 in RecordsData.put data thy end; |
415 in RecordsData.put data thy end; |
416 |
416 |
417 fun get_extfields sg name = |
417 fun get_extfields sg name = |
418 Symtab.lookup (#extfields (RecordsData.get_sg sg), name); |
418 Symtab.lookup (#extfields (RecordsData.get sg), name); |
419 |
419 |
420 fun get_extT_fields sg T = |
420 fun get_extT_fields sg T = |
421 let |
421 let |
422 val ((name,Ts),moreT) = dest_recT T; |
422 val ((name,Ts),moreT) = dest_recT T; |
423 val recname = let val (nm::recn::rst) = rev (NameSpace.unpack name) |
423 val recname = let val (nm::recn::rst) = rev (NameSpace.unpack name) |
424 in NameSpace.pack (rev (nm::rst)) end; |
424 in NameSpace.pack (rev (nm::rst)) end; |
425 val midx = maxidx_of_typs (moreT::Ts); |
425 val midx = maxidx_of_typs (moreT::Ts); |
426 fun varify (a, S) = TVar ((a, midx), S); |
426 fun varify (a, S) = TVar ((a, midx), S); |
427 val varifyT = map_type_tfree varify; |
427 val varifyT = map_type_tfree varify; |
428 val {records,extfields,...} = RecordsData.get_sg sg; |
428 val {records,extfields,...} = RecordsData.get sg; |
429 val (flds,(more,_)) = split_last (Symtab.lookup_multi (extfields,name)); |
429 val (flds,(more,_)) = split_last (Symtab.lookup_multi (extfields,name)); |
430 val args = map varifyT (snd (#extension (valOf (Symtab.lookup (records,recname))))); |
430 val args = map varifyT (snd (#extension (valOf (Symtab.lookup (records,recname))))); |
431 |
431 |
432 val tsig = Sign.tsig_of sg; |
432 val tsig = Sign.tsig_of sg; |
433 fun unify (t,env) = Type.unify tsig env t; |
433 fun unify (t,env) = Type.unify tsig env t; |
456 splits extfields fieldext'; |
456 splits extfields fieldext'; |
457 in RecordsData.put data thy end; |
457 in RecordsData.put data thy end; |
458 |
458 |
459 |
459 |
460 fun get_fieldext sg name = |
460 fun get_fieldext sg name = |
461 Symtab.lookup (#fieldext (RecordsData.get_sg sg), name); |
461 Symtab.lookup (#fieldext (RecordsData.get sg), name); |
462 |
462 |
463 (* parent records *) |
463 (* parent records *) |
464 |
464 |
465 fun add_parents thy NONE parents = parents |
465 fun add_parents thy NONE parents = parents |
466 | add_parents thy (SOME (types, name)) parents = |
466 | add_parents thy (SOME (types, name)) parents = |
839 else opt (); |
839 else opt (); |
840 |
840 |
841 |
841 |
842 fun prove_split_simp sg T prop = |
842 fun prove_split_simp sg T prop = |
843 let |
843 let |
844 val {sel_upd={simpset,...},extsplit,...} = RecordsData.get_sg sg; |
844 val {sel_upd={simpset,...},extsplit,...} = RecordsData.get sg; |
845 val extsplits = |
845 val extsplits = |
846 Library.foldl (fn (thms,(n,_)) => (list (Symtab.lookup (extsplit,n)))@thms) |
846 Library.foldl (fn (thms,(n,_)) => (list (Symtab.lookup (extsplit,n)))@thms) |
847 ([],dest_recTs T); |
847 ([],dest_recTs T); |
848 val thms = (case get_splits sg (rec_id (~1) T) of |
848 val thms = (case get_splits sg (rec_id (~1) T) of |
849 SOME (all_thm,_,_,_) => |
849 SOME (all_thm,_,_,_) => |
878 (case t of (sel as Const (s, Type (_,[domS,rangeS])))$((upd as Const (u, _)) $ k $ r)=> |
878 (case t of (sel as Const (s, Type (_,[domS,rangeS])))$((upd as Const (u, _)) $ k $ r)=> |
879 (case get_selectors sg s of SOME () => |
879 (case get_selectors sg s of SOME () => |
880 (case get_updates sg u of SOME u_name => |
880 (case get_updates sg u of SOME u_name => |
881 let |
881 let |
882 fun mk_abs_var x t = (x, fastype_of t); |
882 fun mk_abs_var x t = (x, fastype_of t); |
883 val {sel_upd={updates,...},extfields,...} = RecordsData.get_sg sg; |
883 val {sel_upd={updates,...},extfields,...} = RecordsData.get sg; |
884 |
884 |
885 fun mk_eq_terms ((upd as Const (u,Type(_,[updT,_]))) $ k $ r) = |
885 fun mk_eq_terms ((upd as Const (u,Type(_,[updT,_]))) $ k $ r) = |
886 (case (Symtab.lookup (updates,u)) of |
886 (case (Symtab.lookup (updates,u)) of |
887 NONE => NONE |
887 NONE => NONE |
888 | SOME u_name |
888 | SOME u_name |
936 val record_upd_simproc = |
936 val record_upd_simproc = |
937 Simplifier.simproc (Theory.sign_of HOL.thy) "record_upd_simp" ["(u k r)"] |
937 Simplifier.simproc (Theory.sign_of HOL.thy) "record_upd_simp" ["(u k r)"] |
938 (fn sg => fn _ => fn t => |
938 (fn sg => fn _ => fn t => |
939 (case t of ((upd as Const (u, Type(_,[_,Type(_,[T,_])]))) $ k $ r) => |
939 (case t of ((upd as Const (u, Type(_,[_,Type(_,[T,_])]))) $ k $ r) => |
940 let datatype ('a,'b) calc = Init of 'b | Inter of 'a |
940 let datatype ('a,'b) calc = Init of 'b | Inter of 'a |
941 val {sel_upd={selectors,updates,...},extfields,...} = RecordsData.get_sg sg; |
941 val {sel_upd={selectors,updates,...},extfields,...} = RecordsData.get sg; |
942 |
942 |
943 fun mk_abs_var x t = (x, fastype_of t); |
943 fun mk_abs_var x t = (x, fastype_of t); |
944 fun sel_name u = NameSpace.base (unsuffix updateN u); |
944 fun sel_name u = NameSpace.base (unsuffix updateN u); |
945 |
945 |
946 fun seed s (upd as Const (more,Type(_,[mT,_]))$ k $ r) = |
946 fun seed s (upd as Const (more,Type(_,[mT,_]))$ k $ r) = |
1140 *) |
1140 *) |
1141 fun record_split_simp_tac thms P i st = |
1141 fun record_split_simp_tac thms P i st = |
1142 let |
1142 let |
1143 val sg = Thm.sign_of_thm st; |
1143 val sg = Thm.sign_of_thm st; |
1144 val {sel_upd={simpset,...},...} |
1144 val {sel_upd={simpset,...},...} |
1145 = RecordsData.get_sg sg; |
1145 = RecordsData.get sg; |
1146 |
1146 |
1147 val has_rec = exists_Const |
1147 val has_rec = exists_Const |
1148 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1148 (fn (s, Type (_, [Type (_, [T, _]), _])) => |
1149 (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T |
1149 (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T |
1150 | _ => false); |
1150 | _ => false); |