clarified class interfaces and internals
authorhaftmann
Sat, 15 Sep 2007 19:27:44 +0200
changeset 24589 d3fca349736c
parent 24588 ed9a1254d674
child 24590 733120d04233
clarified class interfaces and internals
src/HOL/Tools/datatype_abs_proofs.ML
src/HOL/Tools/datatype_codegen.ML
src/HOL/Tools/datatype_package.ML
src/Pure/Isar/class.ML
src/Pure/Isar/isar_syn.ML
src/Pure/axclass.ML
--- a/src/HOL/Tools/datatype_abs_proofs.ML	Sat Sep 15 19:27:43 2007 +0200
+++ b/src/HOL/Tools/datatype_abs_proofs.ML	Sat Sep 15 19:27:44 2007 +0200
@@ -427,7 +427,7 @@
         val n = Sign.arity_number thy tyco;
       in
         thy
-        |> Class.prove_instance_arity (Class.intro_classes_tac [])
+        |> Class.prove_instance (Class.intro_classes_tac [])
             [(tyco, replicate n HOLogic.typeS, [HOLogic.class_size])] []
         |> snd
       end
--- a/src/HOL/Tools/datatype_codegen.ML	Sat Sep 15 19:27:43 2007 +0200
+++ b/src/HOL/Tools/datatype_codegen.ML	Sat Sep 15 19:27:44 2007 +0200
@@ -1,4 +1,4 @@
-(*  Title:      HOL/datatype_codegen.ML
+(*  Title:      HOL/Tools/datatype_codegen.ML
     ID:         $Id$
     Author:     Stefan Berghofer & Florian Haftmann, TU Muenchen
 
@@ -590,7 +590,7 @@
         |> not (null arities) ? (
             f arities css
             #-> (fn defs =>
-              Class.prove_instance_arity tac arities defs
+              Class.prove_instance tac arities defs
             #-> (fn defs =>
               after_qed arities css defs)))
       end;
--- a/src/HOL/Tools/datatype_package.ML	Sat Sep 15 19:27:43 2007 +0200
+++ b/src/HOL/Tools/datatype_package.ML	Sat Sep 15 19:27:44 2007 +0200
@@ -565,7 +565,7 @@
         val n = Sign.arity_number thy tyco;
       in
         thy
-        |> Class.prove_instance_arity (Class.intro_classes_tac [])
+        |> Class.prove_instance (Class.intro_classes_tac [])
             [(tyco, replicate n HOLogic.typeS, [HOLogic.class_size])] []
         |> snd
       end
--- a/src/Pure/Isar/class.ML	Sat Sep 15 19:27:43 2007 +0200
+++ b/src/Pure/Isar/class.ML	Sat Sep 15 19:27:44 2007 +0200
@@ -10,23 +10,32 @@
   val fork_mixfix: bool -> string option -> mixfix -> mixfix * mixfix
 
   val axclass_cmd: bstring * xstring list
-    -> ((bstring * Attrib.src list) * string list) list -> theory -> class * theory
+    -> ((bstring * Attrib.src list) * string list) list
+    -> theory -> class * theory
+  val classrel_cmd: xstring * xstring -> theory -> Proof.state
   val class: bstring -> class list -> Element.context_i Locale.element list
     -> string list -> theory -> string * Proof.context
-  val class_cmd: bstring -> string list -> Element.context Locale.element list
-    -> string list -> theory -> string * Proof.context
-  val class_of_locale: theory -> string -> class option
+  val class_cmd: bstring -> xstring list -> Element.context Locale.element list
+    -> xstring list -> theory -> string * Proof.context
   val add_const_in_class: string -> (string * term) * Syntax.mixfix
     -> theory -> theory
+  val interpretation_in_class: class * class -> theory -> Proof.state
+  val interpretation_in_class_cmd: xstring * xstring -> theory -> Proof.state
+  val prove_interpretation_in_class: tactic -> class * class -> theory -> theory
+  val intro_classes_tac: thm list -> tactic
+  val default_intro_classes_tac: thm list -> tactic
+  val class_of_locale: theory -> string -> class option
+  val print_classes: theory -> unit
 
-  val instance_arity: arity list -> ((bstring * Attrib.src list) * term) list
+  val instance_arity: (theory -> theory) -> arity list -> theory -> Proof.state
+  val instance: arity list -> ((bstring * Attrib.src list) * term) list
     -> (thm list -> theory -> theory)
     -> theory -> Proof.state
-  val instance_arity_cmd: (bstring * string list * string) list
-    -> ((bstring * Attrib.src list) * string) list
+  val instance_cmd: (bstring * xstring list * xstring) list
+    -> ((bstring * Attrib.src list) * xstring) list
     -> (thm list -> theory -> theory)
     -> theory -> Proof.state
-  val prove_instance_arity: tactic -> arity list
+  val prove_instance: tactic -> arity list
     -> ((bstring * Attrib.src list) * term) list
     -> theory -> thm list * theory
   val unoverload: theory -> conv
@@ -35,16 +44,6 @@
   val inst_const: theory -> string * string -> string
   val param_const: theory -> string -> (string * string) option
   val params_of_sort: theory -> sort -> (string * (string * typ)) list
-  val intro_classes_tac: thm list -> tactic
-  val default_intro_classes_tac: thm list -> tactic
-
-  val instance_class: class * class -> theory -> Proof.state
-  val instance_class_cmd: string * string -> theory -> Proof.state
-  val instance_sort: class * sort -> theory -> Proof.state
-  val instance_sort_cmd: string * string -> theory -> Proof.state
-  val prove_instance_sort: tactic -> class * sort -> theory -> theory
-
-  val print_classes: theory -> unit
 end;
 
 structure Class : CLASS =
@@ -60,20 +59,55 @@
     val mx_local = if is_loc then mx else NoSyn;
   in (mx_global, mx_local) end;
 
+fun prove_interpretation tac prfx_atts expr insts =
+  Locale.interpretation_i I prfx_atts expr insts
+  #> Proof.global_terminal_proof
+      (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
+  #> ProofContext.theory_of;
+
+fun prove_interpretation_in tac after_qed (name, expr) =
+  Locale.interpretation_in_locale
+      (ProofContext.theory after_qed) (name, expr)
+  #> Proof.global_terminal_proof
+      (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
+  #> ProofContext.theory_of;
+
+fun OF_LAST thm1 thm2 =
+  let
+    val n = (length o Logic.strip_imp_prems o prop_of) thm2;
+  in (thm1 RSN (n, thm2)) end;
+
+fun strip_all_ofclass thy sort =
+  let
+    val typ = TVar ((AxClass.param_tyvarname, 0), sort);
+    fun prem_inclass t =
+      case Logic.strip_imp_prems t
+       of ofcls :: _ => try Logic.dest_inclass ofcls
+        | [] => NONE;
+    fun strip_ofclass class thm =
+      thm OF (fst o AxClass.of_sort thy (typ, [class])) AxClass.cache;
+    fun strip thm = case (prem_inclass o Thm.prop_of) thm
+     of SOME (_, class) => thm |> strip_ofclass class |> strip
+      | NONE => thm;
+  in strip end;
+
+
+(** axclass command **)
+
 fun axclass_cmd (class, raw_superclasses) raw_specs thy =
   let
     val ctxt = ProofContext.init thy;
     val superclasses = map (Sign.read_class thy) raw_superclasses;
-    val name_atts = map ((apsnd o map) (Attrib.attribute thy) o fst) raw_specs;
-    val axiomss = ProofContext.read_propp (ctxt, map (map (rpair []) o snd) raw_specs)
+    val name_atts = map ((apsnd o map) (Attrib.attribute thy) o fst)
+      raw_specs;
+    val axiomss = ProofContext.read_propp (ctxt, map (map (rpair []) o snd)
+          raw_specs)
       |> snd
       |> (map o map) fst;
-  in AxClass.define_class (class, superclasses) [] (name_atts ~~ axiomss) thy end;
-
-
-(** axclasses with implicit parameter handling **)
-
-(* axclass instances *)
+  in
+    AxClass.define_class (class, superclasses) []
+      (name_atts ~~ axiomss) thy
+  end;
 
 local
 
@@ -84,54 +118,25 @@
   in
     thy
     |> ProofContext.init
-    |> Proof.theorem_i NONE after_qed' ((map (fn t => [(t, [])]) o maps (mk_prop thy)) insts)
+    |> Proof.theorem_i NONE after_qed' ((map (fn t => [(t, [])])
+        o maps (mk_prop thy)) insts)
   end;
 
 in
 
-val axclass_instance_arity =
+val instance_arity =
   gen_instance (Logic.mk_arities oo Sign.cert_arity) AxClass.add_arity;
-val axclass_instance_sort =
+val classrel =
   gen_instance (single oo (Logic.mk_classrel oo AxClass.cert_classrel))
     AxClass.add_classrel I o single;
+val classrel_cmd =
+  gen_instance (single oo (Logic.mk_classrel oo AxClass.read_classrel))
+    AxClass.add_classrel I o single;
 
 end; (*local*)
 
 
-(* introducing axclasses with implicit parameter handling *)
-
-fun axclass_params (name, raw_superclasses) raw_consts raw_dep_axioms other_consts thy =
-  let
-    val superclasses = map (Sign.certify_class thy) raw_superclasses;
-    val consts = (map o apfst o apsnd) (Sign.certify_typ thy) raw_consts;
-    val prefix = Logic.const_of_class name;
-    fun mk_const_name c = NameSpace.map_base (NameSpace.append prefix)
-      (Sign.full_name thy c);
-    fun add_const ((c, ty), syn) =
-      Sign.add_consts_authentic [(c, ty, syn)]
-      #> pair (mk_const_name c, ty);
-    fun mk_axioms cs thy =
-      raw_dep_axioms thy cs
-      |> (map o apsnd o map) (Sign.cert_prop thy)
-      |> rpair thy;
-    fun add_constraint class (c, ty) =
-      Sign.add_const_constraint_i (c, SOME
-        (Term.map_type_tfree (fn (v, _) => TFree (v, [class])) ty));
-  in
-    thy
-    |> Theory.add_path prefix
-    |> fold_map add_const consts
-    ||> Theory.restore_naming thy
-    |-> (fn cs => mk_axioms cs
-    #-> (fn axioms_prop => AxClass.define_class (name, superclasses)
-           (map fst cs @ other_consts) axioms_prop
-    #-> (fn class => `(fn thy => AxClass.get_definition thy class)
-    #-> (fn {intro, axioms, ...} => fold (add_constraint class) cs
-    #> pair (class, ((intro, (map Thm.prop_of axioms, axioms)), cs))))))
-  end;
-
-
-(* explicit constants for overloaded definitions *)
+(** explicit constants for overloaded definitions **)
 
 structure InstData = TheoryDataFun
 (
@@ -146,22 +151,22 @@
       Symtab.merge (K true) (tabb1, tabb2));
 );
 
-fun inst_thms f thy =
-  (Symtab.fold (Symtab.fold (cons o f o snd o snd) o snd) o fst) (InstData.get thy) [];
-fun add_inst (c, tyco) inst = (InstData.map o apfst o Symtab.map_default (c, Symtab.empty))
-  (Symtab.update_new (tyco, inst))
+fun inst_thms f thy = (Symtab.fold (Symtab.fold (cons o f o snd o snd) o snd) o fst)
+    (InstData.get thy) [];
+fun add_inst (c, tyco) inst = (InstData.map o apfst
+      o Symtab.map_default (c, Symtab.empty)) (Symtab.update_new (tyco, inst))
   #> (InstData.map o apsnd) (Symtab.update_new (fst inst, (c, tyco)));
 
-fun unoverload thy thm = MetaSimplifier.rewrite false (inst_thms I thy) thm;
-fun overload thy thm = MetaSimplifier.rewrite false (inst_thms symmetric thy) thm;
+fun unoverload thy = MetaSimplifier.rewrite false (inst_thms I thy);
+fun overload thy = MetaSimplifier.rewrite false (inst_thms symmetric thy);
 
 fun inst_const thy (c, tyco) =
   (fst o the o Symtab.lookup ((the o Symtab.lookup (fst (InstData.get thy))) c)) tyco;
 fun unoverload_const thy (c_ty as (c, _)) =
   case AxClass.class_of_param thy c
    of SOME class => (case Sign.const_typargs thy c_ty
-       of [Type (tyco, _)] =>
-            (case Symtab.lookup ((the o Symtab.lookup (fst (InstData.get thy))) c) tyco
+       of [Type (tyco, _)] => (case Symtab.lookup
+           ((the o Symtab.lookup (fst (InstData.get thy))) c) tyco
              of SOME (c, _) => c
               | NONE => c)
         | [_] => c)
@@ -192,7 +197,8 @@
 
 fun add_def ((class, tyco), ((name, prop), atts)) thy =
   let
-    val ((lhs as Const (c, ty), args), rhs) = (apfst Term.strip_comb o Logic.dest_equals) prop;
+    val ((lhs as Const (c, ty), args), rhs) =
+      (apfst Term.strip_comb o Logic.dest_equals) prop;
     fun add_inst' def ([], (Const (c_inst, ty))) =
           if forall (fn TFree _ => true | _ => false) (Sign.const_typargs thy (c_inst, ty))
           then add_inst (c, tyco) (c_inst, def)
@@ -205,7 +211,7 @@
   end;
 
 
-(* instances with implicit parameter handling *)
+(** instances with implicit parameter handling **)
 
 local
 
@@ -223,7 +229,7 @@
 fun read_def_cmd thy = gen_read_def thy Attrib.intern_src Theory.read_axm;
 fun read_def thy = gen_read_def thy (K I) (K I);
 
-fun gen_instance_arity prep_arity read_def do_proof raw_arities raw_defs after_qed theory =
+fun gen_instance prep_arity read_def do_proof raw_arities raw_defs after_qed theory =
   let
     val arities = map (prep_arity theory) raw_arities;
     val _ = if null arities then error "at least one arity must be given" else ();
@@ -231,7 +237,8 @@
      of [] => ()
       | dupl_tycos => error ("type constructors occur more than once in arities: "
           ^ (commas o map quote) dupl_tycos);
-    val super_sort = (Graph.all_succs o #classes o Sorts.rep_algebra o Sign.classes_of) theory
+    val super_sort =
+      (Graph.all_succs o #classes o Sorts.rep_algebra o Sign.classes_of) theory;
     fun get_consts_class tyco ty class =
       let
         val cs = (these o Option.map snd o try (AxClass.params_of_class theory)) class;
@@ -241,7 +248,8 @@
       end;
     fun get_consts_sort (tyco, asorts, sort) =
       let
-        val ty = Type (tyco, map (fn (v, sort) => TVar ((v, 0), sort)) (Name.names Name.context "'a" asorts))
+        val ty = Type (tyco, map (fn (v, sort) => TVar ((v, 0), sort))
+          (Name.names Name.context "'a" asorts))
       in maps (get_consts_class tyco ty) (super_sort sort) end;
     val cs = maps get_consts_sort arities;
     fun mk_typnorm thy (ty, ty_sc) =
@@ -288,8 +296,6 @@
     |-> (fn (cs, defs) => do_proof (after_qed' cs defs) arities defs)
   end;
 
-fun instance_arity_cmd' do_proof = gen_instance_arity Sign.read_arity read_def_cmd do_proof;
-fun instance_arity' do_proof = gen_instance_arity Sign.cert_arity read_def do_proof;
 fun tactic_proof tac f arities defs =
   fold (fn arity => AxClass.prove_arity arity tac) arities
   #> f
@@ -297,26 +303,27 @@
 
 in
 
-val instance_arity_cmd = instance_arity_cmd'
-  (fn f => fn arities => fn defs => axclass_instance_arity f arities);
-val instance_arity = instance_arity'
-  (fn f => fn arities => fn defs => axclass_instance_arity f arities);
-fun prove_instance_arity tac arities defs =
-  instance_arity' (tactic_proof tac) arities defs (K I);
+val instance = gen_instance Sign.cert_arity read_def
+  (fn f => fn arities => fn defs => instance_arity f arities);
+val instance_cmd = gen_instance Sign.read_arity read_def_cmd
+  (fn f => fn arities => fn defs => instance_arity f arities);
+fun prove_instance tac arities defs =
+  gen_instance Sign.cert_arity read_def
+    (tactic_proof tac) arities defs (K I);
 
 end; (*local*)
 
 
 
-(** combining locales and axclasses **)
-
-(* theory data *)
+(** class data **)
 
 datatype class_data = ClassData of {
   locale: string,
   consts: (string * string) list
     (*locale parameter ~> toplevel theory constant*),
   v: string option,
+  inst: typ Symtab.table * term Symtab.table
+    (*canonical interpretation*),
   intro: thm
 } * thm list (*derived defs*);
 
@@ -336,13 +343,13 @@
 
 (* queries *)
 
-val lookup_class_data = Option.map rep_classdata oo try o Graph.get_node o fst o ClassData.get;
+val lookup_class_data = Option.map rep_classdata oo try o Graph.get_node
+  o fst o ClassData.get;
 fun class_of_locale thy = Symtab.lookup ((snd o ClassData.get) thy);
 
-fun the_class_data thy class =
-  case lookup_class_data thy class
-    of NONE => error ("undeclared class " ^ quote class)
-     | SOME data => data;
+fun the_class_data thy class = case lookup_class_data thy class
+ of NONE => error ("undeclared class " ^ quote class)
+  | SOME data => data;
 
 val ancestry = Graph.all_succs o fst o ClassData.get;
 
@@ -391,18 +398,18 @@
       ]
     ]
   in
-    (Pretty.writeln o Pretty.chunks o separate (Pretty.str "") o map mk_entry o Sorts.all_classes)
-      algebra
+    (Pretty.writeln o Pretty.chunks o separate (Pretty.str "")
+      o map mk_entry o Sorts.all_classes) algebra
   end;
 
 
 (* updaters *)
 
-fun add_class_data ((class, superclasses), (locale, consts, v, intro)) =
+fun add_class_data ((class, superclasses), (locale, consts, v, inst, intro)) =
   ClassData.map (fn (gr, tab) => (
     gr
     |> Graph.new_node (class, ClassData ({ locale = locale, consts = consts,
-         v = v, intro = intro }, []))
+         v = v, inst = inst, intro = intro }, []))
     |> fold (curry Graph.add_edge class) superclasses,
     tab
     |> Symtab.update (locale, class)
@@ -411,7 +418,65 @@
 fun add_class_const_thm (class, thm) = (ClassData.map o apfst o Graph.map_node class)
   (fn ClassData (data, thms) => ClassData (data, thm :: thms));
 
-(* tactics and methods *)
+
+(** rule calculation, tactics and methods **)
+
+fun class_intro thy locale class sups =
+  let
+    fun class_elim class =
+      case (map Drule.unconstrainTs o #axioms o AxClass.get_definition thy) class
+       of [thm] => SOME thm
+        | [] => NONE;
+    val pred_intro = case Locale.intros thy locale
+     of ([ax_intro], [intro]) => intro |> OF_LAST ax_intro |> SOME
+      | ([intro], []) => SOME intro
+      | ([], [intro]) => SOME intro
+      | _ => NONE;
+    val pred_intro' = pred_intro
+      |> Option.map (fn intro => intro OF map_filter class_elim sups);
+    val class_intro = (#intro o AxClass.get_definition thy) class;
+    val raw_intro = case pred_intro'
+     of SOME pred_intro => class_intro |> OF_LAST pred_intro
+      | NONE => class_intro;
+    val sort = Sign.super_classes thy class;
+    val typ = TVar ((AxClass.param_tyvarname, 0), sort);
+    val defs = these_defs thy sups;
+  in
+    raw_intro
+    |> Drule.instantiate' [SOME (Thm.ctyp_of thy typ)] []
+    |> strip_all_ofclass thy sort
+    |> Thm.strip_shyps
+    |> MetaSimplifier.rewrite_rule defs
+    |> Drule.unconstrainTs
+  end;
+
+fun class_interpretation class facts defs thy =
+  let
+    val ({ locale, inst, ... }, _) = the_class_data thy class;
+    val tac = (ALLGOALS o ProofContext.fact_tac) facts;
+    val prfx = Logic.const_of_class (NameSpace.base class);
+  in
+    prove_interpretation tac ((false, prfx), []) (Locale.Locale locale)
+      (inst, defs) thy
+  end;
+
+fun interpretation_in_rule thy (class1, class2) =
+  let
+    fun mk_axioms class =
+      let
+        val ({ locale, inst = (_, insttab), ... }, _) = the_class_data thy class;
+      in
+        Locale.global_asms_of thy locale
+        |> maps snd
+        |> (map o map_aterms) (fn Free (s, _) => (the o Symtab.lookup insttab) s | t => t)
+        |> (map o map_types o map_atyps) (fn TFree _ => TFree ("'a", [class1]) | T => T)
+        |> map (ObjectLogic.ensure_propT thy)
+      end;
+    val (prems, concls) = pairself mk_axioms (class1, class2);
+  in
+    Goal.prove_global thy [] prems (Logic.mk_conjunction_list concls)
+      (Locale.intro_locales_tac true (ProofContext.init thy))
+  end;
 
 fun intro_classes_tac facts st =
   let
@@ -443,102 +508,9 @@
     "apply some intro/elim rule")]);
 
 
-(* tactical interfaces to locale commands *)
-
-fun prove_interpretation tac prfx_atts expr insts thy =
-  thy
-  |> Locale.interpretation_i I prfx_atts expr insts
-  |> Proof.global_terminal_proof (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
-  |> ProofContext.theory_of;
-
-fun prove_interpretation_in tac after_qed (name, expr) thy =
-  thy
-  |> Locale.interpretation_in_locale (ProofContext.theory after_qed) (name, expr)
-  |> Proof.global_terminal_proof (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
-  |> ProofContext.theory_of;
-
-
-(* constructing class introduction and other rules from axclass and locale rules *)
-
-fun mk_instT class = Symtab.empty
-  |> Symtab.update (AxClass.param_tyvarname, TFree (AxClass.param_tyvarname, [class]));
-
-fun mk_inst class param_names cs =
-  Symtab.empty
-  |> fold2 (fn v => fn (c, ty) => Symtab.update (v, Const
-       (c, Term.map_type_tfree (fn (v, _) => TFree (v, [class])) ty))) param_names cs;
-
-fun OF_LAST thm1 thm2 =
-  let
-    val n = (length o Logic.strip_imp_prems o prop_of) thm2;
-  in (thm1 RSN (n, thm2)) end;
-
-fun strip_all_ofclass thy sort =
-  let
-    val typ = TVar ((AxClass.param_tyvarname, 0), sort);
-    fun prem_inclass t =
-      case Logic.strip_imp_prems t
-       of ofcls :: _ => try Logic.dest_inclass ofcls
-        | [] => NONE;
-    fun strip_ofclass class thm =
-      thm OF (fst o AxClass.of_sort thy (typ, [class])) AxClass.cache;
-    fun strip thm = case (prem_inclass o Thm.prop_of) thm
-     of SOME (_, class) => thm |> strip_ofclass class |> strip
-      | NONE => thm;
-  in strip end;
+(** classes and class target **)
 
-fun class_intro thy locale class sups =
-  let
-    fun class_elim class =
-      case (map Drule.unconstrainTs o #axioms o AxClass.get_definition thy) class
-       of [thm] => SOME thm
-        | [] => NONE;
-    val pred_intro = case Locale.intros thy locale
-     of ([ax_intro], [intro]) => intro |> OF_LAST ax_intro |> SOME
-      | ([intro], []) => SOME intro
-      | ([], [intro]) => SOME intro
-      | _ => NONE;
-    val pred_intro' = pred_intro
-      |> Option.map (fn intro => intro OF map_filter class_elim sups);
-    val class_intro = (#intro o AxClass.get_definition thy) class;
-    val raw_intro = case pred_intro'
-     of SOME pred_intro => class_intro |> OF_LAST pred_intro
-      | NONE => class_intro;
-    val sort = Sign.super_classes thy class;
-    val typ = TVar ((AxClass.param_tyvarname, 0), sort);
-    val defs = these_defs thy sups;
-  in
-    raw_intro
-    |> Drule.instantiate' [SOME (Thm.ctyp_of thy typ)] []
-    |> strip_all_ofclass thy sort
-    |> Thm.strip_shyps
-    |> MetaSimplifier.rewrite_rule defs
-    |> Drule.unconstrainTs
-  end;
-
-fun interpretation_in_rule thy (class1, class2) =
-  let
-    val (params, consts) = split_list (params_of_sort thy [class1]);
-    (*FIXME also remember this at add_class*)
-    fun mk_axioms class =
-      let
-        val name_locale = (#locale o fst o the_class_data thy) class;
-        val inst = mk_inst class params consts;
-      in
-        Locale.global_asms_of thy name_locale
-        |> maps snd
-        |> (map o map_aterms) (fn Free (s, _) => (the o Symtab.lookup inst) s | t => t)
-        |> (map o map_types o map_atyps) (fn TFree _ => TFree ("'a", [class1]) | T => T)
-        |> map (ObjectLogic.ensure_propT thy)
-      end;
-    val (prems, concls) = pairself mk_axioms (class1, class2);
-  in
-    Goal.prove_global thy [] prems (Logic.mk_conjunction_list concls)
-      (Locale.intro_locales_tac true (ProofContext.init thy))
-  end;
-
-
-(* classes *)
+(* class definition *)
 
 local
 
@@ -553,11 +525,18 @@
 fun gen_class add_locale prep_class prep_param bname
     raw_supclasses raw_elems raw_other_consts thy =
   let
+    fun mk_instT class = Symtab.empty
+      |> Symtab.update (AxClass.param_tyvarname, TFree (AxClass.param_tyvarname, [class]));
+    fun mk_inst class param_names cs =
+      Symtab.empty
+      |> fold2 (fn v => fn (c, ty) => Symtab.update (v, Const
+           (c, Term.map_type_tfree (fn (v, _) => TFree (v, [class])) ty))) param_names cs;
     (*FIXME need proper concept for reading locale statements*)
     fun subst_classtyvar (_, _) =
           TFree (AxClass.param_tyvarname, [])
       | subst_classtyvar (v, sort) =
-          error ("Sort constraint illegal in type class, for type variable " ^ v ^ "::" ^ Sign.string_of_sort thy sort);
+          error ("Sort constraint illegal in type class, for type variable "
+            ^ v ^ "::" ^ Sign.string_of_sort thy sort);
     (*val subst_classtyvars = Element.map_ctxt {name = I, var = I, term = I,
       typ = Term.map_type_tfree subst_classtyvar, fact = I, attrib = I};*)
     val other_consts = map (prep_param thy) raw_other_consts;
@@ -602,7 +581,7 @@
         val super_defs = these_defs thy sups;
         fun prep_asm ((name, atts), ts) =
           ((NameSpace.base name, map (Attrib.attribute thy) atts),
-            (map o map_aterms) ((*MetaSimplifier.rewrite_term thy super_defs [] o *)subst) ts);
+            (map o map_aterms) subst ts);
       in
         Locale.global_asms_of thy name_locale
         |> map prep_asm
@@ -617,21 +596,17 @@
     |-> (fn name_locale => ProofContext.theory_result (
       `(fn thy => extract_params thy name_locale)
       #-> (fn (v, (param_names, params)) =>
-        axclass_params (bname, supsort) params (extract_assumes name_locale params) other_consts
-      #-> (fn (name_axclass, ((_, (ax_terms, ax_axioms)), consts)) =>
+        AxClass.define_class_params (bname, supsort) params
+          (extract_assumes name_locale params) other_consts
+      #-> (fn (name_axclass, (consts, axioms)) =>
         `(fn thy => class_intro thy name_locale name_axclass sups)
       #-> (fn class_intro =>
         add_class_data ((name_axclass, sups),
           (name_locale, map (fst o fst) params ~~ map fst consts, v,
-            class_intro))
-        (*FIXME: class_data should already contain data relevant
-          for interpretation; use this later for class target*)
-        (*FIXME: general export_fixes which may be parametrized
-          with pieces of an emerging class*)
+            (mk_instT name_axclass, mk_inst name_axclass param_names
+              (map snd supconsts @ consts)), class_intro))
       #> note_intro name_axclass class_intro
-      #> prove_interpretation ((ALLGOALS o ProofContext.fact_tac) ax_axioms)
-          ((false, Logic.const_of_class bname), []) (Locale.Locale name_locale)
-          ((mk_instT name_axclass, mk_inst name_axclass param_names (map snd supconsts @ consts)), [])
+      #> class_interpretation name_axclass axioms []
       #> pair name_axclass
       )))))
   end;
@@ -643,73 +618,8 @@
 
 end; (*local*)
 
-local
 
-fun instance_subclass (class1, class2) thy  =
-  let
-    val interp = interpretation_in_rule thy (class1, class2);
-    val ax = #axioms (AxClass.get_definition thy class1);
-    val intro = #intro (AxClass.get_definition thy class2)
-      |> Drule.instantiate' [SOME (Thm.ctyp_of thy
-          (TVar ((AxClass.param_tyvarname, 0), [class1])))] [];
-    val thm = 
-      intro
-      |> OF_LAST (interp OF ax)
-      |> strip_all_ofclass thy (Sign.super_classes thy class2);
-  in
-    thy |> AxClass.add_classrel thm
-  end;
-
-fun instance_subsort (class, sort) thy =
-  let
-    val super_sort = (Graph.all_succs o #classes o Sorts.rep_algebra
-      o Sign.classes_of) thy sort;
-    val classes = filter_out (fn class' => Sign.subsort thy ([class], [class']))
-      (rev super_sort);
-  in
-    thy |> fold (curry instance_subclass class) classes
-  end;
-
-fun instance_sort' do_proof (class, sort) theory =
-  let
-    val loc_name = (#locale o fst o the_class_data theory) class;
-    val loc_expr =
-      (Locale.Merge o map (Locale.Locale o #locale o fst o the_class_data theory)) sort;
-  in
-    theory
-    |> do_proof (instance_subsort (class, sort)) (loc_name, loc_expr)
-  end;
-
-fun gen_instance_sort prep_class prep_sort (raw_class, raw_sort) theory =
-  let
-    val class = prep_class theory raw_class;
-    val sort = prep_sort theory raw_sort;
-  in
-    theory
-    |> instance_sort' (Locale.interpretation_in_locale o ProofContext.theory) (class, sort)
-  end;
-
-fun gen_instance_class prep_class (raw_class, raw_superclass) theory =
-  let
-    val class = prep_class theory raw_class;
-    val superclass = prep_class theory raw_superclass;
-  in
-    theory
-    |> axclass_instance_sort (class, superclass)
-  end;
-
-in
-
-val instance_sort_cmd = gen_instance_sort Sign.read_class Syntax.global_read_sort;
-val instance_sort = gen_instance_sort Sign.certify_class Sign.certify_sort;
-val prove_instance_sort = instance_sort' o prove_interpretation_in;
-val instance_class_cmd = gen_instance_class Sign.read_class;
-val instance_class = gen_instance_class Sign.certify_class;
-
-end; (*local*)
-
-
-(** class target **)
+(* definition in class target *)
 
 fun export_fixes thy class =
   let
@@ -740,14 +650,10 @@
     val (syn', _) = fork_mixfix true NONE syn;
     fun interpret def =
       let
-        val def' = symmetric def
-        val tac = (ALLGOALS o ProofContext.fact_tac) [def'];
-        val name_locale = (#locale o fst o the_class_data thy) class;
+        val def' = symmetric def;
         val def_eq = Thm.prop_of def';
-        val (params, consts) = split_list (params_of_sort thy [class]);
       in
-        prove_interpretation tac ((false, prfx), []) (Locale.Locale name_locale)
-          ((mk_instT class, mk_inst class params consts), [def_eq])
+        class_interpretation class [def'] [def_eq]
         #> add_class_const_thm (class, def')
       end;
   in
@@ -762,4 +668,53 @@
     |> Sign.restore_naming thy
   end;
 
+
+(* interpretation in class target *)
+
+local
+
+fun gen_interpretation_in_class prep_class do_proof (raw_class, raw_superclass) theory =
+  let
+    val class = prep_class theory raw_class;
+    val superclass = prep_class theory raw_superclass;
+    val loc_name = (#locale o fst o the_class_data theory) class;
+    val loc_expr = (Locale.Locale o #locale o fst o the_class_data theory) superclass;
+    fun prove_classrel (class, superclass) thy =
+      let
+        val classes = (Graph.all_succs o #classes o Sorts.rep_algebra
+              o Sign.classes_of) thy [superclass]
+          |> filter_out (fn class' => Sign.subsort thy ([class], [class']));
+        fun instance_subclass (class1, class2) thy  =
+          let
+            val interp = interpretation_in_rule thy (class1, class2);
+            val ax = #axioms (AxClass.get_definition thy class1);
+            val intro = #intro (AxClass.get_definition thy class2)
+              |> Drule.instantiate' [SOME (Thm.ctyp_of thy
+                  (TVar ((AxClass.param_tyvarname, 0), [class1])))] [];
+            val thm = 
+              intro
+              |> OF_LAST (interp OF ax)
+              |> strip_all_ofclass thy (Sign.super_classes thy class2);
+          in
+            thy |> AxClass.add_classrel thm
+          end;
+      in
+        thy |> fold_rev (curry instance_subclass class) classes
+      end;
+  in
+    theory
+    |> do_proof (prove_classrel (class, superclass)) (loc_name, loc_expr)
+  end;
+
+in
+
+val interpretation_in_class = gen_interpretation_in_class Sign.certify_class
+  (Locale.interpretation_in_locale o ProofContext.theory);
+val interpretation_in_class_cmd = gen_interpretation_in_class Sign.read_class
+  (Locale.interpretation_in_locale o ProofContext.theory);
+val prove_interpretation_in_class = gen_interpretation_in_class Sign.certify_class
+  o prove_interpretation_in;
+
+end; (*local*)
+
 end;
--- a/src/Pure/Isar/isar_syn.ML	Sat Sep 15 19:27:43 2007 +0200
+++ b/src/Pure/Isar/isar_syn.ML	Sat Sep 15 19:27:44 2007 +0200
@@ -427,13 +427,24 @@
 val instanceP =
   OuterSyntax.command "instance" "prove type arity or subclass relation" K.thy_goal ((
       P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname)
-           >> Class.instance_class_cmd
+           >> Class.classrel_cmd
       || P.$$$ "advanced" |-- P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname)
-           >> Class.instance_sort_cmd
+           >> Class.interpretation_in_class_cmd
       || P.and_list1 P.arity -- Scan.repeat (SpecParse.opt_thm_name ":" -- P.prop)
-           >> (fn (arities, defs) => Class.instance_arity_cmd arities defs (fold (Code.add_func false)))
+           >> (fn (arities, defs) => Class.instance_cmd arities defs (fold (Code.add_func false)))
     ) >> (Toplevel.print oo Toplevel.theory_to_proof));
 
+val instantiationP =
+  OuterSyntax.command "instantiation" "prove type arity" K.thy_decl (
+      P.and_list1 P.arity -- P.opt_begin
+           >> (fn (arities, begin) => (begin ? Toplevel.print)
+            o Toplevel.begin_local_theory begin
+                (Instance.begin_instantiation_cmd arities)));
+
+val instance_proofP =
+  OuterSyntax.command "instance_proof" "prove type arity relation" K.thy_goal
+      (Scan.succeed ((Toplevel.print oo Toplevel.local_theory_to_proof NONE) Instance.proof_instantiation));
+
 end;
 
 
@@ -993,7 +1004,7 @@
   simproc_setupP, parse_ast_translationP, parse_translationP,
   print_translationP, typed_print_translationP,
   print_ast_translationP, token_translationP, oracleP, contextP,
-  localeP, classP, instanceP, code_datatypeP,
+  localeP, classP, instanceP, instantiationP, instance_proofP, code_datatypeP,
   (*proof commands*)
   theoremP, lemmaP, corollaryP, haveP, henceP, showP, thusP, fixP,
   assumeP, presumeP, defP, obtainP, guessP, letP, caseP, thenP, fromP,
--- a/src/Pure/axclass.ML	Sat Sep 15 19:27:43 2007 +0200
+++ b/src/Pure/axclass.ML	Sat Sep 15 19:27:44 2007 +0200
@@ -8,6 +8,16 @@
 
 signature AX_CLASS =
 sig
+  val define_class: bstring * class list -> string list ->
+    ((bstring * attribute list) * term list) list -> theory -> class * theory
+  val define_class_params: bstring * class list -> ((bstring * typ) * mixfix) list ->
+    (theory -> (string * typ) list -> ((bstring * attribute list) * term list) list) ->
+    string list -> theory ->
+    (class * ((string * typ) list * thm list)) * theory
+  val add_classrel: thm -> theory -> theory
+  val add_arity: thm -> theory -> theory
+  val prove_classrel: class * class -> tactic -> theory -> theory
+  val prove_arity: string * sort list * sort -> tactic -> theory -> theory
   val get_definition: theory -> class -> {def: thm, intro: thm, axioms: thm list,
     params: (string * typ) list}
   val class_intros: theory -> thm list
@@ -17,12 +27,6 @@
   val print_axclasses: theory -> unit
   val cert_classrel: theory -> class * class -> class * class
   val read_classrel: theory -> xstring * xstring -> class * class
-  val add_classrel: thm -> theory -> theory
-  val add_arity: thm -> theory -> theory
-  val prove_classrel: class * class -> tactic -> theory -> theory
-  val prove_arity: string * sort list * sort -> tactic -> theory -> theory
-  val define_class: bstring * class list -> string list ->
-    ((bstring * attribute list) * term list) list -> theory -> class * theory
   val axiomatize_class: bstring * xstring list -> theory -> theory
   val axiomatize_class_i: bstring * class list -> theory -> theory
   val axiomatize_classrel: (xstring * xstring) list -> theory -> theory
@@ -359,6 +363,40 @@
 
 
 
+(** axclasses with implicit parameter handling **)
+
+fun define_class_params (name, raw_superclasses) raw_consts raw_dep_axioms other_consts thy =
+  let
+    val superclasses = map (Sign.certify_class thy) raw_superclasses;
+    val consts = (map o apfst o apsnd) (Sign.certify_typ thy) raw_consts;
+    val prefix = Logic.const_of_class name;
+    fun mk_const_name c = NameSpace.map_base (NameSpace.append prefix)
+      (Sign.full_name thy c);
+    fun add_const ((c, ty), syn) =
+      Sign.add_consts_authentic [(c, ty, syn)]
+      #> pair (mk_const_name c, ty);
+    fun mk_axioms cs thy =
+      raw_dep_axioms thy cs
+      |> (map o apsnd o map) (Sign.cert_prop thy)
+      |> rpair thy;
+    fun add_constraint class (c, ty) =
+      Sign.add_const_constraint_i (c, SOME
+        (Term.map_type_tfree (fn (v, _) => TFree (v, [class])) ty));
+  in
+    thy
+    |> Theory.add_path prefix
+    |> fold_map add_const consts
+    ||> Theory.restore_naming thy
+    |-> (fn cs => mk_axioms cs
+    #-> (fn axioms_prop => define_class (name, superclasses)
+           (map fst cs @ other_consts) axioms_prop
+    #-> (fn class => `(fn thy => get_definition thy class)
+    #-> (fn {axioms, ...} => fold (add_constraint class) cs
+    #> pair (class, (cs, axioms))))))
+  end;
+
+
+
 (** axiomatizations **)
 
 local