src/HOL/Tools/record_package.ML
changeset 16458 4c6fd0c01d28
parent 16379 d29d27e0f59f
child 16783 26fccaaf9cb4
equal deleted inserted replaced
16457:e0f22edf38a5 16458:4c6fd0c01d28
    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);