src/HOL/Tools/record.ML
changeset 35144 8b8302da3a55
parent 35142 495c623f1e3c
child 35145 f132a4fd8679
equal deleted inserted replaced
35143:7b2538c987e7 35144:8b8302da3a55
   268 (* syntax *)
   268 (* syntax *)
   269 
   269 
   270 val Trueprop = HOLogic.mk_Trueprop;
   270 val Trueprop = HOLogic.mk_Trueprop;
   271 fun All xs t = Term.list_all_free (xs, t);
   271 fun All xs t = Term.list_all_free (xs, t);
   272 
   272 
   273 infix 9 $$;
       
   274 infix 0 :== ===;
   273 infix 0 :== ===;
   275 infixr 0 ==>;
   274 infixr 0 ==>;
   276 
   275 
   277 val op $$ = Term.list_comb;
       
   278 val op :== = Primitive_Defs.mk_defpair;
   276 val op :== = Primitive_Defs.mk_defpair;
   279 val op === = Trueprop o HOLogic.mk_eq;
   277 val op === = Trueprop o HOLogic.mk_eq;
   280 val op ==> = Logic.mk_implies;
   278 val op ==> = Logic.mk_implies;
   281 
   279 
   282 
   280 
   584 
   582 
   585 fun add_extsplit name thm thy =
   583 fun add_extsplit name thm thy =
   586   let
   584   let
   587     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
   585     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
   588       Records_Data.get thy;
   586       Records_Data.get thy;
   589     val data = make_record_data records sel_upd
   587     val data =
   590       equalities extinjects (Symtab.update_new (name, thm) extsplit) splits
   588       make_record_data records sel_upd equalities extinjects
   591       extfields fieldext;
   589         (Symtab.update_new (name, thm) extsplit) splits extfields fieldext;
   592   in Records_Data.put data thy end;
   590   in Records_Data.put data thy end;
   593 
   591 
   594 
   592 
   595 (* access 'splits' *)
   593 (* access 'splits' *)
   596 
   594 
   597 fun add_record_splits name thmP thy =
   595 fun add_record_splits name thmP thy =
   598   let
       
   599     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
       
   600       Records_Data.get thy;
       
   601     val data = make_record_data records sel_upd
       
   602       equalities extinjects extsplit (Symtab.update_new (name, thmP) splits)
       
   603       extfields fieldext;
       
   604   in Records_Data.put data thy end;
       
   605 
       
   606 val get_splits = Symtab.lookup o #splits o Records_Data.get;
       
   607 
       
   608 
       
   609 (* parent/extension of named record *)
       
   610 
       
   611 val get_parent = (Option.join o Option.map #parent) oo (Symtab.lookup o #records o Records_Data.get);
       
   612 val get_extension = Option.map #extension oo (Symtab.lookup o #records o Records_Data.get);
       
   613 
       
   614 
       
   615 (* access 'extfields' *)
       
   616 
       
   617 fun add_extfields name fields thy =
       
   618   let
   596   let
   619     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
   597     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
   620       Records_Data.get thy;
   598       Records_Data.get thy;
   621     val data =
   599     val data =
   622       make_record_data records sel_upd
   600       make_record_data records sel_upd equalities extinjects extsplit
   623         equalities extinjects extsplit splits
   601         (Symtab.update_new (name, thmP) splits) extfields fieldext;
       
   602   in Records_Data.put data thy end;
       
   603 
       
   604 val get_splits = Symtab.lookup o #splits o Records_Data.get;
       
   605 
       
   606 
       
   607 (* parent/extension of named record *)
       
   608 
       
   609 val get_parent = (Option.join o Option.map #parent) oo (Symtab.lookup o #records o Records_Data.get);
       
   610 val get_extension = Option.map #extension oo (Symtab.lookup o #records o Records_Data.get);
       
   611 
       
   612 
       
   613 (* access 'extfields' *)
       
   614 
       
   615 fun add_extfields name fields thy =
       
   616   let
       
   617     val {records, sel_upd, equalities, extinjects, extsplit, splits, extfields, fieldext} =
       
   618       Records_Data.get thy;
       
   619     val data =
       
   620       make_record_data records sel_upd equalities extinjects extsplit splits
   624         (Symtab.update_new (name, fields) extfields) fieldext;
   621         (Symtab.update_new (name, fields) extfields) fieldext;
   625   in Records_Data.put data thy end;
   622   in Records_Data.put data thy end;
   626 
   623 
   627 val get_extfields = Symtab.lookup o #extfields o Records_Data.get;
   624 val get_extfields = Symtab.lookup o #extfields o Records_Data.get;
   628 
   625 
   699 
   696 
   700 (* decode type *)
   697 (* decode type *)
   701 
   698 
   702 fun decode_type thy t =
   699 fun decode_type thy t =
   703   let
   700   let
   704     fun get_sort xs n = AList.lookup (op =) xs (n: indexname) |> the_default (Sign.defaultS thy);
   701     fun get_sort env xi =
       
   702       the_default (Sign.defaultS thy) (AList.lookup (op =) env (xi: indexname));
   705     val map_sort = Sign.intern_sort thy;
   703     val map_sort = Sign.intern_sort thy;
   706   in
   704   in
   707     Syntax.typ_of_term (get_sort (Syntax.term_sorts map_sort t)) map_sort t
   705     Syntax.typ_of_term (get_sort (Syntax.term_sorts map_sort t)) map_sort t
   708     |> Sign.intern_tycons thy
   706     |> Sign.intern_tycons thy
   709   end;
   707   end;
   710 
   708 
   711 
   709 
   712 (* parse translations *)
   710 (* parse translations *)
   713 
   711 
       
   712 local
       
   713 
   714 fun gen_field_tr mark sfx (t as Const (c, _) $ Const (name, _) $ arg) =
   714 fun gen_field_tr mark sfx (t as Const (c, _) $ Const (name, _) $ arg) =
   715       if c = mark then Syntax.const (suffix sfx name) $ Abs ("_", dummyT, arg)
   715       if c = mark then Syntax.const (suffix sfx name) $ Abs ("_", dummyT, arg)
   716       else raise TERM ("gen_field_tr: " ^ mark, [t])
   716       else raise TERM ("gen_field_tr: " ^ mark, [t])
   717   | gen_field_tr mark _ t = raise TERM ("gen_field_tr: " ^ mark, [t]);
   717   | gen_field_tr mark _ t = raise TERM ("gen_field_tr: " ^ mark, [t]);
   718 
   718 
   719 fun gen_fields_tr sep mark sfx (tm as Const (c, _) $ t $ u) =
   719 fun gen_fields_tr sep mark sfx (tm as Const (c, _) $ t $ u) =
   720       if c = sep then gen_field_tr mark sfx t :: gen_fields_tr sep mark sfx u
   720       if c = sep then gen_field_tr mark sfx t :: gen_fields_tr sep mark sfx u
   721       else [gen_field_tr mark sfx tm]
   721       else [gen_field_tr mark sfx tm]
   722   | gen_fields_tr _ mark sfx tm = [gen_field_tr mark sfx tm];
   722   | gen_fields_tr _ mark sfx tm = [gen_field_tr mark sfx tm];
   723 
   723 
       
   724 in
   724 
   725 
   725 fun record_update_tr [t, u] =
   726 fun record_update_tr [t, u] =
   726       fold (curry op $)
   727       fold (curry op $)
   727         (gen_fields_tr @{syntax_const "_updates"} @{syntax_const "_update"} updateN u) t
   728         (gen_fields_tr @{syntax_const "_updates"} @{syntax_const "_update"} updateN u) t
   728   | record_update_tr ts = raise TERM ("record_update_tr", ts);
   729   | record_update_tr ts = raise TERM ("record_update_tr", ts);
   729 
   730 
   730 fun update_name_tr (Free (x, T) :: ts) = Free (suffix updateN x, T) $$ ts
   731 end;
   731   | update_name_tr (Const (x, T) :: ts) = Const (suffix updateN x, T) $$ ts
   732 
       
   733 fun update_name_tr (Free (x, T) :: ts) = list_comb (Free (suffix updateN x, T), ts)
       
   734   | update_name_tr (Const (x, T) :: ts) = list_comb (Const (suffix updateN x, T), ts)
   732   | update_name_tr (((c as Const (@{syntax_const "_constrain"}, _)) $ t $ ty) :: ts) =
   735   | update_name_tr (((c as Const (@{syntax_const "_constrain"}, _)) $ t $ ty) :: ts) =
   733       (* FIXME @{type_syntax} *)
   736       (* FIXME @{type_syntax} *)
   734       (c $ update_name_tr [t] $ (Syntax.const "fun" $ ty $ Syntax.const "dummy")) $$ ts
   737       list_comb (c $ update_name_tr [t] $ (Syntax.const "fun" $ ty $ Syntax.const "dummy"), ts)
   735   | update_name_tr ts = raise TERM ("update_name_tr", ts);
   738   | update_name_tr ts = raise TERM ("update_name_tr", ts);
   736 
   739 
   737 fun dest_ext_field mark (t as (Const (c, _) $ Const (name, _) $ arg)) =
   740 fun dest_ext_field mark (t as (Const (c, _) $ Const (name, _) $ arg)) =
   738       if c = mark then (name, arg)
   741       if c = mark then (name, arg)
   739       else raise TERM ("dest_ext_field: " ^ mark, [t])
   742       else raise TERM ("dest_ext_field: " ^ mark, [t])
  2089           else raise TERM ("mk_sel_spec: different arg", [arg]);
  2092           else raise TERM ("mk_sel_spec: different arg", [arg]);
  2090       in Const (mk_updC updateN rec_schemeT0 (c, T)) :== upd end;
  2093       in Const (mk_updC updateN rec_schemeT0 (c, T)) :== upd end;
  2091     val upd_specs = map mk_upd_spec (fields_more ~~ lastN updator_thms);
  2094     val upd_specs = map mk_upd_spec (fields_more ~~ lastN updator_thms);
  2092 
  2095 
  2093     (*derived operations*)
  2096     (*derived operations*)
  2094     val make_spec = Const (full (Binding.name makeN), all_types ---> recT0) $$ all_vars :==
  2097     val make_spec =
  2095       mk_rec (all_vars @ [HOLogic.unit]) 0;
  2098       list_comb (Const (full (Binding.name makeN), all_types ---> recT0), all_vars) :==
  2096     val fields_spec = Const (full (Binding.name fields_selN), types ---> Type extension) $$ vars :==
  2099         mk_rec (all_vars @ [HOLogic.unit]) 0;
  2097       mk_rec (all_vars @ [HOLogic.unit]) parent_len;
  2100     val fields_spec =
       
  2101       list_comb (Const (full (Binding.name fields_selN), types ---> Type extension), vars) :==
       
  2102         mk_rec (all_vars @ [HOLogic.unit]) parent_len;
  2098     val extend_spec =
  2103     val extend_spec =
  2099       Const (full (Binding.name extendN), recT0 --> moreT --> rec_schemeT0) $ r_unit0 $ more :==
  2104       Const (full (Binding.name extendN), recT0 --> moreT --> rec_schemeT0) $ r_unit0 $ more :==
  2100       mk_rec ((map (mk_sel r_unit0) all_fields) @ [more]) 0;
  2105         mk_rec ((map (mk_sel r_unit0) all_fields) @ [more]) 0;
  2101     val truncate_spec = Const (full (Binding.name truncateN), rec_schemeT0 --> recT0) $ r0 :==
  2106     val truncate_spec =
  2102       mk_rec ((map (mk_sel r0) all_fields) @ [HOLogic.unit]) 0;
  2107       Const (full (Binding.name truncateN), rec_schemeT0 --> recT0) $ r0 :==
       
  2108         mk_rec ((map (mk_sel r0) all_fields) @ [HOLogic.unit]) 0;
  2103 
  2109 
  2104 
  2110 
  2105     (* 2st stage: defs_thy *)
  2111     (* 2st stage: defs_thy *)
  2106 
  2112 
  2107     fun mk_defs () =
  2113     fun mk_defs () =