src/HOL/Tools/record_package.ML
changeset 17412 e26cb20ef0cc
parent 17377 afaa031ed4da
child 17485 c39871c52977
equal deleted inserted replaced
17411:664434175578 17412:e26cb20ef0cc
   299 val print_records = RecordsData.print;
   299 val print_records = RecordsData.print;
   300 
   300 
   301 
   301 
   302 (* access 'records' *)
   302 (* access 'records' *)
   303 
   303 
   304 val get_record = Symtab.curried_lookup o #records o RecordsData.get;
   304 val get_record = Symtab.lookup o #records o RecordsData.get;
   305 
   305 
   306 fun put_record name info thy =
   306 fun put_record name info thy =
   307   let
   307   let
   308     val {records, sel_upd, equalities, extinjects,extsplit,splits,extfields,fieldext} =
   308     val {records, sel_upd, equalities, extinjects,extsplit,splits,extfields,fieldext} =
   309           RecordsData.get thy;
   309           RecordsData.get thy;
   310     val data = make_record_data (Symtab.curried_update (name, info) records)
   310     val data = make_record_data (Symtab.update (name, info) records)
   311       sel_upd equalities extinjects extsplit splits extfields fieldext;
   311       sel_upd equalities extinjects extsplit splits extfields fieldext;
   312   in RecordsData.put data thy end;
   312   in RecordsData.put data thy end;
   313 
   313 
   314 (* access 'sel_upd' *)
   314 (* access 'sel_upd' *)
   315 
   315 
   316 val get_sel_upd = #sel_upd o RecordsData.get;
   316 val get_sel_upd = #sel_upd o RecordsData.get;
   317 
   317 
   318 val get_selectors = Symtab.curried_lookup o #selectors o get_sel_upd;
   318 val get_selectors = Symtab.lookup o #selectors o get_sel_upd;
   319 fun is_selector sg name = is_some (get_selectors sg (Sign.intern_const sg name));
   319 fun is_selector sg name = is_some (get_selectors sg (Sign.intern_const sg name));
   320 
   320 
   321 val get_updates = Symtab.curried_lookup o #updates o get_sel_upd;
   321 val get_updates = Symtab.lookup o #updates o get_sel_upd;
   322 val get_simpset = #simpset o get_sel_upd;
   322 val get_simpset = #simpset o get_sel_upd;
   323 
   323 
   324 fun put_sel_upd names simps thy =
   324 fun put_sel_upd names simps thy =
   325   let
   325   let
   326     val sels = map (rpair ()) names;
   326     val sels = map (rpair ()) names;
   340 fun add_record_equalities name thm thy =
   340 fun add_record_equalities name thm thy =
   341   let
   341   let
   342     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields,fieldext} =
   342     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields,fieldext} =
   343           RecordsData.get thy;
   343           RecordsData.get thy;
   344     val data = make_record_data records sel_upd
   344     val data = make_record_data records sel_upd
   345            (Symtab.curried_update_new (name, thm) equalities) extinjects extsplit
   345            (Symtab.update_new (name, thm) equalities) extinjects extsplit
   346            splits extfields fieldext;
   346            splits extfields fieldext;
   347   in RecordsData.put data thy end;
   347   in RecordsData.put data thy end;
   348 
   348 
   349 val get_equalities =Symtab.curried_lookup o #equalities o RecordsData.get;
   349 val get_equalities =Symtab.lookup o #equalities o RecordsData.get;
   350 
   350 
   351 (* access 'extinjects' *)
   351 (* access 'extinjects' *)
   352 
   352 
   353 fun add_extinjects thm thy =
   353 fun add_extinjects thm thy =
   354   let
   354   let
   365 fun add_extsplit name thm thy =
   365 fun add_extsplit name thm thy =
   366   let
   366   let
   367     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields,fieldext} =
   367     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields,fieldext} =
   368           RecordsData.get thy;
   368           RecordsData.get thy;
   369     val data = make_record_data records sel_upd
   369     val data = make_record_data records sel_upd
   370       equalities extinjects (Symtab.curried_update_new (name, thm) extsplit) splits
   370       equalities extinjects (Symtab.update_new (name, thm) extsplit) splits
   371       extfields fieldext;
   371       extfields fieldext;
   372   in RecordsData.put data thy end;
   372   in RecordsData.put data thy end;
   373 
   373 
   374 val get_extsplit = Symtab.curried_lookup o #extsplit o RecordsData.get;
   374 val get_extsplit = Symtab.lookup o #extsplit o RecordsData.get;
   375 
   375 
   376 (* access 'splits' *)
   376 (* access 'splits' *)
   377 
   377 
   378 fun add_record_splits name thmP thy =
   378 fun add_record_splits name thmP thy =
   379   let
   379   let
   380     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields,fieldext} =
   380     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields,fieldext} =
   381           RecordsData.get thy;
   381           RecordsData.get thy;
   382     val data = make_record_data records sel_upd
   382     val data = make_record_data records sel_upd
   383       equalities extinjects extsplit (Symtab.curried_update_new (name, thmP) splits)
   383       equalities extinjects extsplit (Symtab.update_new (name, thmP) splits)
   384       extfields fieldext;
   384       extfields fieldext;
   385   in RecordsData.put data thy end;
   385   in RecordsData.put data thy end;
   386 
   386 
   387 val get_splits = Symtab.curried_lookup o #splits o RecordsData.get;
   387 val get_splits = Symtab.lookup o #splits o RecordsData.get;
   388 
   388 
   389 
   389 
   390 
   390 
   391 (* extension of a record name *)
   391 (* extension of a record name *)
   392 val get_extension =
   392 val get_extension =
   393   Option.map #extension oo (Symtab.curried_lookup o #records o RecordsData.get);
   393   Option.map #extension oo (Symtab.lookup o #records o RecordsData.get);
   394 
   394 
   395 
   395 
   396 (* access 'extfields' *)
   396 (* access 'extfields' *)
   397 
   397 
   398 fun add_extfields name fields thy =
   398 fun add_extfields name fields thy =
   399   let
   399   let
   400     val {records, sel_upd, equalities, extinjects, extsplit,splits, extfields, fieldext} =
   400     val {records, sel_upd, equalities, extinjects, extsplit,splits, extfields, fieldext} =
   401           RecordsData.get thy;
   401           RecordsData.get thy;
   402     val data = make_record_data records sel_upd
   402     val data = make_record_data records sel_upd
   403          equalities extinjects extsplit splits
   403          equalities extinjects extsplit splits
   404          (Symtab.curried_update_new (name, fields) extfields) fieldext;
   404          (Symtab.update_new (name, fields) extfields) fieldext;
   405   in RecordsData.put data thy end;
   405   in RecordsData.put data thy end;
   406 
   406 
   407 val get_extfields = Symtab.curried_lookup o #extfields o RecordsData.get;
   407 val get_extfields = Symtab.lookup o #extfields o RecordsData.get;
   408 
   408 
   409 fun get_extT_fields sg T =
   409 fun get_extT_fields sg T =
   410   let
   410   let
   411     val ((name,Ts),moreT) = dest_recT T;
   411     val ((name,Ts),moreT) = dest_recT T;
   412     val recname = let val (nm::recn::rst) = rev (NameSpace.unpack name)
   412     val recname = let val (nm::recn::rst) = rev (NameSpace.unpack name)
   413                   in NameSpace.pack (rev (nm::rst)) end;
   413                   in NameSpace.pack (rev (nm::rst)) end;
   414     val midx = maxidx_of_typs (moreT::Ts);
   414     val midx = maxidx_of_typs (moreT::Ts);
   415     fun varify (a, S) = TVar ((a, midx), S);
   415     fun varify (a, S) = TVar ((a, midx), S);
   416     val varifyT = map_type_tfree varify;
   416     val varifyT = map_type_tfree varify;
   417     val {records,extfields,...} = RecordsData.get sg;
   417     val {records,extfields,...} = RecordsData.get sg;
   418     val (flds,(more,_)) = split_last (Symtab.curried_lookup_multi extfields name);
   418     val (flds,(more,_)) = split_last (Symtab.lookup_multi extfields name);
   419     val args = map varifyT (snd (#extension (the (Symtab.curried_lookup records recname))));
   419     val args = map varifyT (snd (#extension (the (Symtab.lookup records recname))));
   420 
   420 
   421     val (subst,_) = fold (Sign.typ_unify sg) (but_last args ~~ but_last Ts) (Vartab.empty,0);
   421     val (subst,_) = fold (Sign.typ_unify sg) (but_last args ~~ but_last Ts) (Vartab.empty,0);
   422     val flds' = map (apsnd ((Envir.norm_type subst) o varifyT)) flds;
   422     val flds' = map (apsnd ((Envir.norm_type subst) o varifyT)) flds;
   423   in (flds',(more,moreT)) end;
   423   in (flds',(more,moreT)) end;
   424 
   424 
   436 fun add_fieldext extname_types fields thy =
   436 fun add_fieldext extname_types fields thy =
   437   let
   437   let
   438     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
   438     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
   439            RecordsData.get thy;
   439            RecordsData.get thy;
   440     val fieldext' =
   440     val fieldext' =
   441       fold (fn field => Symtab.curried_update_new (field, extname_types)) fields fieldext;
   441       fold (fn field => Symtab.update_new (field, extname_types)) fields fieldext;
   442     val data=make_record_data records sel_upd equalities extinjects extsplit
   442     val data=make_record_data records sel_upd equalities extinjects extsplit
   443               splits extfields fieldext';
   443               splits extfields fieldext';
   444   in RecordsData.put data thy end;
   444   in RecordsData.put data thy end;
   445 
   445 
   446 
   446 
   447 val get_fieldext = Symtab.curried_lookup o #fieldext o RecordsData.get;
   447 val get_fieldext = Symtab.lookup o #fieldext o RecordsData.get;
   448 
   448 
   449 (* parent records *)
   449 (* parent records *)
   450 
   450 
   451 fun add_parents thy NONE parents = parents
   451 fun add_parents thy NONE parents = parents
   452   | add_parents thy (SOME (types, name)) parents =
   452   | add_parents thy (SOME (types, name)) parents =
   817 
   817 
   818 fun prove_split_simp sg ss T prop =
   818 fun prove_split_simp sg ss T prop =
   819   let
   819   let
   820     val {sel_upd={simpset,...},extsplit,...} = RecordsData.get sg;
   820     val {sel_upd={simpset,...},extsplit,...} = RecordsData.get sg;
   821     val extsplits =
   821     val extsplits =
   822             Library.foldl (fn (thms,(n,_)) => the_list (Symtab.curried_lookup extsplit n) @ thms)
   822             Library.foldl (fn (thms,(n,_)) => the_list (Symtab.lookup extsplit n) @ thms)
   823                     ([],dest_recTs T);
   823                     ([],dest_recTs T);
   824     val thms = (case get_splits sg (rec_id (~1) T) of
   824     val thms = (case get_splits sg (rec_id (~1) T) of
   825                    SOME (all_thm,_,_,_) =>
   825                    SOME (all_thm,_,_,_) =>
   826                      all_thm::(case extsplits of [thm] => [] | _ => extsplits)
   826                      all_thm::(case extsplits of [thm] => [] | _ => extsplits)
   827                               (* [thm] is the same as all_thm *)
   827                               (* [thm] is the same as all_thm *)
   833 
   833 
   834 
   834 
   835 local
   835 local
   836 fun eq (s1:string) (s2:string) = (s1 = s2);
   836 fun eq (s1:string) (s2:string) = (s1 = s2);
   837 fun has_field extfields f T =
   837 fun has_field extfields f T =
   838      exists (fn (eN,_) => exists (eq f o fst) (Symtab.curried_lookup_multi extfields eN))
   838      exists (fn (eN,_) => exists (eq f o fst) (Symtab.lookup_multi extfields eN))
   839        (dest_recTs T);
   839        (dest_recTs T);
   840 in
   840 in
   841 (* record_simproc *)
   841 (* record_simproc *)
   842 (* Simplifies selections of an record update:
   842 (* Simplifies selections of an record update:
   843  *  (1)  S (r(|S:=k|)) = k respectively
   843  *  (1)  S (r(|S:=k|)) = k respectively
   859           (case get_updates sg u of SOME u_name =>
   859           (case get_updates sg u of SOME u_name =>
   860             let
   860             let
   861               val {sel_upd={updates,...},extfields,...} = RecordsData.get sg;
   861               val {sel_upd={updates,...},extfields,...} = RecordsData.get sg;
   862 
   862 
   863               fun mk_eq_terms ((upd as Const (u,Type(_,[kT,_]))) $ k $ r) =
   863               fun mk_eq_terms ((upd as Const (u,Type(_,[kT,_]))) $ k $ r) =
   864                   (case Symtab.curried_lookup updates u of
   864                   (case Symtab.lookup updates u of
   865                      NONE => NONE
   865                      NONE => NONE
   866                    | SOME u_name
   866                    | SOME u_name
   867                      => if u_name = s
   867                      => if u_name = s
   868                         then let
   868                         then let
   869                                val rv = ("r",rT)
   869                                val rv = ("r",rT)