37 -> (string * typ * mixfix) list -> theory -> theory |
37 -> (string * typ * mixfix) list -> theory -> theory |
38 val setup: (theory -> theory) list |
38 val setup: (theory -> theory) list |
39 end; |
39 end; |
40 |
40 |
41 |
41 |
42 structure RecordPackage :RECORD_PACKAGE = |
42 structure RecordPackage :RECORD_PACKAGE = |
43 struct |
43 struct |
44 |
44 |
45 val rec_UNIV_I = thm "rec_UNIV_I"; |
45 val rec_UNIV_I = thm "rec_UNIV_I"; |
46 val rec_True_simp = thm "rec_True_simp"; |
46 val rec_True_simp = thm "rec_True_simp"; |
47 val Pair_eq = thm "Product_Type.Pair_eq"; |
47 val Pair_eq = thm "Product_Type.Pair_eq"; |
58 val rN = "r"; |
58 val rN = "r"; |
59 val moreN = "more"; |
59 val moreN = "more"; |
60 val schemeN = "_scheme"; |
60 val schemeN = "_scheme"; |
61 val ext_typeN = "_ext_type"; |
61 val ext_typeN = "_ext_type"; |
62 val extN ="_ext"; |
62 val extN ="_ext"; |
63 val ext_dest = "_val"; |
63 val ext_dest = "_sel"; |
64 val updateN = "_update"; |
64 val updateN = "_update"; |
65 val schemeN = "_scheme"; |
65 val schemeN = "_scheme"; |
66 val makeN = "make"; |
66 val makeN = "make"; |
67 val fields_selN = "fields"; |
67 val fields_selN = "fields"; |
68 val extendN = "extend"; |
68 val extendN = "extend"; |
72 val RepN = "Rep_"; |
72 val RepN = "Rep_"; |
73 val AbsN = "Abs_"; |
73 val AbsN = "Abs_"; |
74 |
74 |
75 (*** utilities ***) |
75 (*** utilities ***) |
76 |
76 |
77 |
77 fun but_last xs = fst (split_last xs); |
78 fun last [] = error "RecordPackage.last: empty list" |
|
79 | last [x] = x |
|
80 | last (x::xs) = last xs; |
|
81 |
|
82 fun but_last [] = error "RecordPackage.but_last: empty list" |
|
83 | but_last [x] = [] |
|
84 | but_last (x::xs) = x::but_last xs; |
|
85 |
|
86 fun remdups [] = [] |
|
87 | remdups (x::xs) = x::remdups (filter_out (fn y => y=x) xs); |
|
88 |
|
89 fun is_suffix sfx s = is_some (try (unsuffix sfx) s); |
|
90 |
78 |
91 (* messages *) |
79 (* messages *) |
92 |
80 |
93 val quiet_mode = ref false; |
81 val quiet_mode = ref false; |
94 fun message s = if ! quiet_mode then () else writeln s; |
82 fun message s = if ! quiet_mode then () else writeln s; |
149 (* types *) |
137 (* types *) |
150 |
138 |
151 fun dest_recT (typ as Type (c_ext_type, Ts as (T::_))) = |
139 fun dest_recT (typ as Type (c_ext_type, Ts as (T::_))) = |
152 (case try (unsuffix ext_typeN) c_ext_type of |
140 (case try (unsuffix ext_typeN) c_ext_type of |
153 None => raise TYPE ("RecordPackage.dest_recT", [typ], []) |
141 None => raise TYPE ("RecordPackage.dest_recT", [typ], []) |
154 | Some c => ((c, Ts), last Ts)) |
142 | Some c => ((c, Ts), last_elem Ts)) |
155 | dest_recT typ = raise TYPE ("RecordPackage.dest_recT", [typ], []); |
143 | dest_recT typ = raise TYPE ("RecordPackage.dest_recT", [typ], []); |
156 |
144 |
157 fun is_recT T = |
145 fun is_recT T = |
158 (case try dest_recT T of None => false | Some _ => true); |
146 (case try dest_recT T of None => false | Some _ => true); |
159 |
147 |
219 equalities = equalities, splits = splits, |
207 equalities = equalities, splits = splits, |
220 extfields = extfields, fieldext = fieldext }: record_data; |
208 extfields = extfields, fieldext = fieldext }: record_data; |
221 |
209 |
222 structure RecordsArgs = |
210 structure RecordsArgs = |
223 struct |
211 struct |
224 val name = "HOL/records"; |
212 val name = "HOL/structures"; (* FIXME *) |
225 type T = record_data; |
213 type T = record_data; |
226 |
214 |
227 val empty = |
215 val empty = |
228 make_record_data Symtab.empty |
216 make_record_data Symtab.empty |
229 {selectors = Symtab.empty, updates = Symtab.empty, simpset = HOL_basic_ss} |
217 {selectors = Symtab.empty, updates = Symtab.empty, simpset = HOL_basic_ss} |
437 else [dest_ext_field mark trm] |
425 else [dest_ext_field mark trm] |
438 | dest_ext_fields _ mark t = [dest_ext_field mark t] |
426 | dest_ext_fields _ mark t = [dest_ext_field mark t] |
439 |
427 |
440 fun gen_ext_fields_tr sep mark sfx more sg t = |
428 fun gen_ext_fields_tr sep mark sfx more sg t = |
441 let |
429 let |
|
430 val msg = "error in record input: "; |
442 val fieldargs = dest_ext_fields sep mark t; |
431 val fieldargs = dest_ext_fields sep mark t; |
443 fun splitargs (field::fields) ((name,arg)::fargs) = |
432 fun splitargs (field::fields) ((name,arg)::fargs) = |
444 if is_suffix name field |
433 if can (unsuffix name) field |
445 then let val (args,rest) = splitargs fields fargs |
434 then let val (args,rest) = splitargs fields fargs |
446 in (arg::args,rest) end |
435 in (arg::args,rest) end |
447 else raise TERM ("gen_ext_fields_tr: expecting field " ^ field ^ |
436 else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t]) |
448 " but got " ^ name, [t]) |
|
449 | splitargs [] (fargs as (_::_)) = ([],fargs) |
437 | splitargs [] (fargs as (_::_)) = ([],fargs) |
450 | splitargs (_::_) [] = raise TERM ("gen_ext_fields_tr: expecting more fields", [t]) |
438 | splitargs (_::_) [] = raise TERM (msg ^ "expecting more fields", [t]) |
451 | splitargs _ _ = ([],[]); |
439 | splitargs _ _ = ([],[]); |
452 |
440 |
453 fun mk_ext (fargs as (name,arg)::_) = |
441 fun mk_ext (fargs as (name,arg)::_) = |
454 (case get_fieldext sg (Sign.intern_const sg name) of |
442 (case get_fieldext sg (Sign.intern_const sg name) of |
455 Some (ext,_) => (case get_extfields sg ext of |
443 Some (ext,_) => (case get_extfields sg ext of |
457 => let val (args,rest) = |
445 => let val (args,rest) = |
458 splitargs (map fst (but_last flds)) fargs; |
446 splitargs (map fst (but_last flds)) fargs; |
459 val more' = mk_ext rest; |
447 val more' = mk_ext rest; |
460 in list_comb (Syntax.const (suffix sfx ext),args@[more']) |
448 in list_comb (Syntax.const (suffix sfx ext),args@[more']) |
461 end |
449 end |
462 | None => raise TERM("gen_ext_fields_tr: no fields defined for " |
450 | None => raise TERM(msg ^ "no fields defined for " |
463 ^ ext,[t])) |
451 ^ ext,[t])) |
464 | None => raise TERM ("gen_ext_fields_tr: "^ name ^" is no proper field",[t])) |
452 | None => raise TERM (msg ^ name ^" is no proper field",[t])) |
465 | mk_ext [] = more |
453 | mk_ext [] = more |
466 |
454 |
467 in mk_ext fieldargs end; |
455 in mk_ext fieldargs end; |
468 |
456 |
469 fun gen_ext_type_tr sep mark sfx more sg t = |
457 fun gen_ext_type_tr sep mark sfx more sg t = |
470 let |
458 let |
|
459 val msg = "error in record-type input: "; |
471 val fieldargs = dest_ext_fields sep mark t; |
460 val fieldargs = dest_ext_fields sep mark t; |
472 fun splitargs (field::fields) ((name,arg)::fargs) = |
461 fun splitargs (field::fields) ((name,arg)::fargs) = |
473 if is_suffix name field |
462 if can (unsuffix name) field |
474 then let val (args,rest) = splitargs fields fargs |
463 then let val (args,rest) = splitargs fields fargs |
475 in (arg::args,rest) end |
464 in (arg::args,rest) end |
476 else raise TERM ("gen_ext_type_tr: expecting field " ^ field ^ |
465 else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t]) |
477 " but got " ^ name, [t]) |
|
478 | splitargs [] (fargs as (_::_)) = ([],fargs) |
466 | splitargs [] (fargs as (_::_)) = ([],fargs) |
479 | splitargs (_::_) [] = raise TERM ("gen_ext_type_tr: expecting more fields", [t]) |
467 | splitargs (_::_) [] = raise TERM (msg ^ "expecting more fields", [t]) |
480 | splitargs _ _ = ([],[]); |
468 | splitargs _ _ = ([],[]); |
481 |
469 |
482 fun get_sort xs n = (case assoc (xs,n) of |
470 fun get_sort xs n = (case assoc (xs,n) of |
483 Some s => s |
471 Some s => s |
484 | None => Sign.defaultS sg); |
472 | None => Sign.defaultS sg); |
505 (but_last alphas); |
493 (but_last alphas); |
506 |
494 |
507 val more' = mk_ext rest; |
495 val more' = mk_ext rest; |
508 in list_comb (Syntax.const (suffix sfx ext),alphas'@[more']) |
496 in list_comb (Syntax.const (suffix sfx ext),alphas'@[more']) |
509 end handle TUNIFY => raise |
497 end handle TUNIFY => raise |
510 TERM ("gen_ext_type_tr: type is no proper record (extension)", [t])) |
498 TERM (msg ^ "type is no proper record (extension)", [t])) |
511 | None => raise TERM ("gen_ext_fields_tr: no fields defined for " ^ ext,[t])) |
499 | None => raise TERM (msg ^ "no fields defined for " ^ ext,[t])) |
512 | None => raise TERM ("gen_ext_fields_tr: "^ name ^" is no proper field",[t])) |
500 | None => raise TERM (msg ^ name ^" is no proper field",[t])) |
513 | mk_ext [] = more |
501 | mk_ext [] = more |
514 |
502 |
515 in mk_ext fieldargs end; |
503 in mk_ext fieldargs end; |
516 |
504 |
517 fun gen_adv_record_tr sep mark sfx unit sg [t] = |
505 fun gen_adv_record_tr sep mark sfx unit sg [t] = |
1123 val dest_specs = |
1111 val dest_specs = |
1124 ListPair.map mk_dest_spec (idxms, fields_more); |
1112 ListPair.map mk_dest_spec (idxms, fields_more); |
1125 |
1113 |
1126 (* code generator data *) |
1114 (* code generator data *) |
1127 (* Representation as nested pairs is revealed for codegeneration *) |
1115 (* Representation as nested pairs is revealed for codegeneration *) |
1128 val [rep_code,abs_code] = map (Codegen.parse_mixfix (K (Bound 0))) ["I","I"]; |
1116 val [rep_code,abs_code] = map (Codegen.parse_mixfix (K (Bound 0))) ["(_)","(_)"]; |
1129 val ext_type_code = Codegen.parse_mixfix (K dummyT) "_"; |
1117 val ext_type_code = Codegen.parse_mixfix (K dummyT) "(_)"; |
1130 |
1118 |
1131 (* 1st stage: defs_thy *) |
1119 (* 1st stage: defs_thy *) |
1132 val (defs_thy, ([abs_inject, abs_inverse, abs_induct],ext_def::dest_defs)) = |
1120 val (defs_thy, ([abs_inject, abs_inverse, abs_induct],ext_def::dest_defs)) = |
1133 thy |
1121 thy |
1134 |> extension_typedef name repT (alphas@[zeta]) |
1122 |> extension_typedef name repT (alphas@[zeta]) |
1693 (* setup theory *) |
1681 (* setup theory *) |
1694 |
1682 |
1695 val setup = |
1683 val setup = |
1696 [RecordsData.init, |
1684 [RecordsData.init, |
1697 Theory.add_trfuns ([], parse_translation, [], []), |
1685 Theory.add_trfuns ([], parse_translation, [], []), |
1698 Theory.add_advanced_trfuns ([], adv_parse_translation, [], []), |
1686 Theory.add_advanced_trfuns ([], adv_parse_translation, [], []), |
1699 Simplifier.change_simpset_of Simplifier.addsimprocs |
1687 Simplifier.change_simpset_of Simplifier.addsimprocs |
1700 [record_simproc, record_eq_simproc]]; |
1688 [record_simproc, record_upd_simproc, record_eq_simproc]]; |
1701 |
1689 |
1702 (* outer syntax *) |
1690 (* outer syntax *) |
1703 |
1691 |
1704 local structure P = OuterParse and K = OuterSyntax.Keyword in |
1692 local structure P = OuterParse and K = OuterSyntax.Keyword in |
1705 |
1693 |
1706 val record_decl = |
1694 val record_decl = |
1707 P.type_args -- P.name -- |
1695 P.type_args -- P.name -- |
1708 (P.$$$ "=" |-- Scan.option (P.typ --| P.$$$ "+") -- Scan.repeat1 P.const); |
1696 (P.$$$ "=" |-- Scan.option (P.typ --| P.$$$ "+") -- Scan.repeat1 P.const); |
1709 |
1697 |
1710 val recordP = |
1698 val recordP = |
1711 OuterSyntax.command "record" "define extensible record" K.thy_decl |
1699 OuterSyntax.command "record" "define extensible record" K.thy_decl |
1712 (record_decl >> (fn (x, (y, z)) => Toplevel.theory (add_record x y z))); |
1700 (record_decl >> (fn (x, (y, z)) => Toplevel.theory (add_record x y z))); |
1713 |
1701 |
1714 val _ = OuterSyntax.add_parsers [recordP]; |
1702 val _ = OuterSyntax.add_parsers [recordP]; |
1715 |
1703 |
1716 end; |
1704 end; |