src/Pure/Isar/code.ML
changeset 31957 a9742afd403e
parent 31890 e943b039f0ac
child 31962 baa8dce5bc45
equal deleted inserted replaced
31956:c3844c4d0c2c 31957:a9742afd403e
     5 executable content.  Cache assumes non-concurrent processing of a single theory.
     5 executable content.  Cache assumes non-concurrent processing of a single theory.
     6 *)
     6 *)
     7 
     7 
     8 signature CODE =
     8 signature CODE =
     9 sig
     9 sig
       
    10   (*constants*)
       
    11   val string_of_const: theory -> string -> string
       
    12   val args_number: theory -> string -> int
       
    13   val check_const: theory -> term -> string
       
    14   val read_bare_const: theory -> string -> string * typ
       
    15   val read_const: theory -> string -> string
       
    16   val typscheme: theory -> string * typ -> (string * sort) list * typ
       
    17 
    10   (*constructor sets*)
    18   (*constructor sets*)
    11   val constrset_of_consts: theory -> (string * typ) list
    19   val constrset_of_consts: theory -> (string * typ) list
    12     -> string * ((string * sort) list * (string * typ list) list)
    20     -> string * ((string * sort) list * (string * typ list) list)
    13 
       
    14   (*typ instantiations*)
       
    15   val typscheme: theory -> string * typ -> (string * sort) list * typ
       
    16   val inst_thm: theory -> sort Vartab.table -> thm -> thm
       
    17 
       
    18   (*constants*)
       
    19   val string_of_typ: theory -> typ -> string
       
    20   val string_of_const: theory -> string -> string
       
    21   val no_args: theory -> string -> int
       
    22   val check_const: theory -> term -> string
       
    23   val read_bare_const: theory -> string -> string * typ
       
    24   val read_const: theory -> string -> string
       
    25 
    21 
    26   (*constant aliasses*)
    22   (*constant aliasses*)
    27   val add_const_alias: thm -> theory -> theory
    23   val add_const_alias: thm -> theory -> theory
    28   val triv_classes: theory -> class list
    24   val triv_classes: theory -> class list
    29   val resubst_alias: theory -> string -> string
    25   val resubst_alias: theory -> string -> string
    33   val mk_eqn_warning: theory -> (string -> bool) -> thm -> (thm * bool) option
    29   val mk_eqn_warning: theory -> (string -> bool) -> thm -> (thm * bool) option
    34   val mk_eqn_liberal: theory -> (string -> bool) -> thm -> (thm * bool) option
    30   val mk_eqn_liberal: theory -> (string -> bool) -> thm -> (thm * bool) option
    35   val assert_eqn: theory -> thm * bool -> thm * bool
    31   val assert_eqn: theory -> thm * bool -> thm * bool
    36   val assert_eqns_const: theory -> string
    32   val assert_eqns_const: theory -> string
    37     -> (thm * bool) list -> (thm * bool) list
    33     -> (thm * bool) list -> (thm * bool) list
    38   val const_typ_eqn: thm -> string * typ
    34   val const_typ_eqn: theory -> thm -> string * typ
    39   val const_eqn: theory -> thm -> string
       
    40   val typscheme_eqn: theory -> thm -> (string * sort) list * typ
    35   val typscheme_eqn: theory -> thm -> (string * sort) list * typ
    41   val expand_eta: theory -> int -> thm -> thm
    36   val expand_eta: theory -> int -> thm -> thm
    42   val rewrite_eqn: simpset -> thm -> thm
       
    43   val rewrite_head: thm list -> thm -> thm
       
    44   val norm_args: theory -> thm list -> thm list 
    37   val norm_args: theory -> thm list -> thm list 
    45   val norm_varnames: theory -> thm list -> thm list
    38   val norm_varnames: theory -> thm list -> thm list
    46 
       
    47   (*case certificates*)
       
    48   val case_cert: thm -> string * (int * string list)
       
    49 
       
    50   (*infrastructure*)
       
    51   val add_attribute: string * attribute parser -> theory -> theory
       
    52   val purge_data: theory -> theory
       
    53 
    39 
    54   (*executable content*)
    40   (*executable content*)
    55   val add_datatype: (string * typ) list -> theory -> theory
    41   val add_datatype: (string * typ) list -> theory -> theory
    56   val add_datatype_cmd: string list -> theory -> theory
    42   val add_datatype_cmd: string list -> theory -> theory
    57   val type_interpretation:
    43   val type_interpretation:
    58     (string * ((string * sort) list * (string * typ list) list)
    44     (string * ((string * sort) list * (string * typ list) list)
    59       -> theory -> theory) -> theory -> theory
    45       -> theory -> theory) -> theory -> theory
    60   val add_eqn: thm -> theory -> theory
    46   val add_eqn: thm -> theory -> theory
       
    47   val add_eqnl: string * (thm * bool) list lazy -> theory -> theory
    61   val add_nbe_eqn: thm -> theory -> theory
    48   val add_nbe_eqn: thm -> theory -> theory
    62   val add_default_eqn: thm -> theory -> theory
    49   val add_default_eqn: thm -> theory -> theory
    63   val add_default_eqn_attribute: attribute
    50   val add_default_eqn_attribute: attribute
    64   val add_default_eqn_attrib: Attrib.src
    51   val add_default_eqn_attrib: Attrib.src
    65   val del_eqn: thm -> theory -> theory
    52   val del_eqn: thm -> theory -> theory
    66   val del_eqns: string -> theory -> theory
    53   val del_eqns: string -> theory -> theory
    67   val add_eqnl: string * (thm * bool) list lazy -> theory -> theory
       
    68   val add_case: thm -> theory -> theory
    54   val add_case: thm -> theory -> theory
    69   val add_undefined: string -> theory -> theory
    55   val add_undefined: string -> theory -> theory
    70 
       
    71   (*data retrieval*)
       
    72   val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list)
    56   val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list)
    73   val get_datatype_of_constr: theory -> string -> string option
    57   val get_datatype_of_constr: theory -> string -> string option
    74   val default_typscheme: theory -> string -> (string * sort) list * typ
       
    75   val these_eqns: theory -> string -> (thm * bool) list
    58   val these_eqns: theory -> string -> (thm * bool) list
    76   val all_eqns: theory -> (thm * bool) list
    59   val all_eqns: theory -> (thm * bool) list
    77   val get_case_scheme: theory -> string -> (int * (int * string list)) option
    60   val get_case_scheme: theory -> string -> (int * (int * string list)) option
    78   val undefineds: theory -> string list
    61   val undefineds: theory -> string list
    79   val print_codesetup: theory -> unit
    62   val print_codesetup: theory -> unit
       
    63 
       
    64   (*infrastructure*)
       
    65   val add_attribute: string * attribute parser -> theory -> theory
       
    66   val purge_data: theory -> theory
    80 end;
    67 end;
    81 
    68 
    82 signature CODE_DATA_ARGS =
    69 signature CODE_DATA_ARGS =
    83 sig
    70 sig
    84   type T
    71   type T
   115 fun string_of_typ thy = setmp show_sorts true (Syntax.string_of_typ_global thy);
   102 fun string_of_typ thy = setmp show_sorts true (Syntax.string_of_typ_global thy);
   116 fun string_of_const thy c = case AxClass.inst_of_param thy c
   103 fun string_of_const thy c = case AxClass.inst_of_param thy c
   117  of SOME (c, tyco) => Sign.extern_const thy c ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco)
   104  of SOME (c, tyco) => Sign.extern_const thy c ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco)
   118   | NONE => Sign.extern_const thy c;
   105   | NONE => Sign.extern_const thy c;
   119 
   106 
   120 fun no_args thy = length o fst o strip_type o Sign.the_const_type thy;
   107 fun args_number thy = length o fst o strip_type o Sign.the_const_type thy;
   121 
   108 
   122 
   109 
   123 (* utilities *)
   110 (* utilities *)
   124 
   111 
   125 fun typscheme thy (c, ty) =
   112 fun typscheme thy (c, ty) =
   126   let
   113   let
   127     val ty' = Logic.unvarifyT ty;
   114     val ty' = Logic.unvarifyT ty;
   128     fun dest (TFree (v, sort)) = (v, sort)
   115   in (map dest_TFree (Sign.const_typargs thy (c, ty')), Type.strip_sorts ty') end;
   129       | dest ty = error ("Illegal type parameter in type scheme: " ^ Syntax.string_of_typ_global thy ty);
       
   130     val vs = map dest (Sign.const_typargs thy (c, ty'));
       
   131   in (vs, Type.strip_sorts ty') end;
       
   132 
       
   133 fun inst_thm thy tvars' thm =
       
   134   let
       
   135     val tvars = (Term.add_tvars o Thm.prop_of) thm [];
       
   136     val inter_sort = Sorts.inter_sort (Sign.classes_of thy);
       
   137     fun mk_inst (tvar as (v, sort)) = case Vartab.lookup tvars' v
       
   138      of SOME sort' => SOME (pairself (Thm.ctyp_of thy o TVar)
       
   139           (tvar, (v, inter_sort (sort, sort'))))
       
   140       | NONE => NONE;
       
   141     val insts = map_filter mk_inst tvars;
       
   142   in Thm.instantiate (insts, []) thm end;
       
   143 
   116 
   144 fun expand_eta thy k thm =
   117 fun expand_eta thy k thm =
   145   let
   118   let
   146     val (lhs, rhs) = (Logic.dest_equals o Thm.plain_prop_of) thm;
   119     val (lhs, rhs) = (Logic.dest_equals o Thm.plain_prop_of) thm;
   147     val (head, args) = strip_comb lhs;
   120     val (head, args) = strip_comb lhs;
   171     thm
   144     thm
   172     |> fold expand vs
   145     |> fold expand vs
   173     |> Conv.fconv_rule Drule.beta_eta_conversion
   146     |> Conv.fconv_rule Drule.beta_eta_conversion
   174   end;
   147   end;
   175 
   148 
   176 fun eqn_conv conv =
       
   177   let
       
   178     fun lhs_conv ct = if can Thm.dest_comb ct
       
   179       then (Conv.combination_conv lhs_conv conv) ct
       
   180       else Conv.all_conv ct;
       
   181   in Conv.combination_conv (Conv.arg_conv lhs_conv) conv end;
       
   182 
       
   183 fun head_conv conv =
       
   184   let
       
   185     fun lhs_conv ct = if can Thm.dest_comb ct
       
   186       then (Conv.fun_conv lhs_conv) ct
       
   187       else conv ct;
       
   188   in Conv.fun_conv (Conv.arg_conv lhs_conv) end;
       
   189 
       
   190 val rewrite_eqn = Conv.fconv_rule o eqn_conv o Simplifier.rewrite;
       
   191 val rewrite_head = Conv.fconv_rule o head_conv o MetaSimplifier.rewrite false;
       
   192 
       
   193 fun norm_args thy thms =
   149 fun norm_args thy thms =
   194   let
   150   let
   195     val num_args_of = length o snd o strip_comb o fst o Logic.dest_equals;
   151     val num_args_of = length o snd o strip_comb o fst o Logic.dest_equals;
   196     val k = fold (curry Int.max o num_args_of o Thm.prop_of) thms 0;
   152     val k = fold (curry Int.max o num_args_of o Thm.prop_of) thms 0;
   197   in
   153   in
   263     |> burrow_thms (canonical_tvars thy)
   219     |> burrow_thms (canonical_tvars thy)
   264     |> Drule.zero_var_indexes_list
   220     |> Drule.zero_var_indexes_list
   265   end;
   221   end;
   266 
   222 
   267 
   223 
       
   224 (* reading constants as terms *)
       
   225 
       
   226 fun check_bare_const thy t = case try dest_Const t
       
   227  of SOME c_ty => c_ty
       
   228   | NONE => error ("Not a constant: " ^ Syntax.string_of_term_global thy t);
       
   229 
       
   230 fun check_const thy = AxClass.unoverload_const thy o check_bare_const thy;
       
   231 
       
   232 fun read_bare_const thy = check_bare_const thy o Syntax.read_term_global thy;
       
   233 
       
   234 fun read_const thy = AxClass.unoverload_const thy o read_bare_const thy;
       
   235 
       
   236 
   268 (* const aliasses *)
   237 (* const aliasses *)
   269 
   238 
   270 structure ConstAlias = TheoryDataFun
   239 structure ConstAlias = TheoryDataFun
   271 (
   240 (
   272   type T = ((string * string) * thm) list * class list;
   241   type T = ((string * string) * thm) list * class list;
   278       Library.merge (op =) (classes1, classes2));
   247       Library.merge (op =) (classes1, classes2));
   279 );
   248 );
   280 
   249 
   281 fun add_const_alias thm thy =
   250 fun add_const_alias thm thy =
   282   let
   251   let
   283     val lhs_rhs = case try Logic.dest_equals (Thm.prop_of thm)
   252     val (ofclass, eqn) = case try Logic.dest_equals (Thm.prop_of thm)
       
   253      of SOME ofclass_eq => ofclass_eq
       
   254       | _ => error ("Bad certificate: " ^ Display.string_of_thm thm);
       
   255     val (T, class) = case try Logic.dest_of_class ofclass
       
   256      of SOME T_class => T_class
       
   257       | _ => error ("Bad certificate: " ^ Display.string_of_thm thm);
       
   258     val tvar = case try Term.dest_TVar T
       
   259      of SOME tvar => tvar
       
   260       | _ => error ("Bad type: " ^ Display.string_of_thm thm);
       
   261     val _ = if Term.add_tvars eqn [] = [tvar] then ()
       
   262       else error ("Inconsistent type: " ^ Display.string_of_thm thm);
       
   263     val lhs_rhs = case try Logic.dest_equals eqn
   284      of SOME lhs_rhs => lhs_rhs
   264      of SOME lhs_rhs => lhs_rhs
   285       | _ => error ("Not an equation: " ^ Display.string_of_thm thm);
   265       | _ => error ("Not an equation: " ^ Syntax.string_of_term_global thy eqn);
   286     val c_c' = case try (pairself (AxClass.unoverload_const thy o dest_Const)) lhs_rhs
   266     val c_c' = case try (pairself (check_const thy)) lhs_rhs
   287      of SOME c_c' => c_c'
   267      of SOME c_c' => c_c'
   288       | _ => error ("Not an equation with two constants: " ^ Display.string_of_thm thm);
   268       | _ => error ("Not an equation with two constants: "
   289     val some_class = the_list (AxClass.class_of_param thy (snd c_c'));
   269           ^ Syntax.string_of_term_global thy eqn);
       
   270     val _ = if the_list (AxClass.class_of_param thy (snd c_c')) = [class] then ()
       
   271       else error ("Inconsistent class: " ^ Display.string_of_thm thm);
   290   in thy |>
   272   in thy |>
   291     ConstAlias.map (fn (alias, classes) =>
   273     ConstAlias.map (fn (alias, classes) =>
   292       ((c_c', thm) :: alias, fold (insert (op =)) some_class classes))
   274       ((c_c', thm) :: alias, insert (op =) class classes))
   293   end;
   275   end;
   294 
   276 
   295 fun resubst_alias thy =
   277 fun resubst_alias thy =
   296   let
   278   let
   297     val alias = fst (ConstAlias.get thy);
   279     val alias = fst (ConstAlias.get thy);
   302     perhaps subst_inst_param
   284     perhaps subst_inst_param
   303     #> perhaps subst_alias
   285     #> perhaps subst_alias
   304   end;
   286   end;
   305 
   287 
   306 val triv_classes = snd o ConstAlias.get;
   288 val triv_classes = snd o ConstAlias.get;
   307 
       
   308 
       
   309 (* reading constants as terms *)
       
   310 
       
   311 fun check_bare_const thy t = case try dest_Const t
       
   312  of SOME c_ty => c_ty
       
   313   | NONE => error ("Not a constant: " ^ Syntax.string_of_term_global thy t);
       
   314 
       
   315 fun check_const thy = AxClass.unoverload_const thy o check_bare_const thy;
       
   316 
       
   317 fun read_bare_const thy = check_bare_const thy o Syntax.read_term_global thy;
       
   318 
       
   319 fun read_const thy = AxClass.unoverload_const thy o read_bare_const thy;
       
   320 
   289 
   321 
   290 
   322 (* constructor sets *)
   291 (* constructor sets *)
   323 
   292 
   324 fun constrset_of_consts thy cs =
   293 fun constrset_of_consts thy cs =
   438            ^ string_of_typ thy ty_decl)
   407            ^ string_of_typ thy ty_decl)
   439   in (thm, proper) end;
   408   in (thm, proper) end;
   440 
   409 
   441 fun assert_eqn thy is_constr = error_thm (gen_assert_eqn thy is_constr is_constr);
   410 fun assert_eqn thy is_constr = error_thm (gen_assert_eqn thy is_constr is_constr);
   442 
   411 
   443 val const_typ_eqn = dest_Const o fst o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
       
   444 
       
   445 
   412 
   446 (*those following are permissive wrt. to overloaded constants!*)
   413 (*those following are permissive wrt. to overloaded constants!*)
   447 
   414 
   448 fun mk_eqn thy is_constr_head = error_thm (gen_assert_eqn thy is_constr_head (K true)) o
   415 fun mk_eqn thy is_constr_head = error_thm (gen_assert_eqn thy is_constr_head (K true)) o
   449   apfst (LocalDefs.meta_rewrite_rule (ProofContext.init thy));
   416   apfst (LocalDefs.meta_rewrite_rule (ProofContext.init thy));
   454 
   421 
   455 fun mk_eqn_liberal thy is_constr_head = Option.map (fn (thm, _) => (thm, is_linear thm))
   422 fun mk_eqn_liberal thy is_constr_head = Option.map (fn (thm, _) => (thm, is_linear thm))
   456   o try_thm (gen_assert_eqn thy is_constr_head (K true))
   423   o try_thm (gen_assert_eqn thy is_constr_head (K true))
   457   o rpair false o LocalDefs.meta_rewrite_rule (ProofContext.init thy);
   424   o rpair false o LocalDefs.meta_rewrite_rule (ProofContext.init thy);
   458 
   425 
   459 fun const_typ_eqn_unoverload thy thm =
   426 fun const_typ_eqn thy thm =
   460   let
   427   let
   461     val (c, ty) = const_typ_eqn thm;
   428     val (c, ty) = (dest_Const o fst o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of) thm;
   462     val c' = AxClass.unoverload_const thy (c, ty);
   429     val c' = AxClass.unoverload_const thy (c, ty);
   463   in (c', ty) end;
   430   in (c', ty) end;
   464 
   431 
   465 fun typscheme_eqn thy = typscheme thy o const_typ_eqn_unoverload thy;
   432 fun typscheme_eqn thy = typscheme thy o const_typ_eqn thy;
   466 fun const_eqn thy = fst o const_typ_eqn_unoverload thy;
   433 fun const_eqn thy = fst o const_typ_eqn thy;
   467 
   434 
   468 
   435 
   469 (* case cerificates *)
   436 (* case cerificates *)
   470 
   437 
   471 fun case_certificate thm =
   438 fun case_certificate thm =
   785       |> (map o apsnd) (snd o fst)
   752       |> (map o apsnd) (snd o fst)
   786       |> sort (string_ord o pairself fst);
   753       |> sort (string_ord o pairself fst);
   787     val dtyps = the_dtyps exec
   754     val dtyps = the_dtyps exec
   788       |> Symtab.dest
   755       |> Symtab.dest
   789       |> map (fn (dtco, (_, (vs, cos)) :: _) =>
   756       |> map (fn (dtco, (_, (vs, cos)) :: _) =>
   790           (Syntax.string_of_typ_global thy (Type (dtco, map TFree vs)), cos))
   757           (string_of_typ thy (Type (dtco, map TFree vs)), cos))
   791       |> sort (string_ord o pairself fst)
   758       |> sort (string_ord o pairself fst)
   792   in
   759   in
   793     (Pretty.writeln o Pretty.chunks) [
   760     (Pretty.writeln o Pretty.chunks) [
   794       Pretty.block (
   761       Pretty.block (
   795         Pretty.str "code equations:"
   762         Pretty.str "code equations:"
   815           let
   782           let
   816             val thm' = incr_indexes max thm;
   783             val thm' = incr_indexes max thm;
   817             val max' = Thm.maxidx_of thm' + 1;
   784             val max' = Thm.maxidx_of thm' + 1;
   818           in (thm', max') end;
   785           in (thm', max') end;
   819         val (thms', maxidx) = fold_map incr_thm thms 0;
   786         val (thms', maxidx) = fold_map incr_thm thms 0;
   820         val ty1 :: tys = map (snd o const_typ_eqn) thms';
   787         val ty1 :: tys = map (snd o const_typ_eqn thy) thms';
   821         fun unify ty env = Sign.typ_unify thy (ty1, ty) env
   788         fun unify ty env = Sign.typ_unify thy (ty1, ty) env
   822           handle Type.TUNIFY =>
   789           handle Type.TUNIFY =>
   823             error ("Type unificaton failed, while unifying code equations\n"
   790             error ("Type unificaton failed, while unifying code equations\n"
   824             ^ (cat_lines o map Display.string_of_thm) thms
   791             ^ (cat_lines o map Display.string_of_thm) thms
   825             ^ "\nwith types\n"
   792             ^ "\nwith types\n"
   961 
   928 
   962 fun all_eqns thy =
   929 fun all_eqns thy =
   963   Symtab.dest ((the_eqns o the_exec) thy)
   930   Symtab.dest ((the_eqns o the_exec) thy)
   964   |> maps (Lazy.force o snd o snd o fst o snd);
   931   |> maps (Lazy.force o snd o snd o fst o snd);
   965 
   932 
   966 fun default_typscheme thy c =
       
   967   let
       
   968     fun the_const_typscheme c = (curry (typscheme thy) c o snd o dest_Const
       
   969       o TermSubst.zero_var_indexes o curry Const "" o Sign.the_const_type thy) c;
       
   970     fun strip_sorts (vs, ty) = (map (fn (v, _) => (v, [])) vs, ty);
       
   971   in case AxClass.class_of_param thy c
       
   972    of SOME class => ([(Name.aT, [class])], snd (the_const_typscheme c))
       
   973     | NONE => if is_constr thy c
       
   974         then strip_sorts (the_const_typscheme c)
       
   975         else case get_eqns thy c
       
   976          of (thm, _) :: _ => (typscheme_eqn thy o Drule.zero_var_indexes) thm
       
   977           | [] => strip_sorts (the_const_typscheme c) end;
       
   978 
       
   979 end; (*struct*)
   933 end; (*struct*)
   980 
   934 
   981 
   935 
   982 (** type-safe interfaces for data depedent on executable content **)
   936 (** type-safe interfaces for data depedent on executable content **)
   983 
   937