src/Pure/Isar/code.ML
changeset 28368 8437fb395294
parent 28359 bd4750bcb4e6
child 28403 da9ae7774513
equal deleted inserted replaced
28367:10ea34297962 28368:8437fb395294
     6 executable content.  Cache assumes non-concurrent processing of a single theory.
     6 executable content.  Cache assumes non-concurrent processing of a single theory.
     7 *)
     7 *)
     8 
     8 
     9 signature CODE =
     9 signature CODE =
    10 sig
    10 sig
    11   val add_func: thm -> theory -> theory
    11   val add_eqn: thm -> theory -> theory
    12   val add_nonlinear_func: thm -> theory -> theory
    12   val add_nonlinear_eqn: thm -> theory -> theory
    13   val add_liberal_func: thm -> theory -> theory
    13   val add_liberal_eqn: thm -> theory -> theory
    14   val add_default_func: thm -> theory -> theory
    14   val add_default_eqn: thm -> theory -> theory
    15   val add_default_func_attr: Attrib.src
    15   val add_default_eqn_attr: Attrib.src
    16   val del_func: thm -> theory -> theory
    16   val del_eqn: thm -> theory -> theory
    17   val del_funcs: string -> theory -> theory
    17   val del_eqns: string -> theory -> theory
    18   val add_funcl: string * (thm * bool) list Susp.T -> theory -> theory
    18   val add_eqnl: string * (thm * bool) list Susp.T -> theory -> theory
    19   val map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory
    19   val map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory
    20   val map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory
    20   val map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory
    21   val add_inline: thm -> theory -> theory
    21   val add_inline: thm -> theory -> theory
    22   val del_inline: thm -> theory -> theory
    22   val del_inline: thm -> theory -> theory
    23   val add_post: thm -> theory -> theory
    23   val add_post: thm -> theory -> theory
    33   val add_undefined: string -> theory -> theory
    33   val add_undefined: string -> theory -> theory
    34   val purge_data: theory -> theory
    34   val purge_data: theory -> theory
    35 
    35 
    36   val coregular_algebra: theory -> Sorts.algebra
    36   val coregular_algebra: theory -> Sorts.algebra
    37   val operational_algebra: theory -> (sort -> sort) * Sorts.algebra
    37   val operational_algebra: theory -> (sort -> sort) * Sorts.algebra
    38   val these_funcs: theory -> string -> (thm * bool) list
    38   val these_eqns: theory -> string -> (thm * bool) list
    39   val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list)
    39   val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list)
    40   val get_datatype_of_constr: theory -> string -> string option
    40   val get_datatype_of_constr: theory -> string -> string option
    41   val get_case_data: theory -> string -> (int * string list) option
    41   val get_case_data: theory -> string -> (int * string list) option
    42   val is_undefined: theory -> string -> bool
    42   val is_undefined: theory -> string -> bool
    43   val default_typ: theory -> string -> (string * sort) list * typ
    43   val default_typ: theory -> string -> (string * sort) list * typ
   170 
   170 
   171 
   171 
   172 (* specification data *)
   172 (* specification data *)
   173 
   173 
   174 datatype spec = Spec of {
   174 datatype spec = Spec of {
   175   funcs: (bool * (thm * bool) list Susp.T) Symtab.table,
   175   eqns: (bool * (thm * bool) list Susp.T) Symtab.table,
   176   dtyps: ((string * sort) list * (string * typ list) list) Symtab.table,
   176   dtyps: ((string * sort) list * (string * typ list) list) Symtab.table,
   177   cases: (int * string list) Symtab.table * unit Symtab.table
   177   cases: (int * string list) Symtab.table * unit Symtab.table
   178 };
   178 };
   179 
   179 
   180 fun mk_spec (funcs, (dtyps, cases)) =
   180 fun mk_spec (eqns, (dtyps, cases)) =
   181   Spec { funcs = funcs, dtyps = dtyps, cases = cases };
   181   Spec { eqns = eqns, dtyps = dtyps, cases = cases };
   182 fun map_spec f (Spec { funcs = funcs, dtyps = dtyps, cases = cases }) =
   182 fun map_spec f (Spec { eqns = eqns, dtyps = dtyps, cases = cases }) =
   183   mk_spec (f (funcs, (dtyps, cases)));
   183   mk_spec (f (eqns, (dtyps, cases)));
   184 fun merge_spec (Spec { funcs = funcs1, dtyps = dtyps1, cases = (cases1, undefs1) },
   184 fun merge_spec (Spec { eqns = eqns1, dtyps = dtyps1, cases = (cases1, undefs1) },
   185   Spec { funcs = funcs2, dtyps = dtyps2, cases = (cases2, undefs2) }) =
   185   Spec { eqns = eqns2, dtyps = dtyps2, cases = (cases2, undefs2) }) =
   186   let
   186   let
   187     val funcs = Symtab.join (K merge_defthms) (funcs1, funcs2);
   187     val eqns = Symtab.join (K merge_defthms) (eqns1, eqns2);
   188     val dtyps = merge_dtyps (dtyps1, dtyps2);
   188     val dtyps = merge_dtyps (dtyps1, dtyps2);
   189     val cases = (Symtab.merge (K true) (cases1, cases2),
   189     val cases = (Symtab.merge (K true) (cases1, cases2),
   190       Symtab.merge (K true) (undefs1, undefs2));
   190       Symtab.merge (K true) (undefs1, undefs2));
   191   in mk_spec (funcs, (dtyps, cases)) end;
   191   in mk_spec (eqns, (dtyps, cases)) end;
   192 
   192 
   193 
   193 
   194 (* pre- and postprocessor *)
   194 (* pre- and postprocessor *)
   195 
   195 
   196 datatype thmproc = Thmproc of {
   196 datatype thmproc = Thmproc of {
   232 val empty_exec = mk_exec (mk_thmproc ((MetaSimplifier.empty_ss, MetaSimplifier.empty_ss), []),
   232 val empty_exec = mk_exec (mk_thmproc ((MetaSimplifier.empty_ss, MetaSimplifier.empty_ss), []),
   233   mk_spec (Symtab.empty, (Symtab.empty, (Symtab.empty, Symtab.empty))));
   233   mk_spec (Symtab.empty, (Symtab.empty, (Symtab.empty, Symtab.empty))));
   234 
   234 
   235 fun the_thmproc (Exec { thmproc = Thmproc x, ...}) = x;
   235 fun the_thmproc (Exec { thmproc = Thmproc x, ...}) = x;
   236 fun the_spec (Exec { spec = Spec x, ...}) = x;
   236 fun the_spec (Exec { spec = Spec x, ...}) = x;
   237 val the_funcs = #funcs o the_spec;
   237 val the_eqns = #eqns o the_spec;
   238 val the_dtyps = #dtyps o the_spec;
   238 val the_dtyps = #dtyps o the_spec;
   239 val the_cases = #cases o the_spec;
   239 val the_cases = #cases o the_spec;
   240 val map_thmproc = map_exec o apfst o map_thmproc;
   240 val map_thmproc = map_exec o apfst o map_thmproc;
   241 val map_funcs = map_exec o apsnd o map_spec o apfst;
   241 val map_eqns = map_exec o apsnd o map_spec o apfst;
   242 val map_dtyps = map_exec o apsnd o map_spec o apsnd o apfst;
   242 val map_dtyps = map_exec o apsnd o map_spec o apsnd o apfst;
   243 val map_cases = map_exec o apsnd o map_spec o apsnd o apsnd;
   243 val map_cases = map_exec o apsnd o map_spec o apsnd o apsnd;
   244 
   244 
   245 
   245 
   246 (* data slots dependent on executable content *)
   246 (* data slots dependent on executable content *)
   356 
   356 
   357 fun print_codesetup thy =
   357 fun print_codesetup thy =
   358   let
   358   let
   359     val ctxt = ProofContext.init thy;
   359     val ctxt = ProofContext.init thy;
   360     val exec = the_exec thy;
   360     val exec = the_exec thy;
   361     fun pretty_func (s, (_, lthms)) =
   361     fun pretty_eqn (s, (_, lthms)) =
   362       (Pretty.block o Pretty.fbreaks) (
   362       (Pretty.block o Pretty.fbreaks) (
   363         Pretty.str s :: pretty_lthms ctxt lthms
   363         Pretty.str s :: pretty_lthms ctxt lthms
   364       );
   364       );
   365     fun pretty_dtyp (s, []) =
   365     fun pretty_dtyp (s, []) =
   366           Pretty.str s
   366           Pretty.str s
   376                           :: map (Pretty.quote o Syntax.pretty_typ_global thy) tys)) cos)
   376                           :: map (Pretty.quote o Syntax.pretty_typ_global thy) tys)) cos)
   377           );
   377           );
   378     val pre = (#pre o the_thmproc) exec;
   378     val pre = (#pre o the_thmproc) exec;
   379     val post = (#post o the_thmproc) exec;
   379     val post = (#post o the_thmproc) exec;
   380     val functrans = (map fst o #functrans o the_thmproc) exec;
   380     val functrans = (map fst o #functrans o the_thmproc) exec;
   381     val funcs = the_funcs exec
   381     val eqns = the_eqns exec
   382       |> Symtab.dest
   382       |> Symtab.dest
   383       |> (map o apfst) (Code_Unit.string_of_const thy)
   383       |> (map o apfst) (Code_Unit.string_of_const thy)
   384       |> sort (string_ord o pairself fst);
   384       |> sort (string_ord o pairself fst);
   385     val dtyps = the_dtyps exec
   385     val dtyps = the_dtyps exec
   386       |> Symtab.dest
   386       |> Symtab.dest
   390   in
   390   in
   391     (Pretty.writeln o Pretty.chunks) [
   391     (Pretty.writeln o Pretty.chunks) [
   392       Pretty.block (
   392       Pretty.block (
   393         Pretty.str "defining equations:"
   393         Pretty.str "defining equations:"
   394         :: Pretty.fbrk
   394         :: Pretty.fbrk
   395         :: (Pretty.fbreaks o map pretty_func) funcs
   395         :: (Pretty.fbreaks o map pretty_eqn) eqns
   396       ),
   396       ),
   397       Pretty.block [
   397       Pretty.block [
   398         Pretty.str "preprocessing simpset:",
   398         Pretty.str "preprocessing simpset:",
   399         Pretty.fbrk,
   399         Pretty.fbrk,
   400         MetaSimplifier.pretty_ss pre
   400         MetaSimplifier.pretty_ss pre
   419 
   419 
   420 
   420 
   421 
   421 
   422 (** theorem transformation and certification **)
   422 (** theorem transformation and certification **)
   423 
   423 
   424 fun const_of thy = dest_Const o fst o strip_comb o fst o Logic.dest_equals
   424 fun const_of thy = dest_Const o fst o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
   425   o ObjectLogic.drop_judgment thy o Thm.plain_prop_of;
   425 
   426 
   426 fun const_of_eqn thy = AxClass.unoverload_const thy o const_of thy;
   427 fun const_of_func thy = AxClass.unoverload_const thy o const_of thy;
   427 
   428 
   428 fun common_typ_eqns [] = []
   429 fun common_typ_funcs [] = []
   429   | common_typ_eqns [thm] = [thm]
   430   | common_typ_funcs [thm] = [thm]
   430   | common_typ_eqns (thms as thm :: _) = (*FIXME is too general*)
   431   | common_typ_funcs (thms as thm :: _) = (*FIXME is too general*)
       
   432       let
   431       let
   433         val thy = Thm.theory_of_thm thm;
   432         val thy = Thm.theory_of_thm thm;
   434         fun incr_thm thm max =
   433         fun incr_thm thm max =
   435           let
   434           let
   436             val thm' = incr_indexes max thm;
   435             val thm' = incr_indexes max thm;
   449           cons (Thm.ctyp_of thy (TVar (x_i, sort)), Thm.ctyp_of thy ty)) env [];
   448           cons (Thm.ctyp_of thy (TVar (x_i, sort)), Thm.ctyp_of thy ty)) env [];
   450       in map (Thm.instantiate (instT, [])) thms' end;
   449       in map (Thm.instantiate (instT, [])) thms' end;
   451 
   450 
   452 fun certify_const thy const thms =
   451 fun certify_const thy const thms =
   453   let
   452   let
   454     fun cert thm = if const = const_of_func thy thm
   453     fun cert thm = if const = const_of_eqn thy thm
   455       then thm else error ("Wrong head of defining equation,\nexpected constant "
   454       then thm else error ("Wrong head of defining equation,\nexpected constant "
   456         ^ Code_Unit.string_of_const thy const ^ "\n" ^ Display.string_of_thm thm)
   455         ^ Code_Unit.string_of_const thy const ^ "\n" ^ Display.string_of_thm thm)
   457   in map cert thms end;
   456   in map cert thms end;
   458 
   457 
   459 
   458 
   473 
   472 
   474 fun specific_constraints thy (class, tyco) =
   473 fun specific_constraints thy (class, tyco) =
   475   let
   474   let
   476     val vs = Name.invents Name.context "" (Sign.arity_number thy tyco);
   475     val vs = Name.invents Name.context "" (Sign.arity_number thy tyco);
   477     val classparams = (map fst o these o try (#params o AxClass.get_info thy)) class;
   476     val classparams = (map fst o these o try (#params o AxClass.get_info thy)) class;
   478     val funcs = classparams
   477     val eqns = classparams
   479       |> map_filter (fn c => try (AxClass.param_of_inst thy) (c, tyco))
   478       |> map_filter (fn c => try (AxClass.param_of_inst thy) (c, tyco))
   480       |> map (Symtab.lookup ((the_funcs o the_exec) thy))
   479       |> map (Symtab.lookup ((the_eqns o the_exec) thy))
   481       |> (map o Option.map) (map fst o Susp.force o snd)
   480       |> (map o Option.map) (map fst o Susp.force o snd)
   482       |> maps these
   481       |> maps these
   483       |> map (Thm.transfer thy);
   482       |> map (Thm.transfer thy);
   484     fun sorts_of [Type (_, tys)] = map (snd o dest_TVar) tys
   483     fun sorts_of [Type (_, tys)] = map (snd o dest_TVar) tys
   485       | sorts_of tys = map (snd o dest_TVar) tys;
   484       | sorts_of tys = map (snd o dest_TVar) tys;
   486     val sorts = map (sorts_of o Sign.const_typargs thy o const_of thy) funcs;
   485     val sorts = map (sorts_of o Sign.const_typargs thy o const_of thy) eqns;
   487   in sorts end;
   486   in sorts end;
   488 
   487 
   489 fun weakest_constraints thy algebra (class, tyco) =
   488 fun weakest_constraints thy algebra (class, tyco) =
   490   let
   489   let
   491     val all_superclasses = Sorts.complete_sort algebra [class];
   490     val all_superclasses = Sorts.complete_sort algebra [class];
   546   in retrieve_algebra thy (member (op =) operational_classes) end;
   545   in retrieve_algebra thy (member (op =) operational_classes) end;
   547 
   546 
   548 val classparam_weakest_typ = gen_classparam_typ weakest_constraints;
   547 val classparam_weakest_typ = gen_classparam_typ weakest_constraints;
   549 val classparam_strongest_typ = gen_classparam_typ strongest_constraints;
   548 val classparam_strongest_typ = gen_classparam_typ strongest_constraints;
   550 
   549 
   551 fun assert_func_typ thm =
   550 fun assert_eqn_linear (eqn as (thm, linear)) =
       
   551   if linear then eqn else Code_Unit.bad_thm
       
   552     ("Duplicate variables on left hand side of defining equation:\n"
       
   553       ^ Display.string_of_thm thm);
       
   554 
       
   555 fun assert_eqn_typ (thm, linear) =
   552   let
   556   let
   553     val thy = Thm.theory_of_thm thm;
   557     val thy = Thm.theory_of_thm thm;
   554     fun check_typ_classparam tyco (c, thm) =
   558     fun check_typ_classparam tyco (c, thm) =
   555           let
   559           let
   556             val SOME class = AxClass.class_of_param thy c;
   560             val SOME class = AxClass.class_of_param thy c;
   595       end;
   599       end;
   596     fun check_typ (c, thm) =
   600     fun check_typ (c, thm) =
   597       case AxClass.inst_of_param thy c
   601       case AxClass.inst_of_param thy c
   598        of SOME (c, tyco) => check_typ_classparam tyco (c, thm)
   602        of SOME (c, tyco) => check_typ_classparam tyco (c, thm)
   599         | NONE => check_typ_fun (c, thm);
   603         | NONE => check_typ_fun (c, thm);
   600   in check_typ (const_of_func thy thm, thm) end;
   604     val c = const_of_eqn thy thm;
   601 
   605     val thm' = check_typ (c, thm);
   602 fun mk_func linear = Code_Unit.error_thm (assert_func_typ o Code_Unit.mk_func linear);
   606   in (thm', linear) end;
   603 val mk_liberal_func = Code_Unit.warning_thm (assert_func_typ o Code_Unit.mk_func true);
   607 
   604 val mk_syntactic_func = Code_Unit.warning_thm (assert_func_typ o Code_Unit.mk_func false);
   608 fun mk_eqn linear = Code_Unit.error_thm
   605 val mk_default_func = Code_Unit.try_thm (assert_func_typ o Code_Unit.mk_func true);
   609   (assert_eqn_typ o (if linear then assert_eqn_linear else I) o Code_Unit.mk_eqn);
       
   610 val mk_liberal_eqn = Code_Unit.warning_thm
       
   611   (assert_eqn_typ o assert_eqn_linear o Code_Unit.mk_eqn);
       
   612 val mk_syntactic_eqn = Code_Unit.warning_thm
       
   613   (assert_eqn_typ o Code_Unit.mk_eqn);
       
   614 val mk_default_eqn = Code_Unit.try_thm
       
   615   (assert_eqn_typ o assert_eqn_linear o Code_Unit.mk_eqn);
   606 
   616 
   607 end; (*local*)
   617 end; (*local*)
   608 
   618 
   609 
   619 
   610 (** interfaces and attributes **)
   620 (** interfaces and attributes **)
   639 
   649 
   640 val get_case_data = Symtab.lookup o fst o the_cases o the_exec;
   650 val get_case_data = Symtab.lookup o fst o the_cases o the_exec;
   641 
   651 
   642 val is_undefined = Symtab.defined o snd o the_cases o the_exec;
   652 val is_undefined = Symtab.defined o snd o the_cases o the_exec;
   643 
   653 
   644 fun gen_add_func linear strict default thm thy =
   654 fun gen_add_eqn linear strict default thm thy =
   645   case (if strict then SOME o mk_func linear else mk_liberal_func) thm
   655   case (if strict then SOME o mk_eqn linear else mk_liberal_eqn) thm
   646    of SOME func =>
   656    of SOME (thm, _) =>
   647         let
   657         let
   648           val c = const_of_func thy func;
   658           val c = const_of_eqn thy thm;
   649           val _ = if strict andalso (is_some o AxClass.class_of_param thy) c
   659           val _ = if strict andalso (is_some o AxClass.class_of_param thy) c
   650             then error ("Rejected polymorphic equation for overloaded constant:\n"
   660             then error ("Rejected polymorphic equation for overloaded constant:\n"
   651               ^ Display.string_of_thm thm)
   661               ^ Display.string_of_thm thm)
   652             else ();
   662             else ();
   653           val _ = if strict andalso (is_some o get_datatype_of_constr thy) c
   663           val _ = if strict andalso (is_some o get_datatype_of_constr thy) c
   654             then error ("Rejected equation for datatype constructor:\n"
   664             then error ("Rejected equation for datatype constructor:\n"
   655               ^ Display.string_of_thm func)
   665               ^ Display.string_of_thm thm)
   656             else ();
   666             else ();
   657         in
   667         in
   658           (map_exec_purge (SOME [c]) o map_funcs) (Symtab.map_default
   668           (map_exec_purge (SOME [c]) o map_eqns) (Symtab.map_default
   659             (c, (true, Susp.value [])) (add_thm default (func, linear))) thy
   669             (c, (true, Susp.value [])) (add_thm default (thm, linear))) thy
   660         end
   670         end
   661     | NONE => thy;
   671     | NONE => thy;
   662 
   672 
   663 val add_func = gen_add_func true true false;
   673 val add_eqn = gen_add_eqn true true false;
   664 val add_liberal_func = gen_add_func true false false;
   674 val add_liberal_eqn = gen_add_eqn true false false;
   665 val add_default_func = gen_add_func true false true;
   675 val add_default_eqn = gen_add_eqn true false true;
   666 val add_nonlinear_func = gen_add_func false true false;
   676 val add_nonlinear_eqn = gen_add_eqn false true false;
   667 
   677 
   668 fun del_func thm thy = case mk_syntactic_func thm
   678 fun del_eqn thm thy = case mk_syntactic_eqn thm
   669  of SOME func => let
   679  of SOME (thm, _) => let
   670         val c = const_of_func thy func;
   680         val c = const_of_eqn thy thm;
   671       in map_exec_purge (SOME [c]) (map_funcs
   681       in map_exec_purge (SOME [c]) (map_eqns
   672         (Symtab.map_entry c (del_thm func))) thy
   682         (Symtab.map_entry c (del_thm thm))) thy
   673       end
   683       end
   674   | NONE => thy;
   684   | NONE => thy;
   675 
   685 
   676 fun del_funcs c = map_exec_purge (SOME [c])
   686 fun del_eqns c = map_exec_purge (SOME [c])
   677   (map_funcs (Symtab.map_entry c (K (false, Susp.value []))));
   687   (map_eqns (Symtab.map_entry c (K (false, Susp.value []))));
   678 
   688 
   679 fun add_funcl (c, lthms) thy =
   689 fun add_eqnl (c, lthms) thy =
   680   let
   690   let
   681     val lthms' = certificate thy (fn thy => certify_const thy c) lthms;
   691     val lthms' = certificate thy (fn thy => certify_const thy c) lthms;
   682       (*FIXME must check compatibility with sort algebra;
   692       (*FIXME must check compatibility with sort algebra;
   683         alas, naive checking results in non-termination!*)
   693         alas, naive checking results in non-termination!*)
   684   in
   694   in
   685     map_exec_purge (SOME [c])
   695     map_exec_purge (SOME [c])
   686       (map_funcs (Symtab.map_default (c, (true, Susp.value []))
   696       (map_eqns (Symtab.map_default (c, (true, Susp.value []))
   687         (add_lthms lthms'))) thy
   697         (add_lthms lthms'))) thy
   688   end;
   698   end;
   689 
   699 
   690 val add_default_func_attr = Attrib.internal (fn _ => Thm.declaration_attribute
   700 val add_default_eqn_attr = Attrib.internal (fn _ => Thm.declaration_attribute
   691   (fn thm => Context.mapping (add_default_func thm) I));
   701   (fn thm => Context.mapping (add_default_eqn thm) I));
   692 
   702 
   693 structure TypeInterpretation = InterpretationFun(type T = string * serial val eq = eq_snd (op =) : T * T -> bool);
   703 structure TypeInterpretation = InterpretationFun(type T = string * serial val eq = eq_snd (op =) : T * T -> bool);
   694 
   704 
   695 fun add_datatype raw_cs thy =
   705 fun add_datatype raw_cs thy =
   696   let
   706   let
   701      of SOME (vs, cos) => if null cos then NONE else SOME (cs' @ map fst cos)
   711      of SOME (vs, cos) => if null cos then NONE else SOME (cs' @ map fst cos)
   702       | NONE => NONE;
   712       | NONE => NONE;
   703   in
   713   in
   704     thy
   714     thy
   705     |> map_exec_purge purge_cs (map_dtyps (Symtab.update (tyco, vs_cos))
   715     |> map_exec_purge purge_cs (map_dtyps (Symtab.update (tyco, vs_cos))
   706         #> map_funcs (fold (Symtab.delete_safe o fst) cs))
   716         #> map_eqns (fold (Symtab.delete_safe o fst) cs))
   707     |> TypeInterpretation.data (tyco, serial ())
   717     |> TypeInterpretation.data (tyco, serial ())
   708   end;
   718   end;
   709 
   719 
   710 fun type_interpretation f =  TypeInterpretation.interpretation
   720 fun type_interpretation f =  TypeInterpretation.interpretation
   711   (fn (tyco, _) => fn thy => f (tyco, get_datatype thy tyco) thy);
   721   (fn (tyco, _) => fn thy => f (tyco, get_datatype thy tyco) thy);
   760     fun add_del_attribute (name, (add, del)) =
   770     fun add_del_attribute (name, (add, del)) =
   761       add_attribute (name, Args.del |-- Scan.succeed (mk_attribute del)
   771       add_attribute (name, Args.del |-- Scan.succeed (mk_attribute del)
   762         || Scan.succeed (mk_attribute add))
   772         || Scan.succeed (mk_attribute add))
   763   in
   773   in
   764     TypeInterpretation.init
   774     TypeInterpretation.init
   765     #> add_del_attribute ("func", (add_func, del_func))
   775     #> add_del_attribute ("func", (add_eqn, del_eqn))
   766     #> add_simple_attribute ("nbe", add_nonlinear_func)
   776     #> add_simple_attribute ("nbe", add_nonlinear_eqn)
   767     #> add_del_attribute ("inline", (add_inline, del_inline))
   777     #> add_del_attribute ("inline", (add_inline, del_inline))
   768     #> add_del_attribute ("post", (add_post, del_post))
   778     #> add_del_attribute ("post", (add_post, del_post))
   769   end));
   779   end));
   770 
   780 
   771 
   781 
   774 local
   784 local
   775 
   785 
   776 fun apply_functrans thy [] = []
   786 fun apply_functrans thy [] = []
   777   | apply_functrans thy (thms as (thm, _) :: _) =
   787   | apply_functrans thy (thms as (thm, _) :: _) =
   778       let
   788       let
   779         val const = const_of_func thy thm;
   789         val const = const_of_eqn thy thm;
   780         val functrans = (map (fn (_, (_, f)) => f thy) o #functrans
   790         val functrans = (map (fn (_, (_, f)) => f thy) o #functrans
   781           o the_thmproc o the_exec) thy;
   791           o the_thmproc o the_exec) thy;
   782         val thms' = perhaps (perhaps_loop (perhaps_apply functrans)) (map fst thms);
   792         val thms' = perhaps (perhaps_loop (perhaps_apply functrans)) (map fst thms);
   783         val thms'' = certify_const thy const thms';
   793         val thms'' = certify_const thy const thms';
   784         val linears = map snd thms;
   794       in map Code_Unit.add_linear thms'' end;
   785       in (*FIXME temporary workaround*) if length thms'' = length linears
       
   786         then thms'' ~~ linears
       
   787         else map (rpair true) thms''
       
   788       end;
       
   789 
   795 
   790 fun rhs_conv conv thm =
   796 fun rhs_conv conv thm =
   791   let
   797   let
   792     val thm' = (conv o Thm.rhs_of) thm;
   798     val thm' = (conv o Thm.rhs_of) thm;
   793   in Thm.transitive thm thm' end
   799   in Thm.transitive thm thm' end
   805   let
   811   let
   806     val pre = (Simplifier.theory_context thy o #pre o the_thmproc o the_exec) thy;
   812     val pre = (Simplifier.theory_context thy o #pre o the_thmproc o the_exec) thy;
   807   in
   813   in
   808     thms
   814     thms
   809     |> apply_functrans thy
   815     |> apply_functrans thy
   810     |> (map o apfst) (Code_Unit.rewrite_func pre)
   816     |> (map o apfst) (Code_Unit.rewrite_eqn pre)
   811     (*FIXME - must check here: rewrite rule, defining equation, proper constant *)
   817     (*FIXME - must check here: rewrite rule, defining equation, proper constant *)
   812     |> (map o apfst) (AxClass.unoverload thy)
   818     |> (map o apfst) (AxClass.unoverload thy)
   813     |> burrow_fst common_typ_funcs
   819     |> burrow_fst common_typ_eqns
   814   end;
   820   end;
   815 
   821 
   816 
   822 
   817 fun preprocess_conv ct =
   823 fun preprocess_conv ct =
   818   let
   824   let
   848           (K (TVar ((Name.aT, 0), [class]))) (Sign.the_const_type thy c))
   854           (K (TVar ((Name.aT, 0), [class]))) (Sign.the_const_type thy c))
   849       | NONE => get_constr_typ thy c);
   855       | NONE => get_constr_typ thy c);
   850 
   856 
   851 local
   857 local
   852 
   858 
   853 fun get_funcs thy const =
   859 fun get_eqns thy const =
   854   Symtab.lookup ((the_funcs o the_exec) thy) const
   860   Symtab.lookup ((the_eqns o the_exec) thy) const
   855   |> Option.map (Susp.force o snd)
   861   |> Option.map (Susp.force o snd)
   856   |> these
   862   |> these
   857   |> (map o apfst) (Thm.transfer thy);
   863   |> (map o apfst) (Thm.transfer thy);
   858 
   864 
   859 in
   865 in
   860 
   866 
   861 fun these_funcs thy const =
   867 fun these_eqns thy const =
   862   let
   868   let
   863     fun drop_refl thy = filter_out (is_equal o Term.fast_term_ord o Logic.dest_equals
   869     val drop_refl = filter_out
   864       o ObjectLogic.drop_judgment thy o Thm.plain_prop_of o fst);
   870       (is_equal o Term.fast_term_ord o Logic.dest_equals o Thm.plain_prop_of o fst);
   865   in
   871   in
   866     get_funcs thy const
   872     get_eqns thy const
   867     |> preprocess thy
   873     |> preprocess thy
   868     |> drop_refl thy
   874     |> drop_refl
   869   end;
   875   end;
   870 
   876 
   871 fun default_typ thy c = case default_typ_proto thy c
   877 fun default_typ thy c = case default_typ_proto thy c
   872  of SOME ty => Code_Unit.typscheme thy (c, ty)
   878  of SOME ty => Code_Unit.typscheme thy (c, ty)
   873   | NONE => (case get_funcs thy c
   879   | NONE => (case get_eqns thy c
   874      of (thm, _) :: _ => snd (Code_Unit.head_func (AxClass.unoverload thy thm))
   880      of (thm, _) :: _ => snd (Code_Unit.head_eqn (AxClass.unoverload thy thm))
   875       | [] => Code_Unit.typscheme thy (c, Sign.the_const_type thy c));
   881       | [] => Code_Unit.typscheme thy (c, Sign.the_const_type thy c));
   876 
   882 
   877 end; (*local*)
   883 end; (*local*)
   878 
   884 
   879 end; (*struct*)
   885 end; (*struct*)