src/HOL/Tools/record.ML
changeset 35147 9eb89f41c29d
parent 35146 f7bf73b0d7e5
child 35148 3a34fee2cfcd
equal deleted inserted replaced
35146:f7bf73b0d7e5 35147:9eb89f41c29d
   709 
   709 
   710 (* parse translations *)
   710 (* parse translations *)
   711 
   711 
   712 local
   712 local
   713 
   713 
   714 fun field_update_tr (Const (@{syntax_const "_field_update"}, _) $ Const (name, _) $ arg) =
   714 fun field_type_tr ((Const (@{syntax_const "_field_type"}, _) $ Const (name, _) $ arg)) =
   715       Syntax.const (suffix updateN name) $ Abs ("_", dummyT, arg)
   715       (name, arg)
   716   | field_update_tr t = raise TERM ("field_update_tr", [t]);
   716   | field_type_tr t = raise TERM ("field_type_tr", [t]);
   717 
   717 
   718 fun field_updates_tr (Const (@{syntax_const "_field_updates"}, _) $ t $ u) =
   718 fun field_types_tr (Const (@{syntax_const "_field_types"}, _) $ t $ u) =
   719       field_update_tr t :: field_updates_tr u
   719       field_type_tr t :: field_types_tr u
   720   | field_updates_tr t = [field_update_tr t];
   720   | field_types_tr t = [field_type_tr t];
   721 
   721 
   722 fun record_update_tr [t, u] = fold (curry op $) (field_updates_tr u) t
   722 fun record_field_types_tr more ctxt t =
   723   | record_update_tr ts = raise TERM ("record_update_tr", ts);
   723   let
       
   724     val thy = ProofContext.theory_of ctxt;
       
   725     fun err msg = raise TERM ("Error in record-type input: " ^ msg, [t]);
       
   726 
       
   727     fun split_args (field :: fields) ((name, arg) :: fargs) =
       
   728           if can (unsuffix name) field then
       
   729             let val (args, rest) = split_args fields fargs
       
   730             in (arg :: args, rest) end
       
   731           else err ("expecting field " ^ field ^ " but got " ^ name)
       
   732       | split_args [] (fargs as (_ :: _)) = ([], fargs)
       
   733       | split_args (_ :: _) [] = err "expecting more fields"
       
   734       | split_args _ _ = ([], []);
       
   735 
       
   736     fun mk_ext (fargs as (name, _) :: _) =
       
   737           (case get_fieldext thy (Sign.intern_const thy name) of
       
   738             SOME (ext, alphas) =>
       
   739               (case get_extfields thy ext of
       
   740                 SOME fields =>
       
   741                   let
       
   742                     val fields' = but_last fields;
       
   743                     val types = map snd fields';
       
   744                     val (args, rest) = split_args (map fst fields') fargs;
       
   745                     val argtypes = map (Sign.certify_typ thy o decode_type thy) args;
       
   746                     val midx = fold Term.maxidx_typ argtypes 0;
       
   747                     val varifyT = varifyT midx;
       
   748                     val vartypes = map varifyT types;
       
   749 
       
   750                     val subst = fold (Sign.typ_match thy) (vartypes ~~ argtypes) Vartab.empty
       
   751                       handle Type.TYPE_MATCH => err "type is no proper record (extension)";
       
   752                     val alphas' =
       
   753                       map (Syntax.term_of_typ (! Syntax.show_sorts) o Envir.norm_type subst o varifyT)
       
   754                         (but_last alphas);
       
   755 
       
   756                     val more' = mk_ext rest;
       
   757                   in
       
   758                     (* FIXME authentic syntax *)
       
   759                     list_comb (Syntax.const (suffix ext_typeN ext), alphas' @ [more'])
       
   760                   end
       
   761               | NONE => err ("no fields defined for " ^ ext))
       
   762           | NONE => err (name ^ " is no proper field"))
       
   763       | mk_ext [] = more;
       
   764   in
       
   765     mk_ext (field_types_tr t)
       
   766   end;
       
   767 
       
   768 (* FIXME @{type_syntax} *)
       
   769 fun record_type_tr ctxt [t] = record_field_types_tr (Syntax.const "Product_Type.unit") ctxt t
       
   770   | record_type_tr _ ts = raise TERM ("record_type_tr", ts);
       
   771 
       
   772 fun record_type_scheme_tr ctxt [t, more] = record_field_types_tr more ctxt t
       
   773   | record_type_scheme_tr _ ts = raise TERM ("record_type_scheme_tr", ts);
   724 
   774 
   725 
   775 
   726 fun field_tr ((Const (@{syntax_const "_field"}, _) $ Const (name, _) $ arg)) = (name, arg)
   776 fun field_tr ((Const (@{syntax_const "_field"}, _) $ Const (name, _) $ arg)) = (name, arg)
   727   | field_tr t = raise TERM ("field_tr", [t]);
   777   | field_tr t = raise TERM ("field_tr", [t]);
   728 
   778 
   766 
   816 
   767 fun record_scheme_tr ctxt [t, more] = record_fields_tr more ctxt t
   817 fun record_scheme_tr ctxt [t, more] = record_fields_tr more ctxt t
   768   | record_scheme_tr _ ts = raise TERM ("record_scheme_tr", ts);
   818   | record_scheme_tr _ ts = raise TERM ("record_scheme_tr", ts);
   769 
   819 
   770 
   820 
   771 fun field_type_tr ((Const (@{syntax_const "_field_type"}, _) $ Const (name, _) $ arg)) =
   821 fun field_update_tr (Const (@{syntax_const "_field_update"}, _) $ Const (name, _) $ arg) =
   772       (name, arg)
   822       Syntax.const (suffix updateN name) $ Abs ("_", dummyT, arg)
   773   | field_type_tr t = raise TERM ("field_type_tr", [t]);
   823   | field_update_tr t = raise TERM ("field_update_tr", [t]);
   774 
   824 
   775 fun field_types_tr (Const (@{syntax_const "_field_types"}, _) $ t $ u) =
   825 fun field_updates_tr (Const (@{syntax_const "_field_updates"}, _) $ t $ u) =
   776       field_type_tr t :: field_types_tr u
   826       field_update_tr t :: field_updates_tr u
   777   | field_types_tr t = [field_type_tr t];
   827   | field_updates_tr t = [field_update_tr t];
   778 
   828 
   779 fun record_field_types_tr more ctxt t =
   829 fun record_update_tr [t, u] = fold (curry op $) (field_updates_tr u) t
   780   let
   830   | record_update_tr ts = raise TERM ("record_update_tr", ts);
   781     val thy = ProofContext.theory_of ctxt;
       
   782     fun err msg = raise TERM ("Error in record-type input: " ^ msg, [t]);
       
   783 
       
   784     fun split_args (field :: fields) ((name, arg) :: fargs) =
       
   785           if can (unsuffix name) field then
       
   786             let val (args, rest) = split_args fields fargs
       
   787             in (arg :: args, rest) end
       
   788           else err ("expecting field " ^ field ^ " but got " ^ name)
       
   789       | split_args [] (fargs as (_ :: _)) = ([], fargs)
       
   790       | split_args (_ :: _) [] = err "expecting more fields"
       
   791       | split_args _ _ = ([], []);
       
   792 
       
   793     fun mk_ext (fargs as (name, _) :: _) =
       
   794           (case get_fieldext thy (Sign.intern_const thy name) of
       
   795             SOME (ext, alphas) =>
       
   796               (case get_extfields thy ext of
       
   797                 SOME fields =>
       
   798                   let
       
   799                     val fields' = but_last fields;
       
   800                     val types = map snd fields';
       
   801                     val (args, rest) = split_args (map fst fields') fargs;
       
   802                     val argtypes = map (Sign.certify_typ thy o decode_type thy) args;
       
   803                     val midx = fold Term.maxidx_typ argtypes 0;
       
   804                     val varifyT = varifyT midx;
       
   805                     val vartypes = map varifyT types;
       
   806 
       
   807                     val subst = fold (Sign.typ_match thy) (vartypes ~~ argtypes) Vartab.empty
       
   808                       handle Type.TYPE_MATCH => err "type is no proper record (extension)";
       
   809                     val alphas' =
       
   810                       map (Syntax.term_of_typ (! Syntax.show_sorts) o Envir.norm_type subst o varifyT)
       
   811                         (but_last alphas);
       
   812 
       
   813                     val more' = mk_ext rest;
       
   814                   in
       
   815                     (* FIXME authentic syntax *)
       
   816                     list_comb (Syntax.const (suffix ext_typeN ext), alphas' @ [more'])
       
   817                   end
       
   818               | NONE => err ("no fields defined for " ^ ext))
       
   819           | NONE => err (name ^ " is no proper field"))
       
   820       | mk_ext [] = more;
       
   821   in
       
   822     mk_ext (field_types_tr t)
       
   823   end;
       
   824 
       
   825 (* FIXME @{type_syntax} *)
       
   826 fun record_type_tr ctxt [t] = record_field_types_tr (Syntax.const "Product_Type.unit") ctxt t
       
   827   | record_type_tr _ ts = raise TERM ("record_type_tr", ts);
       
   828 
       
   829 fun record_type_scheme_tr ctxt [t, more] = record_field_types_tr more ctxt t
       
   830   | record_type_scheme_tr _ ts = raise TERM ("record_type_scheme_tr", ts);
       
   831 
   831 
   832 in
   832 in
   833 
   833 
   834 val parse_translation =
   834 val parse_translation =
   835  [(@{syntax_const "_record_update"}, record_update_tr)];
   835  [(@{syntax_const "_record_update"}, record_update_tr)];
  1427 fun record_split_simproc P =
  1427 fun record_split_simproc P =
  1428   Simplifier.simproc @{theory HOL} "record_split_simp" ["x"]
  1428   Simplifier.simproc @{theory HOL} "record_split_simp" ["x"]
  1429     (fn thy => fn _ => fn t =>
  1429     (fn thy => fn _ => fn t =>
  1430       (case t of
  1430       (case t of
  1431         Const (quantifier, Type (_, [Type (_, [T, _]), _])) $ _ =>
  1431         Const (quantifier, Type (_, [Type (_, [T, _]), _])) $ _ =>
  1432           if quantifier = @{const_name All} orelse
  1432           if quantifier = @{const_name all} orelse
  1433             quantifier = @{const_name all} orelse
  1433             quantifier = @{const_name All} orelse
  1434             quantifier = @{const_name Ex}
  1434             quantifier = @{const_name Ex}
  1435           then
  1435           then
  1436             (case rec_id ~1 T of
  1436             (case rec_id ~1 T of
  1437               "" => NONE
  1437               "" => NONE
  1438             | _ =>
  1438             | _ =>
  1552   end);
  1552   end);
  1553 
  1553 
  1554 
  1554 
  1555 (* record_split_tac *)
  1555 (* record_split_tac *)
  1556 
  1556 
  1557 (*Split all records in the goal, which are quantified by ALL or !!.*)
  1557 (*Split all records in the goal, which are quantified by !! or ALL.*)
  1558 val record_split_tac = CSUBGOAL (fn (cgoal, i) =>
  1558 val record_split_tac = CSUBGOAL (fn (cgoal, i) =>
  1559   let
  1559   let
  1560     val goal = term_of cgoal;
  1560     val goal = term_of cgoal;
  1561 
  1561 
  1562     val has_rec = exists_Const
  1562     val has_rec = exists_Const
  1563       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1563       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1564           (s = @{const_name All} orelse s = @{const_name all}) andalso is_recT T
  1564           (s = @{const_name all} orelse s = @{const_name All}) andalso is_recT T
  1565         | _ => false);
  1565         | _ => false);
  1566 
  1566 
  1567     fun is_all t =
  1567     fun is_all t =
  1568       (case t of
  1568       (case t of
  1569         Const (quantifier, _) $ _ =>
  1569         Const (quantifier, _) $ _ =>
  1570           if quantifier = @{const_name All} orelse quantifier = @{const_name all} then ~1 else 0
  1570           if quantifier = @{const_name all} orelse quantifier = @{const_name All} then ~1 else 0
  1571       | _ => 0);
  1571       | _ => 0);
  1572   in
  1572   in
  1573     if has_rec goal then
  1573     if has_rec goal then
  1574       Simplifier.full_simp_tac (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i
  1574       Simplifier.full_simp_tac (HOL_basic_ss addsimprocs [record_split_simproc is_all]) i
  1575     else no_tac
  1575     else no_tac