src/HOL/Tools/record_package.ML
changeset 22578 b0eb5652f210
parent 22219 61b5bab471ce
child 22596 d0d2af4db18f
equal deleted inserted replaced
22577:1a08fce38565 22578:b0eb5652f210
   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 =