src/HOL/Tools/record.ML
changeset 35135 1667fd3b051d
parent 35133 a68e4972fd31
child 35136 34206672b168
equal deleted inserted replaced
35134:d8d6c2f55c0c 35135:1667fd3b051d
    69 
    69 
    70 val tuple_iso_tuple = (@{const_name tuple_iso_tuple}, @{thm tuple_iso_tuple});
    70 val tuple_iso_tuple = (@{const_name tuple_iso_tuple}, @{thm tuple_iso_tuple});
    71 
    71 
    72 fun named_cterm_instantiate values thm =
    72 fun named_cterm_instantiate values thm =
    73   let
    73   let
    74     fun match name ((name', _), _) = name = name'
    74     fun match name ((name', _), _) = name = name';
    75       | match name _ = false;
       
    76     fun getvar name =
    75     fun getvar name =
    77       (case find_first (match name) (Term.add_vars (prop_of thm) []) of
    76       (case find_first (match name) (Term.add_vars (prop_of thm) []) of
    78         SOME var => cterm_of (theory_of_thm thm) (Var var)
    77         SOME var => cterm_of (theory_of_thm thm) (Var var)
    79       | NONE => raise THM ("named_cterm_instantiate: " ^ name, 0, [thm]));
    78       | NONE => raise THM ("named_cterm_instantiate: " ^ name, 0, [thm]));
    80   in
    79   in
    91 
    90 
    92 fun do_typedef name repT alphas thy =
    91 fun do_typedef name repT alphas thy =
    93   let
    92   let
    94     fun get_thms thy name =
    93     fun get_thms thy name =
    95       let
    94       let
    96         val SOME {Rep_inject = rep_inject, Abs_name = absN, abs_type = absT,
    95         val {Rep_inject = rep_inject, Abs_name = absN, abs_type = absT,
    97           Abs_inverse = abs_inverse, ...} = Typedef.get_info thy name;
    96           Abs_inverse = abs_inverse, ...} = Typedef.the_info thy name;
    98         val rewrite_rule =
    97         val rewrite_rule =
    99           MetaSimplifier.rewrite_rule [@{thm iso_tuple_UNIV_I}, @{thm iso_tuple_True_simp}];
    98           MetaSimplifier.rewrite_rule [@{thm iso_tuple_UNIV_I}, @{thm iso_tuple_True_simp}];
   100       in
    99       in
   101         (map rewrite_rule [rep_inject, abs_inverse], Const (absN, repT --> absT), absT)
   100         (map rewrite_rule [rep_inject, abs_inverse], Const (absN, repT --> absT), absT)
   102       end;
   101       end;
   370     foldcong: Simplifier.simpset,
   369     foldcong: Simplifier.simpset,
   371     unfoldcong: Simplifier.simpset},
   370     unfoldcong: Simplifier.simpset},
   372   equalities: thm Symtab.table,
   371   equalities: thm Symtab.table,
   373   extinjects: thm list,
   372   extinjects: thm list,
   374   extsplit: thm Symtab.table,  (*maps extension name to split rule*)
   373   extsplit: thm Symtab.table,  (*maps extension name to split rule*)
   375   splits: (thm * thm * thm * thm) Symtab.table,  (*!!, !, EX - split-equalities, induct rule*)
   374   splits: (thm * thm * thm * thm) Symtab.table,  (*!!, ALL, EX - split-equalities, induct rule*)
   376   extfields: (string * typ) list Symtab.table,  (*maps extension to its fields*)
   375   extfields: (string * typ) list Symtab.table,  (*maps extension to its fields*)
   377   fieldext: (string * typ list) Symtab.table};  (*maps field to its extension*)
   376   fieldext: (string * typ list) Symtab.table};  (*maps field to its extension*)
   378 
   377 
   379 fun make_record_data
   378 fun make_record_data
   380     records sel_upd equalities extinjects extsplit splits extfields fieldext =
   379     records sel_upd equalities extinjects extsplit splits extfields fieldext =
   697   | dest_ext_fields _ mark t = [dest_ext_field mark t];
   696   | dest_ext_fields _ mark t = [dest_ext_field mark t];
   698 
   697 
   699 fun gen_ext_fields_tr sep mark sfx more ctxt t =
   698 fun gen_ext_fields_tr sep mark sfx more ctxt t =
   700   let
   699   let
   701     val thy = ProofContext.theory_of ctxt;
   700     val thy = ProofContext.theory_of ctxt;
   702     val msg = "error in record input: ";
   701     fun err msg = raise TERM ("error in record input: " ^ msg, [t]);
   703 
   702 
   704     val fieldargs = dest_ext_fields sep mark t;
   703     val fieldargs = dest_ext_fields sep mark t;
   705     fun splitargs (field :: fields) ((name, arg) :: fargs) =
   704     fun splitargs (field :: fields) ((name, arg) :: fargs) =
   706           if can (unsuffix name) field
   705           if can (unsuffix name) field
   707           then
   706           then
   708             let val (args, rest) = splitargs fields fargs
   707             let val (args, rest) = splitargs fields fargs
   709             in (arg :: args, rest) end
   708             in (arg :: args, rest) end
   710           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   709           else err ("expecting field " ^ field ^ " but got " ^ name)
   711       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   710       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   712       | splitargs (_ :: _) [] = raise TERM (msg ^ "expecting more fields", [t])
   711       | splitargs (_ :: _) [] = err "expecting more fields"
   713       | splitargs _ _ = ([], []);
   712       | splitargs _ _ = ([], []);
   714 
   713 
   715     fun mk_ext (fargs as (name, _) :: _) =
   714     fun mk_ext (fargs as (name, _) :: _) =
   716           (case get_fieldext thy (Sign.intern_const thy name) of
   715           (case get_fieldext thy (Sign.intern_const thy name) of
   717             SOME (ext, _) =>
   716             SOME (ext, _) =>
   719                 SOME flds =>
   718                 SOME flds =>
   720                   let
   719                   let
   721                     val (args, rest) = splitargs (map fst (but_last flds)) fargs;
   720                     val (args, rest) = splitargs (map fst (but_last flds)) fargs;
   722                     val more' = mk_ext rest;
   721                     val more' = mk_ext rest;
   723                   in list_comb (Syntax.const (suffix sfx ext), args @ [more']) end
   722                   in list_comb (Syntax.const (suffix sfx ext), args @ [more']) end
   724               | NONE => raise TERM (msg ^ "no fields defined for " ^ ext, [t]))
   723               | NONE => err ("no fields defined for " ^ ext))
   725           | NONE => raise TERM (msg ^ name ^ " is no proper field", [t]))
   724           | NONE => err (name ^ " is no proper field"))
   726       | mk_ext [] = more;
   725       | mk_ext [] = more;
   727   in mk_ext fieldargs end;
   726   in mk_ext fieldargs end;
   728 
   727 
   729 fun gen_ext_type_tr sep mark sfx more ctxt t =
   728 fun gen_ext_type_tr sep mark sfx more ctxt t =
   730   let
   729   let
   731     val thy = ProofContext.theory_of ctxt;
   730     val thy = ProofContext.theory_of ctxt;
   732     val msg = "error in record-type input: ";
   731     fun err msg = raise TERM ("error in record-type input: " ^ msg, [t]);
   733 
   732 
   734     val fieldargs = dest_ext_fields sep mark t;
   733     val fieldargs = dest_ext_fields sep mark t;
   735     fun splitargs (field :: fields) ((name, arg) :: fargs) =
   734     fun splitargs (field :: fields) ((name, arg) :: fargs) =
   736           if can (unsuffix name) field then
   735           if can (unsuffix name) field then
   737             let val (args, rest) = splitargs fields fargs
   736             let val (args, rest) = splitargs fields fargs
   738             in (arg :: args, rest) end
   737             in (arg :: args, rest) end
   739           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   738           else err ("expecting field " ^ field ^ " but got " ^ name)
   740       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   739       | splitargs [] (fargs as (_ :: _)) = ([], fargs)
   741       | splitargs (_ :: _) [] = raise TERM (msg ^ "expecting more fields", [t])
   740       | splitargs (_ :: _) [] = err "expecting more fields"
   742       | splitargs _ _ = ([], []);
   741       | splitargs _ _ = ([], []);
   743 
   742 
   744     fun mk_ext (fargs as (name, _) :: _) =
   743     fun mk_ext (fargs as (name, _) :: _) =
   745           (case get_fieldext thy (Sign.intern_const thy name) of
   744           (case get_fieldext thy (Sign.intern_const thy name) of
   746             SOME (ext, alphas) =>
   745             SOME (ext, alphas) =>
   762 
   761 
   763                     val more' = mk_ext rest;
   762                     val more' = mk_ext rest;
   764                   in
   763                   in
   765                     list_comb (Syntax.const (suffix sfx ext), alphas' @ [more'])
   764                     list_comb (Syntax.const (suffix sfx ext), alphas' @ [more'])
   766                   end handle Type.TYPE_MATCH =>
   765                   end handle Type.TYPE_MATCH =>
   767                     raise TERM (msg ^ "type is no proper record (extension)", [t]))
   766                     raise err "type is no proper record (extension)")
   768               | NONE => raise TERM (msg ^ "no fields defined for " ^ ext, [t]))
   767               | NONE => err ("no fields defined for " ^ ext))
   769           | NONE => raise TERM (msg ^ name ^" is no proper field", [t]))
   768           | NONE => err (name ^ " is no proper field"))
   770       | mk_ext [] = more;
   769       | mk_ext [] = more;
   771 
   770 
   772   in mk_ext fieldargs end;
   771   in mk_ext fieldargs end;
   773 
   772 
   774 fun gen_adv_record_tr sep mark sfx unit ctxt [t] =
   773 fun gen_adv_record_tr sep mark sfx unit ctxt [t] =
  1514   end);
  1513   end);
  1515 
  1514 
  1516 
  1515 
  1517 (* record_split_tac *)
  1516 (* record_split_tac *)
  1518 
  1517 
  1519 (*Split all records in the goal, which are quantified by ! or !!.*)
  1518 (*Split all records in the goal, which are quantified by ALL or !!.*)
  1520 val record_split_tac = CSUBGOAL (fn (cgoal, i) =>
  1519 val record_split_tac = CSUBGOAL (fn (cgoal, i) =>
  1521   let
  1520   let
  1522     val goal = term_of cgoal;
  1521     val goal = term_of cgoal;
  1523 
  1522 
  1524     val has_rec = exists_Const
  1523     val has_rec = exists_Const
  2020     val sel_specs = map mk_sel_spec (fields_more ~~ lastN accessor_thms);
  2019     val sel_specs = map mk_sel_spec (fields_more ~~ lastN accessor_thms);
  2021 
  2020 
  2022     (*updates*)
  2021     (*updates*)
  2023     fun mk_upd_spec ((c, T), thm) =
  2022     fun mk_upd_spec ((c, T), thm) =
  2024       let
  2023       let
  2025         val (upd $ _ $ arg) =
  2024         val upd $ _ $ arg =
  2026           (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o Envir.beta_eta_contract o concl_of) thm;
  2025           fst (HOLogic.dest_eq (HOLogic.dest_Trueprop (Envir.beta_eta_contract (concl_of thm))));
  2027         val _ =
  2026         val _ =
  2028           if (arg aconv r_rec0) then ()
  2027           if arg aconv r_rec0 then ()
  2029           else raise TERM ("mk_sel_spec: different arg", [arg]);
  2028           else raise TERM ("mk_sel_spec: different arg", [arg]);
  2030       in Const (mk_updC updateN rec_schemeT0 (c, T)) :== upd end;
  2029       in Const (mk_updC updateN rec_schemeT0 (c, T)) :== upd end;
  2031     val upd_specs = map mk_upd_spec (fields_more ~~ lastN updator_thms);
  2030     val upd_specs = map mk_upd_spec (fields_more ~~ lastN updator_thms);
  2032 
  2031 
  2033     (*derived operations*)
  2032     (*derived operations*)