479 (* parent records *) |
479 (* parent records *) |
480 |
480 |
481 fun add_parents thy NONE parents = parents |
481 fun add_parents thy NONE parents = parents |
482 | add_parents thy (SOME (types, name)) parents = |
482 | add_parents thy (SOME (types, name)) parents = |
483 let |
483 let |
484 val sign = Theory.sign_of thy; |
|
485 fun err msg = error (msg ^ " parent record " ^ quote name); |
484 fun err msg = error (msg ^ " parent record " ^ quote name); |
486 |
485 |
487 val {args, parent, fields, extension, induct} = |
486 val {args, parent, fields, extension, induct} = |
488 (case get_record thy name of SOME info => info | NONE => err "Unknown"); |
487 (case get_record thy name of SOME info => info | NONE => err "Unknown"); |
489 val _ = if length types <> length args then err "Bad number of arguments for" else (); |
488 val _ = if length types <> length args then err "Bad number of arguments for" else (); |
490 |
489 |
491 fun bad_inst ((x, S), T) = |
490 fun bad_inst ((x, S), T) = |
492 if Sign.of_sort sign (T, S) then NONE else SOME x |
491 if Sign.of_sort thy (T, S) then NONE else SOME x |
493 val bads = List.mapPartial bad_inst (args ~~ types); |
492 val bads = List.mapPartial bad_inst (args ~~ types); |
494 val _ = null bads orelse err ("Ill-sorted instantiation of " ^ commas bads ^ " in"); |
493 val _ = null bads orelse err ("Ill-sorted instantiation of " ^ commas bads ^ " in"); |
495 |
494 |
496 val inst = map fst args ~~ types; |
495 val inst = map fst args ~~ types; |
497 val subst = Term.map_type_tfree (the o AList.lookup (op =) inst o fst); |
496 val subst = Term.map_type_tfree (the o AList.lookup (op =) inst o fst); |
1718 |
1717 |
1719 (* record_definition *) |
1718 (* record_definition *) |
1720 fun record_definition (args, bname) parent (parents: parent_info list) raw_fields thy = |
1719 fun record_definition (args, bname) parent (parents: parent_info list) raw_fields thy = |
1721 (* smlnj needs type annotation of parents *) |
1720 (* smlnj needs type annotation of parents *) |
1722 let |
1721 let |
1723 val sign = Theory.sign_of thy; |
|
1724 |
|
1725 val alphas = map fst args; |
1722 val alphas = map fst args; |
1726 val name = Sign.full_name sign bname; |
1723 val name = Sign.full_name thy bname; |
1727 val full = Sign.full_name_path sign bname; |
1724 val full = Sign.full_name_path thy bname; |
1728 val base = Sign.base_name; |
1725 val base = Sign.base_name; |
1729 |
1726 |
1730 val (bfields, field_syntax) = split_list (map (fn (x, T, mx) => ((x, T), mx)) raw_fields); |
1727 val (bfields, field_syntax) = split_list (map (fn (x, T, mx) => ((x, T), mx)) raw_fields); |
1731 |
1728 |
1732 val parent_fields = List.concat (map #fields parents); |
1729 val parent_fields = List.concat (map #fields parents); |
2170 (*we do all preparations and error checks here, deferring the real |
2167 (*we do all preparations and error checks here, deferring the real |
2171 work to record_definition*) |
2168 work to record_definition*) |
2172 fun gen_add_record prep_typ prep_raw_parent (params, bname) raw_parent raw_fields thy = |
2169 fun gen_add_record prep_typ prep_raw_parent (params, bname) raw_parent raw_fields thy = |
2173 let |
2170 let |
2174 val _ = Theory.requires thy "Record" "record definitions"; |
2171 val _ = Theory.requires thy "Record" "record definitions"; |
2175 val sign = Theory.sign_of thy; |
|
2176 val _ = message ("Defining record " ^ quote bname ^ " ..."); |
2172 val _ = message ("Defining record " ^ quote bname ^ " ..."); |
2177 |
2173 |
2178 |
2174 |
2179 (* parents *) |
2175 (* parents *) |
2180 |
2176 |
2181 fun prep_inst T = snd (cert_typ sign ([], T)); |
2177 fun prep_inst T = snd (cert_typ thy ([], T)); |
2182 |
2178 |
2183 val parent = Option.map (apfst (map prep_inst) o prep_raw_parent sign) raw_parent |
2179 val parent = Option.map (apfst (map prep_inst) o prep_raw_parent thy) raw_parent |
2184 handle ERROR msg => cat_error msg ("The error(s) above in parent record specification"); |
2180 handle ERROR msg => cat_error msg ("The error(s) above in parent record specification"); |
2185 val parents = add_parents thy parent []; |
2181 val parents = add_parents thy parent []; |
2186 |
2182 |
2187 val init_env = |
2183 val init_env = |
2188 (case parent of |
2184 (case parent of |
2191 |
2187 |
2192 |
2188 |
2193 (* fields *) |
2189 (* fields *) |
2194 |
2190 |
2195 fun prep_field (env, (c, raw_T, mx)) = |
2191 fun prep_field (env, (c, raw_T, mx)) = |
2196 let val (env', T) = prep_typ sign (env, raw_T) handle ERROR msg => |
2192 let val (env', T) = prep_typ thy (env, raw_T) handle ERROR msg => |
2197 cat_error msg ("The error(s) above occured in field " ^ quote c) |
2193 cat_error msg ("The error(s) above occured in field " ^ quote c) |
2198 in (env', (c, T, mx)) end; |
2194 in (env', (c, T, mx)) end; |
2199 |
2195 |
2200 val (envir, bfields) = foldl_map prep_field (init_env, raw_fields); |
2196 val (envir, bfields) = foldl_map prep_field (init_env, raw_fields); |
2201 val envir_names = map fst envir; |
2197 val envir_names = map fst envir; |
2202 |
2198 |
2203 |
2199 |
2204 (* args *) |
2200 (* args *) |
2205 |
2201 |
2206 val defaultS = Sign.defaultS sign; |
2202 val defaultS = Sign.defaultS thy; |
2207 val args = map (fn x => (x, AList.lookup (op =) envir x |> the_default defaultS)) params; |
2203 val args = map (fn x => (x, AList.lookup (op =) envir x |> the_default defaultS)) params; |
2208 |
2204 |
2209 |
2205 |
2210 (* errors *) |
2206 (* errors *) |
2211 |
2207 |
2212 val name = Sign.full_name sign bname; |
2208 val name = Sign.full_name thy bname; |
2213 val err_dup_record = |
2209 val err_dup_record = |
2214 if is_none (get_record thy name) then [] |
2210 if is_none (get_record thy name) then [] |
2215 else ["Duplicate definition of record " ^ quote name]; |
2211 else ["Duplicate definition of record " ^ quote name]; |
2216 |
2212 |
2217 val err_dup_parms = |
2213 val err_dup_parms = |