src/HOL/Tools/record_package.ML
changeset 14358 233c5bd5b539
parent 14255 e6e3e3f0deed
child 14427 cea7d2f76112
equal deleted inserted replaced
14357:e49d5d5ae66a 14358:233c5bd5b539
    23   val updateN: string
    23   val updateN: string
    24   val mk_fieldT: (string * typ) * typ -> typ
    24   val mk_fieldT: (string * typ) * typ -> typ
    25   val dest_fieldT: typ -> (string * typ) * typ
    25   val dest_fieldT: typ -> (string * typ) * typ
    26   val dest_fieldTs: typ -> (string * typ) list
    26   val dest_fieldTs: typ -> (string * typ) list
    27   val last_fieldT: typ -> (string * typ) option
    27   val last_fieldT: typ -> (string * typ) option
       
    28   val last_field: Sign.sg -> string -> (string * typ) option
       
    29   val get_parents: Sign.sg -> string -> string list
    28   val mk_field: (string * term) * term -> term
    30   val mk_field: (string * term) * term -> term
    29   val mk_fst: term -> term
    31   val mk_fst: term -> term
    30   val mk_snd: term -> term
    32   val mk_snd: term -> term
    31   val mk_recordT: (string * typ) list * typ -> typ
    33   val mk_recordT: (string * typ) list * typ -> typ
    32   val dest_recordT: typ -> (string * typ) list * typ
    34   val dest_recordT: typ -> (string * typ) list * typ
    42   val record_upd_simproc: simproc
    44   val record_upd_simproc: simproc
    43   val record_split_simproc: (term -> bool) -> simproc
    45   val record_split_simproc: (term -> bool) -> simproc
    44   val record_split_simp_tac: (term -> bool) -> int -> tactic
    46   val record_split_simp_tac: (term -> bool) -> int -> tactic
    45 end;
    47 end;
    46 
    48 
    47 structure RecordPackage :RECORD_PACKAGE =
    49 structure RecordPackage: RECORD_PACKAGE =
    48 struct
    50 struct
    49 
    51 
    50 
    52 
    51 (*** theory context references ***)
    53 (*** theory context references ***)
    52 
    54 
   350     (fn Const ("unit", _) => true | _ => false) "_record_type" "_record_type_scheme";
   352     (fn Const ("unit", _) => true | _ => false) "_record_type" "_record_type_scheme";
   351 
   353 
   352 
   354 
   353 (* record_type_abbr_tr' tries to reconstruct the record name type abbreviation from *)
   355 (* record_type_abbr_tr' tries to reconstruct the record name type abbreviation from *)
   354 (* the (nested) field types.                                                        *)
   356 (* the (nested) field types.                                                        *)
   355 fun record_type_abbr_tr' sg abbr alphas zeta lastF recT rec_schemeT tm =
   357 fun record_type_abbr_tr' sg abbr alphas zeta lastF rec_schemeT tm =
   356   let
   358   let
   357       (* tm is term representation of a (nested) field type. We first reconstruct the      *)
   359       (* tm is term representation of a (nested) field type. We first reconstruct the      *)
   358       (* type from tm so that we can continue on the type level rather then the term level.*)
   360       (* type from tm so that we can continue on the type level rather then the term level.*)
   359  
   361  
   360       fun get_sort xs n = (case assoc (xs,n) of 
   362       fun get_sort xs n = (case assoc (xs,n) of 
   385             | _ => record_type_tr' tm)
   387             | _ => record_type_tr' tm)
   386        else record_type_tr' tm
   388        else record_type_tr' tm
   387   end
   389   end
   388 
   390 
   389      
   391      
   390 fun gen_record_type_abbr_tr' sg abbr alphas zeta lastF recT rec_schemeT name =
   392 fun gen_record_type_abbr_tr' sg abbr alphas zeta lastF rec_schemeT name =
   391   let val name_sfx = suffix field_typeN name
   393   let val name_sfx = suffix field_typeN name
   392       val tr' = record_type_abbr_tr' sg abbr alphas zeta lastF recT rec_schemeT 
   394       val tr' = record_type_abbr_tr' sg abbr alphas zeta lastF rec_schemeT 
   393   in (name_sfx, fn [t,u] => tr' (Syntax.const name_sfx $ t $ u) | _ => raise Match) end;
   395   in (name_sfx, fn [t,u] => tr' (Syntax.const name_sfx $ t $ u) | _ => raise Match) end;
   394       
   396       
   395 val record_tr' =
   397 val record_tr' =
   396   gen_record_tr' "_fields" "_field" fieldN
   398   gen_record_tr' "_fields" "_field" fieldN
   397     (fn Const ("Unity", _) => true | _ => false) "_record" "_record_scheme";
   399     (fn Const ("Unity", _) => true | _ => false) "_record" "_record_scheme";
   595   in RecordsData.put data thy end;
   597   in RecordsData.put data thy end;
   596 
   598 
   597 fun get_splits sg name =
   599 fun get_splits sg name =
   598   Symtab.lookup (#splits (RecordsData.get_sg sg), name);
   600   Symtab.lookup (#splits (RecordsData.get_sg sg), name);
   599 
   601 
   600 
   602 (* last field of a record *)
       
   603 fun last_field sg name =
       
   604       case Symtab.lookup (#records (RecordsData.get_sg sg),name) of
       
   605         Some r => Some (hd (rev (#fields r)))
       
   606       | None => None;
       
   607 
       
   608 (* get parent names *)
       
   609 fun get_parents sg name =
       
   610      (case Symtab.lookup (#records (RecordsData.get_sg sg),name) of
       
   611          Some r => (case #parent r of
       
   612                      Some (_,p) => p::get_parents sg p
       
   613                    | None => [])
       
   614       | None => [])
       
   615        
   601 (* parent records *)
   616 (* parent records *)
   602 
   617 
   603 fun add_parents thy None parents = parents
   618 fun add_parents thy None parents = parents
   604   | add_parents thy (Some (types, name)) parents =
   619   | add_parents thy (Some (types, name)) parents =
   605       let
   620       let
   622         conditional (not (null bads)) (fn () =>
   637         conditional (not (null bads)) (fn () =>
   623           err ("Ill-sorted instantiation of " ^ commas bads ^ " in"));
   638           err ("Ill-sorted instantiation of " ^ commas bads ^ " in"));
   624         add_parents thy parent'
   639         add_parents thy parent'
   625           (make_parent_info name fields' field_inducts field_cases field_splits simps::parents)
   640           (make_parent_info name fields' field_inducts field_cases field_splits simps::parents)
   626       end;
   641       end;
       
   642 
   627 
   643 
   628 
   644 
   629 (** record simprocs **)
   645 (** record simprocs **)
   630  
   646  
   631 fun quick_and_dirty_prove sg xs asms prop tac =
   647 fun quick_and_dirty_prove sg xs asms prop tac =
   914   in foldl_map type_def (theory, names) end;
   930   in foldl_map type_def (theory, names) end;
   915 
   931 
   916 
   932 
   917 (* field_definitions *)
   933 (* field_definitions *)
   918 
   934 
   919 fun field_definitions fields names xs alphas zeta moreT more vars named_vars thy =
   935 fun field_definitions fields names alphas zeta moreT more vars thy =
   920   let
   936   let
   921     val sign = Theory.sign_of thy;
   937     val sign = Theory.sign_of thy;
   922     val base = Sign.base_name;
   938     val base = Sign.base_name;
   923 
   939 
   924     val xT = TFree (variant alphas "'x", HOLogic.typeS);
   940     val xT = TFree (variant alphas "'x", HOLogic.typeS);
  1061 
  1077 
  1062     val field_type_tr's = 
  1078     val field_type_tr's = 
  1063 	let val fldnames = if parent_len = 0 then (tl names) else names;
  1079 	let val fldnames = if parent_len = 0 then (tl names) else names;
  1064         in print_translation_field_types (distinct (flat (map NameSpace.accesses' fldnames))) 
  1080         in print_translation_field_types (distinct (flat (map NameSpace.accesses' fldnames))) 
  1065         end;
  1081         end;
  1066                           
  1082 
  1067     fun record_type_abbr_tr's thy =
  1083     fun record_type_abbr_tr's thy =
  1068 	let val trnames = (distinct (flat (map NameSpace.accesses' [hd all_names])))
  1084 	let val trnames = NameSpace.accesses' (hd all_names)
  1069             val sg = Theory.sign_of thy
  1085             val sg = Theory.sign_of thy
  1070 	in map (gen_record_type_abbr_tr' 
  1086 	in map (gen_record_type_abbr_tr' 
  1071                  sg bname alphas zeta (hd (rev names)) (recT 0) (rec_schemeT 0)) trnames end;   
  1087                  sg bname alphas zeta (hd (rev names)) (rec_schemeT 0)) trnames end;   
  1072 
  1088 
  1073     (* prepare declarations *)
  1089     (* prepare declarations *)
  1074 
  1090 
  1075     val sel_decls = map (mk_selC (rec_schemeT 0)) bfields @
  1091     val sel_decls = map (mk_selC (rec_schemeT 0)) bfields @
  1076       [mk_moreC (rec_schemeT 0) (moreN, moreT)];
  1092       [mk_moreC (rec_schemeT 0) (moreN, moreT)];
  1194     (* 1st stage: fields_thy *)
  1210     (* 1st stage: fields_thy *)
  1195 
  1211 
  1196     val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) =
  1212     val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) =
  1197       thy
  1213       thy
  1198       |> Theory.add_path bname
  1214       |> Theory.add_path bname
  1199       |> field_definitions fields names xs alphas zeta moreT more vars named_vars;
  1215       |> field_definitions fields names alphas zeta moreT more vars;
  1200 
  1216 
  1201     val all_field_inducts = flat (map #field_inducts parents) @ field_inducts;
  1217     val all_field_inducts = flat (map #field_inducts parents) @ field_inducts;
  1202     val all_field_cases = flat (map #field_cases parents) @ field_cases;
  1218     val all_field_cases = flat (map #field_cases parents) @ field_cases;
  1203     val all_field_splits = flat (map #field_splits parents) @ field_splits
  1219     val all_field_splits = flat (map #field_splits parents) @ field_splits
  1204 
  1220