improved
authorhaftmann
Wed, 05 Dec 2007 14:15:51 +0100
changeset 25536 01753a944433
parent 25535 4975b7529a14
child 25537 55017c8b0a24
improved
src/HOL/Library/Eval.thy
src/HOL/ex/ExecutableContent.thy
src/Pure/Isar/class.ML
src/Pure/Isar/instance.ML
src/Pure/Isar/isar_syn.ML
src/Pure/Isar/overloading.ML
--- a/src/HOL/Library/Eval.thy	Wed Dec 05 14:15:48 2007 +0100
+++ b/src/HOL/Library/Eval.thy	Wed Dec 05 14:15:51 2007 +0100
@@ -18,47 +18,64 @@
 structure TypOf =
 struct
 
-val class_typ_of = Sign.intern_class @{theory} "typ_of";
-
-fun term_typ_of_type ty =
+fun mk ty =
   Const (@{const_name typ_of}, Term.itselfT ty --> @{typ typ})
     $ Logic.mk_type ty;
 
-fun mk_typ_of_def ty =
-  let
-    val lhs = Const (@{const_name typ_of}, Term.itselfT ty --> @{typ typ})
-      $ Free ("x", Term.itselfT ty)
-    val rhs = Pure_term.mk_typ (fn v => term_typ_of_type (TFree v)) ty
-  in Logic.mk_equals (lhs, rhs) end;
-
-end;
+end
 *}
 
-instance "prop" :: typ_of
-  "typ_of (T\<Colon>prop itself) \<equiv> STR ''prop'' {\<struct>} []" ..
-
-instance itself :: (typ_of) typ_of
-  "typ_of (T\<Colon>'a itself itself) \<equiv> STR ''itself'' {\<struct>} [typ_of TYPE('a\<Colon>typ_of)]" ..
-
-instance set :: (typ_of) typ_of
-  "typ_of (T\<Colon>'a set itself) \<equiv> STR ''set'' {\<struct>} [typ_of TYPE('a\<Colon>typ_of)]" ..
-
-instance int :: typ_of
-  "typ_of (T\<Colon>int itself) \<equiv> STR ''IntDef.int'' {\<struct>} []" ..
-
 setup {*
 let
-  fun mk arities _ thy =
-    (maps (fn (tyco, asorts, _) => [(("", []), TypOf.mk_typ_of_def
-      (Type (tyco,
-        map TFree (Name.names Name.context "'a" asorts))))]) arities, thy);
-  fun hook specs =
-    DatatypeCodegen.prove_codetypes_arities (Class.intro_classes_tac [])
-      (map (fn (tyco, (is_dt, _)) => (tyco, is_dt)) specs)
-      [TypOf.class_typ_of] mk ((K o K) (fold Code.add_default_func))
-in DatatypeCodegen.add_codetypes_hook hook end
+  fun define_typ_of ty lthy =
+    let
+      val lhs = Const (@{const_name typ_of}, Term.itselfT ty --> @{typ typ})
+        $ Free ("T", Term.itselfT ty);
+      val rhs = Pure_term.mk_typ (fn v => TypOf.mk (TFree v)) ty;
+      val eq = Class.prep_spec lthy (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs)))
+    in lthy |> Specification.definition (NONE, (("", []), eq)) end;
+  fun interpretator tyco thy =
+    let
+      val sorts = replicate (Sign.arity_number thy tyco) @{sort typ_of};
+      val ty = Type (tyco, map TFree (Name.names Name.context "'a" sorts));
+    in
+      thy
+      |> Instance.instantiate ([tyco], sorts, @{sort typ_of})
+           (define_typ_of ty) ((K o K) (Class.intro_classes_tac []))
+    end;
+in TypedefPackage.interpretation interpretator end
 *}
 
+instantiation "prop" :: typ_of
+begin
+
+definition
+  "typ_of (T\<Colon>prop itself) = STR ''prop'' {\<struct>} []"
+
+instance ..
+
+end
+
+instantiation itself :: (typ_of) typ_of
+begin
+
+definition
+  "typ_of (T\<Colon>'a itself itself) = STR ''itself'' {\<struct>} [typ_of TYPE('a\<Colon>typ_of)]"
+
+instance ..
+
+end
+
+instantiation set :: (typ_of) typ_of
+begin
+ 
+definition
+  "typ_of (T\<Colon>'a set itself) = STR ''set'' {\<struct>} [typ_of TYPE('a\<Colon>typ_of)]"
+
+instance ..
+
+end
+
 
 subsection {* @{text term_of} class *}
 
@@ -83,7 +100,7 @@
           val lhs : term = term_term_of dty $ c;
           val rhs : term = Pure_term.mk_term
             (fn (v, ty) => term_term_of ty $ Free (v, ty))
-            (Pure_term.mk_typ (fn (v, sort) => TypOf.term_typ_of_type (TFree (v, sort)))) c
+            (Pure_term.mk_typ (fn (v, sort) => TypOf.mk (TFree (v, sort)))) c
         in
           HOLogic.mk_eq (lhs, rhs)
         end;
@@ -101,24 +118,43 @@
     PureThy.add_thmss [((name, thms), atts)] #-> (fn [thms] => pair (name, thms));
   fun thy_def ((name, atts), t) =
     PureThy.add_defs_i false [((name, t), atts)] #-> (fn [thm] => pair (name, thm));
-  fun mk arities css _ thy =
+  fun prep_dtyp thy vs tyco =
+    let
+      val (_, cs) = DatatypePackage.the_datatype_spec thy tyco;
+      val prep_typ = map_atyps (fn TFree (v, sort) =>
+        TFree (v, (the o AList.lookup (op =) vs) v));
+      fun prep_c (c, tys) = list_comb (Const (c, tys ---> Type (tyco, map TFree vs)),
+        map Free (Name.names Name.context "a" tys));
+    in (tyco, map (prep_c o (apsnd o map) prep_typ) cs) end;
+  fun prep thy tycos =
     let
-      val (_, asorts, _) :: _ = arities;
-      val vs = Name.names Name.context "'a" asorts;
+      val inter_sort = curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
+      val tyco = hd tycos;
+      val (vs_proto, _) = DatatypePackage.the_datatype_spec thy tyco;
+      val all_typs = maps (maps snd o snd o DatatypePackage.the_datatype_spec thy) tycos;
+      fun add_tycos (Type (tyco, tys)) = insert (op =) tyco #>
+            fold add_tycos tys
+        | add_tycos _ = I;
+      val dep_tycos = [] |> fold add_tycos all_typs |> subtract (op =) tycos;
+      val sorts = map (inter_sort o snd) vs_proto;
+      val vs = map fst vs_proto ~~ sorts;
+      val css = map (prep_dtyp thy vs) tycos;
       val defs = map (TermOf.mk_terms_of_defs vs) css;
       val defs' = (map (pair ("", []) o ObjectLogic.ensure_propT thy) o flat) defs;
-    in
-      thy
-      |> PrimrecPackage.gen_primrec thy_note thy_def "" defs'
-      |> snd
+    in if forall (fn tyco => can (Sign.arity_sorts thy tyco) @{sort term_of}) dep_tycos
+        andalso not (tycos = [@{type_name typ}])
+      then SOME (sorts, defs')
+      else NONE
     end;
-  fun hook specs =
-    if null specs orelse (fst o hd) specs = (fst o dest_Type) @{typ typ} then I
-    else
-      DatatypeCodegen.prove_codetypes_arities (Class.intro_classes_tac [])
-      (map (fn (tyco, (is_dt, _)) => (tyco, is_dt)) specs)
-      [TermOf.class_term_of] ((K o K o pair) []) mk
-in DatatypeCodegen.add_codetypes_hook hook end
+  fun interpretator tycos thy = case prep thy tycos
+   of SOME (sorts, defs) =>
+      thy
+      |> Instance.instantiate (tycos, sorts, @{sort term_of})
+           (pair ()) ((K o K) (Class.intro_classes_tac []))
+      |> PrimrecPackage.gen_primrec thy_note thy_def "" defs
+      |> snd
+    | NONE => thy;
+  in DatatypePackage.interpretation interpretator end
 *}
 
 abbreviation
--- a/src/HOL/ex/ExecutableContent.thy	Wed Dec 05 14:15:48 2007 +0100
+++ b/src/HOL/ex/ExecutableContent.thy	Wed Dec 05 14:15:51 2007 +0100
@@ -7,7 +7,7 @@
 theory ExecutableContent
 imports
   Main
-  (*Eval*)
+  Eval
   "~~/src/HOL/ex/Records"
   AssocList
   Binomial
--- a/src/Pure/Isar/class.ML	Wed Dec 05 14:15:48 2007 +0100
+++ b/src/Pure/Isar/class.ML	Wed Dec 05 14:15:51 2007 +0100
@@ -31,7 +31,8 @@
   val print_classes: theory -> unit
 
   (*instances*)
-  val init_instantiation: arity list -> theory -> local_theory
+  val init_instantiation: string list * sort list * sort -> theory -> local_theory
+  val prep_spec: local_theory -> term -> term
   val instantiation_instance: (local_theory -> local_theory) -> local_theory -> Proof.state
   val prove_instantiation_instance: (Proof.context -> tactic) -> local_theory -> local_theory
   val conclude_instantiation: local_theory -> local_theory
@@ -56,8 +57,8 @@
   val classrel_cmd: xstring * xstring -> theory -> Proof.state
 
   (*old instance layer*)
-  val instance_arity: (theory -> theory) -> arity list -> theory -> Proof.state
-  val instance_arity_cmd: (bstring * xstring list * xstring) list -> theory -> Proof.state
+  val instance_arity: (theory -> theory) -> arity -> theory -> Proof.state
+  val instance_arity_cmd: bstring * xstring list * xstring -> theory -> Proof.state
 end;
 
 structure Class : CLASS =
@@ -134,7 +135,7 @@
     thy
     |> ProofContext.init
     |> Proof.theorem_i NONE after_qed' ((map (fn t => [(t, [])])
-        o maps (mk_prop thy)) insts)
+        o mk_prop thy) insts)
   end;
 
 in
@@ -144,11 +145,9 @@
 val instance_arity_cmd =
   gen_instance (Logic.mk_arities oo Sign.read_arity) AxClass.add_arity I;
 val classrel =
-  gen_instance (single oo (Logic.mk_classrel oo AxClass.cert_classrel))
-    AxClass.add_classrel I o single;
+  gen_instance (single oo (Logic.mk_classrel oo AxClass.cert_classrel)) AxClass.add_classrel I;
 val classrel_cmd =
-  gen_instance (single oo (Logic.mk_classrel oo AxClass.read_classrel))
-    AxClass.add_classrel I o single;
+  gen_instance (single oo (Logic.mk_classrel oo AxClass.read_classrel)) AxClass.add_classrel I;
 
 end; (*local*)
 
@@ -826,14 +825,14 @@
 (* bookkeeping *)
 
 datatype instantiation = Instantiation of {
-  arities: arity list,
+  arities: string list * sort list * sort,
   params: ((string * string) * (string * typ)) list
 }
 
 structure Instantiation = ProofDataFun
 (
   type T = instantiation
-  fun init _ = Instantiation { arities = [], params = [] };
+  fun init _ = Instantiation { arities = ([], [], []), params = [] };
 );
 
 fun mk_instantiation (arities, params) =
@@ -844,7 +843,7 @@
   (fn Instantiation { arities, params } => mk_instantiation (f (arities, params)));
 
 fun the_instantiation lthy = case get_instantiation lthy
- of { arities = [], ... } => error "No instantiation target"
+ of { arities = ([], [], []), ... } => error "No instantiation target"
   | data => data;
 
 val instantiation_params = #params o get_instantiation;
@@ -859,6 +858,19 @@
 
 (* syntax *)
 
+fun subst_param thy params = map_aterms (fn t as Const (c, ty) => (case inst_tyco thy (c, ty)
+     of SOME tyco => (case AList.lookup (op =) params (c, tyco)
+         of SOME v_ty => Free v_ty
+          | NONE => t)
+      | NONE => t)
+  | t => t);
+
+fun prep_spec lthy =
+  let
+    val thy = ProofContext.theory_of lthy;
+    val params = instantiation_params lthy;
+  in subst_param thy params end;
+
 fun inst_term_check ts lthy =
   let
     val params = instantiation_params lthy;
@@ -873,12 +885,7 @@
       | check_improve _ = I;
     val improvement = (fold o fold_aterms) check_improve ts Vartab.empty;
     val ts' = (map o map_types) (Envir.typ_subst_TVars improvement) ts;
-    val ts'' = (map o map_aterms) (fn t as Const (c, ty) => (case inst_tyco thy (c, ty)
-         of SOME tyco => (case AList.lookup (op =) params (c, tyco)
-             of SOME v_ty => Free v_ty
-              | NONE => t)
-          | NONE => t)
-      | t => t) ts';
+    val ts'' = map (subst_param thy params) ts';
   in if eq_list (op aconv) (ts, ts'') then NONE else SOME (ts'', lthy) end;
 
 fun inst_term_uncheck ts lthy =
@@ -908,33 +915,24 @@
     explode #> scan_valids #> implode
   end;
 
-fun init_instantiation arities thy =
+fun init_instantiation (tycos, sorts, sort) thy =
   let
-    val _ = if null arities then error "At least one arity must be given" else ();
-    val _ = case (duplicates (op =) o map #1) arities
-     of [] => ()
-      | dupl_tycos => error ("Type constructors occur more than once in arities: "
-          ^ commas_quote dupl_tycos);
-    val _ = map (map (the_class_data thy) o #3) arities;
-    val ty_insts = map (fn (tyco, sorts, _) =>
-        (tyco, Type (tyco, map TFree (Name.names Name.context Name.aT sorts))))
-      arities;
-    val ty_inst = the o AList.lookup (op =) ty_insts;
+    val _ = if null tycos then error "At least one arity must be given" else ();
+    val _ = map (the_class_data thy) sort;
+    val vs = map TFree (Name.names Name.context Name.aT sorts);
     fun type_name "*" = "prod"
       | type_name "+" = "sum"
       | type_name s = sanatize_name (NameSpace.base s); (*FIXME*)
-    fun get_param tyco sorts (param, (c, ty)) = if can (inst thy) (c, tyco)
+    fun get_param tyco (param, (c, ty)) = if can (inst thy) (c, tyco)
       then NONE else SOME ((unoverload_const thy (c, ty), tyco),
-        (param ^ "_" ^ type_name tyco, map_atyps (K (ty_inst tyco)) ty));
-    fun get_params (tyco, sorts, sort) =
-      map_filter (get_param tyco sorts) (these_params thy sort)
-    val params = maps get_params arities;
+        (param ^ "_" ^ type_name tyco, map_atyps (K (Type (tyco, vs))) ty));
+    val params = map_product get_param tycos (these_params thy sort) |> map_filter I;
   in
     thy
     |> ProofContext.init
-    |> Instantiation.put (mk_instantiation (arities, params))
-    |> fold (Variable.declare_term o Logic.mk_type o snd) ty_insts
-    |> fold ProofContext.add_arity arities
+    |> Instantiation.put (mk_instantiation ((tycos, sorts, sort), params))
+    |> fold (Variable.declare_term o Logic.mk_type) vs
+    |> fold (fn tyco => ProofContext.add_arity (tyco, sorts, sort)) tycos
     |> Context.proof_map (
         Syntax.add_term_check 0 "instance" inst_term_check
         #> Syntax.add_term_uncheck 0 "instance" inst_term_uncheck)
@@ -942,8 +940,8 @@
 
 fun gen_instantiation_instance do_proof after_qed lthy =
   let
-    val arities = (#arities o the_instantiation) lthy;
-    val arities_proof = maps Logic.mk_arities arities;
+    val (tycos, sorts, sort) = (#arities o the_instantiation) lthy;
+    val arities_proof = maps (fn tyco => Logic.mk_arities (tyco, sorts, sort)) tycos;
     fun after_qed' results =
       LocalTheory.theory (fold (AxClass.add_arity o Thm.varifyT) results)
       #> after_qed;
@@ -962,6 +960,7 @@
 fun conclude_instantiation lthy =
   let
     val { arities, params } = the_instantiation lthy;
+    val (tycos, sorts, sort) = arities;
     val thy = ProofContext.theory_of lthy;
     (*val _ = map (fn (tyco, sorts, sort) =>
       if Sign.of_sort thy
@@ -970,8 +969,8 @@
         arities; FIXME activate when old instance command is gone*)
     val params_of = maps (these o try (#params o AxClass.get_info thy))
       o Sign.complete_sort thy;
-    val missing_params = arities
-      |> maps (fn (tyco, _, sort) => params_of sort |> map (rpair tyco))
+    val missing_params = tycos
+      |> maps (fn tyco => params_of sort |> map (rpair tyco))
       |> filter_out (can (inst thy) o apfst fst);
     fun declare_missing ((c, ty0), tyco) thy =
     (*fun declare_missing ((c, tyco), (_, ty)) thy =*)
--- a/src/Pure/Isar/instance.ML	Wed Dec 05 14:15:48 2007 +0100
+++ b/src/Pure/Isar/instance.ML	Wed Dec 05 14:15:51 2007 +0100
@@ -7,35 +7,38 @@
 
 signature INSTANCE =
 sig
-  val instantiate: arity list -> (local_theory -> local_theory)
-    -> (Proof.context -> tactic) -> theory -> theory
-  val instance: arity list -> ((bstring * Attrib.src list) * term) list
-    -> theory -> Proof.state
-  val prove_instance: tactic -> arity list -> ((bstring * Attrib.src list) * term) list
-    -> theory -> thm list * theory
+  val instantiate: string list * sort list * sort -> (local_theory -> 'a * local_theory)
+    -> (Proof.context -> 'a -> tactic) -> theory -> theory
 
-  val instantiation_cmd: (xstring * sort * xstring) list
-    -> theory -> local_theory
-  val instance_cmd: (xstring * sort * xstring) list -> ((bstring * Attrib.src list) * xstring) list
+  val instantiation_cmd: xstring list * sort * xstring -> theory -> local_theory
+  val instance_cmd: xstring * sort * xstring -> ((bstring * Attrib.src list) * xstring) list
     -> theory -> Proof.state
 end;
 
 structure Instance : INSTANCE =
 struct
 
+fun read_multi_arity thy (raw_tycos, raw_sorts, raw_sort) =
+  let
+    val all_arities = map (fn raw_tyco => Sign.read_arity thy
+      (raw_tyco, raw_sorts, raw_sort)) raw_tycos;
+    val tycos = map #1 all_arities;
+    val (_, sorts, sort) = hd all_arities;
+  in (tycos, sorts, sort) end;
+
 fun instantiation_cmd raw_arities thy =
-  TheoryTarget.instantiation (map (Sign.read_arity thy) raw_arities) thy;
+  TheoryTarget.instantiation (read_multi_arity thy raw_arities) thy;
 
 fun instantiate arities f tac =
   TheoryTarget.instantiation arities
   #> f
-  #> Class.prove_instantiation_instance tac
+  #-> (fn result => Class.prove_instantiation_instance (fn ctxt => tac ctxt result))
   #> LocalTheory.exit
   #> ProofContext.theory_of;
 
 fun gen_instance prep_arity prep_attr parse_term do_proof do_proof' raw_arities defs thy =
   let
-    val arities = map (prep_arity thy) raw_arities;
+    val (tyco, sorts, sort) = prep_arity thy raw_arities;
     fun export_defs ctxt = 
       let
         val ctxt_thy = ProofContext.init (ProofContext.theory_of ctxt);
@@ -53,32 +56,21 @@
       let
         val def' = (apsnd o apsnd) (Syntax.check_prop ctxt) def;
       in Specification.definition def' ctxt end;
-  in if not (null defs) orelse forall (fn (_, _, sort) =>
-      forall (Class.is_class thy) sort) arities
+  in if not (null defs) orelse forall (Class.is_class thy) sort
   then
     thy
-    |> TheoryTarget.instantiation arities
+    |> TheoryTarget.instantiation ([tyco], sorts, sort)
     |> `(fn ctxt => map (mk_def ctxt) defs)
     |-> (fn defs => fold_map Specification.definition defs)
     |-> (fn defs => `(fn ctxt => export_defs ctxt defs))
     ||> LocalTheory.reinit
-    (*||> ProofContext.theory_of
-    ||> TheoryTarget.instantiation arities*)
     |-> (fn defs => do_proof defs)
   else
     thy
-    |> do_proof' arities
+    |> do_proof' (tyco, sorts, sort)
   end;
 
-val instance = gen_instance Sign.cert_arity (K I) (K I)
-  (fn _ => Class.instantiation_instance Class.conclude_instantiation) (Class.instance_arity I);
 val instance_cmd = gen_instance Sign.read_arity Attrib.intern_src Syntax.parse_prop
   (fn _ => Class.instantiation_instance Class.conclude_instantiation) (Class.instance_arity I);
-fun prove_instance tac arities defs = gen_instance Sign.cert_arity (K I) (K I)
-  (fn defs => Class.prove_instantiation_instance (K tac)
-    #> Class.conclude_instantiation #> ProofContext.theory_of #> pair defs)
-   (pair [] o ProofContext.theory_of o Proof.global_terminal_proof
-      (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
-      oo Class.instance_arity I) arities defs;
 
 end;
--- a/src/Pure/Isar/isar_syn.ML	Wed Dec 05 14:15:48 2007 +0100
+++ b/src/Pure/Isar/isar_syn.ML	Wed Dec 05 14:15:51 2007 +0100
@@ -446,15 +446,15 @@
 
 val _ =
   OuterSyntax.command "instantiation" "instantiate and prove type arity" K.thy_decl
-   (P.and_list1 P.arity --| P.begin
+   (P.multi_arity --| P.begin
      >> (fn arities => Toplevel.print o
          Toplevel.begin_local_theory true (Instance.instantiation_cmd arities)));
 
 val _ =
   OuterSyntax.command "instance" "prove type arity or subclass relation" K.thy_goal
   ((P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname) >> Class.classrel_cmd ||
-    P.and_list1 P.arity -- Scan.repeat (SpecParse.opt_thm_name ":" -- P.prop)
-      >> (fn (arities, defs) => Instance.instance_cmd arities defs))
+    P.arity -- Scan.repeat (SpecParse.opt_thm_name ":" -- P.prop)
+      >> (fn (arity, defs) => Instance.instance_cmd arity defs))
     >> (Toplevel.print oo Toplevel.theory_to_proof)
   || Scan.succeed (Toplevel.print o Toplevel.local_theory_to_proof NONE (Class.instantiation_instance I)));
 
--- a/src/Pure/Isar/overloading.ML	Wed Dec 05 14:15:48 2007 +0100
+++ b/src/Pure/Isar/overloading.ML	Wed Dec 05 14:15:51 2007 +0100
@@ -8,6 +8,7 @@
 signature OVERLOADING =
 sig
   val init: ((string * typ) * (string * bool)) list -> theory -> local_theory
+  val prep_spec: local_theory -> term -> term
   val conclude: local_theory -> local_theory
   val declare: string * typ -> theory -> term * theory
   val confirm: string -> local_theory -> local_theory
@@ -45,14 +46,21 @@
 
 (* syntax *)
 
+fun subst_operation overloading = map_aterms (fn t as Const (c, ty) =>
+    (case AList.lookup (op =) overloading (c, ty)
+     of SOME (v, _) => Free (v, ty)
+      | NONE => t)
+  | t => t);
+
+fun prep_spec lthy =
+  let
+    val overloading = get_overloading lthy;
+  in subst_operation overloading end;
+
 fun term_check ts lthy =
   let
     val overloading = get_overloading lthy;
-    fun subst (t as Const (c, ty)) = (case AList.lookup (op =) overloading (c, ty)
-         of SOME (v, _) => Free (v, ty)
-          | NONE => t)
-      | subst t = t;
-    val ts' = (map o map_aterms) subst ts;
+    val ts' = map (subst_operation overloading) ts;
   in if eq_list (op aconv) (ts, ts') then NONE else SOME (ts', lthy) end;
 
 fun term_uncheck ts lthy =