src/Pure/Tools/class_package.ML
changeset 21924 fe474e69e603
parent 21894 1a0e32ccb8bb
child 21936 c7a7d3ab81d0
equal deleted inserted replaced
21923:663108ee4eef 21924:fe474e69e603
    10   val class: bstring -> class list -> Element.context Locale.element list -> theory ->
    10   val class: bstring -> class list -> Element.context Locale.element list -> theory ->
    11     string * Proof.context
    11     string * Proof.context
    12   val class_i: bstring -> class list -> Element.context_i Locale.element list -> theory ->
    12   val class_i: bstring -> class list -> Element.context_i Locale.element list -> theory ->
    13     string * Proof.context
    13     string * Proof.context
    14   val instance_arity: ((bstring * string list) * string) list
    14   val instance_arity: ((bstring * string list) * string) list
    15     -> bstring * Attrib.src list -> ((bstring * Attrib.src list) * string) list
    15     -> ((bstring * Attrib.src list) * string) list
    16     -> theory -> Proof.state
    16     -> theory -> Proof.state
    17   val instance_arity_i: ((bstring * sort list) * sort) list
    17   val instance_arity_i: ((bstring * sort list) * sort) list
    18     -> bstring * attribute list -> ((bstring * attribute list) * term) list
    18     -> ((bstring * attribute list) * term) list
    19     -> theory -> Proof.state
    19     -> theory -> Proof.state
    20   val prove_instance_arity: (thm list -> tactic) -> ((string * sort list) * sort) list
    20   val prove_instance_arity: tactic -> ((string * sort list) * sort) list
    21     -> bstring * attribute list -> ((bstring * attribute list) * term) list
    21     -> ((bstring * attribute list) * term) list
    22     -> theory -> theory
    22     -> theory -> theory
    23   val instance_sort: string * string -> theory -> Proof.state
    23   val instance_sort: string * string -> theory -> Proof.state
    24   val instance_sort_i: class * sort -> theory -> Proof.state
    24   val instance_sort_i: class * sort -> theory -> Proof.state
    25   val prove_instance_sort: tactic -> class * sort -> theory -> theory
    25   val prove_instance_sort: tactic -> class * sort -> theory -> theory
    26 
    26 
    47 
    47 
    48 
    48 
    49 (** theory data **)
    49 (** theory data **)
    50 
    50 
    51 datatype class_data = ClassData of {
    51 datatype class_data = ClassData of {
    52   name_locale: string,
    52   locale: string,
    53   name_axclass: string,
       
    54   var: string,
    53   var: string,
    55   consts: (string * (string * typ)) list
    54   consts: (string * (string * typ)) list
    56     (*locale parameter ~> toplevel theory constant*),
    55     (*locale parameter ~> toplevel theory constant*),
    57   propnames: string list,
    56   propnames: string list,
    58   defs: thm list
    57   defs: thm list
    59 } * thm list Symtab.table;
    58 };
    60 
    59 
    61 fun rep_classdata (ClassData c) = c;
    60 fun rep_classdata (ClassData c) = c;
    62 
    61 
    63 structure ClassData = TheoryDataFun (
    62 structure ClassData = TheoryDataFun (
    64   struct
    63   struct
    65     val name = "Pure/classes";
    64     val name = "Pure/classes";
    66     type T = class_data Symtab.table;
    65     type T = class_data Symtab.table;
    67     val empty = Symtab.empty;
    66     val empty = Symtab.empty;
    68     val copy = I;
    67     val copy = I;
    69     val extend = I;
    68     val extend = I;
    70     fun merge _ = Symtab.join (fn _ => fn (ClassData (classd, instd1), ClassData (_, instd2)) =>
    69     fun merge _ = Symtab.merge (K true);
    71       (ClassData (classd, Symtab.merge (K true) (instd1, instd2))));
    70     fun print _ _ = ();
    72     fun print thy data =
       
    73       let
       
    74         fun pretty_class (name, ClassData ({name_locale, name_axclass, var, consts, ...}, _)) =
       
    75           (Pretty.block o Pretty.fbreaks) [
       
    76             Pretty.str ("class " ^ name ^ ":"),
       
    77             Pretty.str ("locale: " ^ name_locale),
       
    78             Pretty.str ("axclass: " ^ name_axclass),
       
    79             Pretty.str ("class variable: " ^ var),
       
    80             (Pretty.block o Pretty.fbreaks) (
       
    81               Pretty.str "constants: "
       
    82               :: map (fn (_, (c, ty)) => Pretty.str (c ^ " :: " ^ Sign.string_of_typ thy ty)) consts
       
    83             )
       
    84           ]
       
    85       in
       
    86         (Pretty.writeln o Pretty.chunks o map pretty_class o Symtab.dest) data
       
    87       end;
       
    88   end
    71   end
    89 );
    72 );
    90 
    73 
    91 val _ = Context.add_setup ClassData.init;
    74 val _ = Context.add_setup ClassData.init;
    92 val print_classes = ClassData.print;
       
    93 
    75 
    94 
    76 
    95 (* queries *)
    77 (* queries *)
    96 
    78 
    97 val lookup_class_data = Option.map rep_classdata oo Symtab.lookup o ClassData.get;
    79 val lookup_class_data = Option.map rep_classdata oo Symtab.lookup o ClassData.get;
   111       anc
    93       anc
   112       |> insert (op =) class
    94       |> insert (op =) class
   113       |> fold ancestry ((maps proj_class o Sign.super_classes thy) class);
    95       |> fold ancestry ((maps proj_class o Sign.super_classes thy) class);
   114   in fold ancestry classes [] end;
    96   in fold ancestry classes [] end;
   115 
    97 
   116 val the_parm_map = #consts o fst oo the_class_data;
    98 val the_parm_map = #consts oo the_class_data;
   117 
    99 
   118 val the_propnames = #propnames o fst oo the_class_data;
   100 val the_propnames = #propnames oo the_class_data;
   119 
   101 
   120 fun subst_clsvar v ty_subst =
   102 fun subst_clsvar v ty_subst =
   121   map_type_tfree (fn u as (w, _) =>
   103   map_type_tfree (fn u as (w, _) =>
   122     if w = v then ty_subst else TFree u);
   104     if w = v then ty_subst else TFree u);
   123 
   105 
       
   106 fun print_classes thy =
       
   107   let
       
   108     val algebra = Sign.classes_of thy;
       
   109     val arities =
       
   110       Symtab.empty
       
   111       |> Symtab.fold (fn (tyco, arities) => fold (fn (class, _) =>
       
   112            Symtab.map_default (class, []) (insert (op =) tyco)) arities)
       
   113              ((#arities o Sorts.rep_algebra) algebra);
       
   114     val the_arities = these o Symtab.lookup arities;
       
   115     fun mk_arity class tyco =
       
   116       let
       
   117         val Ss = Sorts.mg_domain algebra tyco [class];
       
   118       in Sign.pretty_arity thy (tyco, Ss, [class]) end;
       
   119     fun mk_param (c, ty) = Pretty.str (Sign.extern_const thy c ^ " :: "
       
   120       ^ setmp show_sorts false (Sign.string_of_typ thy o Type.strip_sorts) ty);
       
   121     fun mk_entry class = (Pretty.block o Pretty.fbreaks o map_filter I) [
       
   122       (SOME o Pretty.str) ("class " ^ class ^ ":"),
       
   123       (SOME o Pretty.block) [Pretty.str "supersort: ",
       
   124         (Sign.pretty_sort thy o Sorts.certify_sort algebra o Sorts.super_classes algebra) class],
       
   125       Option.map (Pretty.str o prefix "locale: " o #locale) (lookup_class_data thy class),
       
   126       ((fn [] => NONE | ps => (SOME o Pretty.block o Pretty.fbreaks) (Pretty.str "parameters:" :: ps)) o map mk_param
       
   127         o these o Option.map #params o try (AxClass.get_definition thy)) class,
       
   128       (SOME o Pretty.block o Pretty.breaks) [
       
   129         Pretty.str "instances:",
       
   130         Pretty.list "" "" (map (mk_arity class) (the_arities class))
       
   131       ]
       
   132     ]
       
   133   in
       
   134     (Pretty.writeln o Pretty.chunks o separate (Pretty.str "") o map mk_entry o Sorts.classes) algebra
       
   135   end;
       
   136 
   124 
   137 
   125 (* updaters *)
   138 (* updaters *)
   126 
   139 
   127 fun add_class_data (class, (name_locale, name_axclass, var, consts, propnames)) =
   140 fun add_class_data (class, (locale, var, consts, propnames)) =
   128   ClassData.map (
   141   ClassData.map (
   129     Symtab.update_new (class, ClassData ({
   142     Symtab.update_new (class, ClassData {
   130       name_locale = name_locale,
   143       locale = locale,
   131       name_axclass = name_axclass,
       
   132       var = var,
   144       var = var,
   133       consts = consts,
   145       consts = consts,
   134       propnames = propnames,
   146       propnames = propnames,
   135       defs = []}, Symtab.empty))
   147       defs = []})
   136   );
   148   );
   137 
   149 
   138 fun add_def (class, thm) =
   150 fun add_def (class, thm) =
   139   ClassData.map (
   151   (ClassData.map o Symtab.map_entry class)
   140     Symtab.map_entry class (fn ClassData ({ name_locale, name_axclass,
   152     (fn ClassData { locale,
   141       var, consts, propnames, defs }, instd) => ClassData ({ name_locale = name_locale,
   153       var, consts, propnames, defs } => ClassData { locale = locale,
   142       name_axclass = name_axclass, var = var,
   154       var = var,
   143       consts = consts, propnames = propnames, defs = thm :: defs }, instd))
   155       consts = consts, propnames = propnames, defs = thm :: defs });
   144   );
       
   145 
       
   146 
       
   147 fun add_inst_def ((class, tyco), thm) =
       
   148   ClassData.map (
       
   149     Symtab.map_entry class (fn ClassData (classd, instd) =>
       
   150       ClassData (classd, Symtab.insert_list eq_thm (tyco, thm) instd))
       
   151   );
       
   152 
   156 
   153 
   157 
   154 (* experimental class target *)
   158 (* experimental class target *)
   155 
   159 
   156 fun export_typ thy loc =
   160 fun export_typ thy loc =
   164   end;
   168   end;
   165 
   169 
   166 fun export_def thy loc =
   170 fun export_def thy loc =
   167   let
   171   let
   168     val class = loc (*FIXME*);
   172     val class = loc (*FIXME*);
   169     val data = (fst o the_class_data thy) class;
   173     val data = the_class_data thy class;
   170     val consts = #consts data;
   174     val consts = #consts data;
   171     val v = #var data;
   175     val v = #var data;
   172     val subst_typ = Term.map_type_tfree (fn var as (w, sort) =>
   176     val subst_typ = Term.map_type_tfree (fn var as (w, sort) =>
   173       if w = v then TFree (w, Sorts.inter_sort (Sign.classes_of thy)
   177       if w = v then TFree (w, Sorts.inter_sort (Sign.classes_of thy)
   174         (sort, [class])) else TFree var)
   178         (sort, [class])) else TFree var)
   181   end;
   185   end;
   182 
   186 
   183 fun export_thm thy loc =
   187 fun export_thm thy loc =
   184   let
   188   let
   185     val class = loc (*FIXME*);
   189     val class = loc (*FIXME*);
   186     val thms = (#defs o fst o the_class_data thy) class;
   190     val thms = (#defs o the_class_data thy) class;
   187   in
   191   in
   188     MetaSimplifier.rewrite_rule thms
   192     MetaSimplifier.rewrite_rule thms
   189   end;
   193   end;
   190 
   194 
   191 
   195 
   310                                    | Locale.Expr e => apsnd (cons e))
   314                                    | Locale.Expr e => apsnd (cons e))
   311       raw_elems ([], []);
   315       raw_elems ([], []);
   312     val supclasses = map (prep_class thy) raw_supclasses;
   316     val supclasses = map (prep_class thy) raw_supclasses;
   313     val supsort =
   317     val supsort =
   314       supclasses
   318       supclasses
   315       |> map (#name_axclass o fst o the_class_data thy)
       
   316       |> Sign.certify_sort thy
   319       |> Sign.certify_sort thy
   317       |> (fn [] => Sign.defaultS thy | S => S);    (* FIXME Why syntax defaultS? *)
   320       |> (fn [] => Sign.defaultS thy | S => S);    (* FIXME Why syntax defaultS? *)
   318     val expr_supclasses = Locale.Merge
   321     val expr_supclasses = Locale.Merge
   319       (map (Locale.Locale o #name_locale o fst o the_class_data thy) supclasses);
   322       (map (Locale.Locale o #locale o the_class_data thy) supclasses);
   320     val expr = Locale.Merge (map (Locale.Locale o #name_locale o fst o the_class_data thy) supclasses
   323     val expr = Locale.Merge (map (Locale.Locale o #locale o the_class_data thy) supclasses
   321       @ exprs);
   324       @ exprs);
   322     val mapp_sup = AList.make
   325     val mapp_sup = AList.make
   323       (the o AList.lookup (op =) ((flat o map (the_parm_map thy) o the_ancestry thy) supclasses))
   326       (the o AList.lookup (op =) ((flat o map (the_parm_map thy) o the_ancestry thy) supclasses))
   324       ((map (fst o fst) o Locale.parameters_of_expr thy) expr_supclasses);
   327       ((map (fst o fst) o Locale.parameters_of_expr thy) expr_supclasses);
   325     fun extract_tyvar_consts thy name_locale =
   328     fun extract_tyvar_consts thy name_locale =
   373           `(fn thy => extract_assumes thy name_locale (mapp_sup @ mapp_this))
   376           `(fn thy => extract_assumes thy name_locale (mapp_sup @ mapp_this))
   374     #-> (fn loc_axioms =>
   377     #-> (fn loc_axioms =>
   375           add_axclass_i (bname, supsort) (map (fst o snd) mapp_this) loc_axioms
   378           add_axclass_i (bname, supsort) (map (fst o snd) mapp_this) loc_axioms
   376     #-> (fn (name_axclass, (_, ax_axioms)) =>
   379     #-> (fn (name_axclass, (_, ax_axioms)) =>
   377           fold (add_global_constraint v name_axclass) mapp_this
   380           fold (add_global_constraint v name_axclass) mapp_this
   378     #> add_class_data (name_locale, (name_locale, name_axclass, v, mapp_this,
   381     #> add_class_data (name_locale, (name_locale, v, mapp_this,
   379           map (fst o fst) loc_axioms))
   382           map (fst o fst) loc_axioms))
   380     #> prove_interpretation_i (Logic.const_of_class bname, [])
   383     #> prove_interpretation_i (Logic.const_of_class bname, [])
   381           (Locale.Locale name_locale) (map (SOME o mk_const thy name_axclass v) (map snd (mapp_sup @ mapp_this)))
   384           (Locale.Locale name_locale) (map (SOME o mk_const thy name_axclass v) (map snd (mapp_sup @ mapp_this)))
   382           ((ALLGOALS o ProofContext.fact_tac) ax_axioms)
   385           ((ALLGOALS o ProofContext.fact_tac) ax_axioms)
   383     ))))) #> pair name_locale)
   386     ))))) #> pair name_locale)
   404   in (c, (insts, ((name, t), atts))) end;
   407   in (c, (insts, ((name, t), atts))) end;
   405 
   408 
   406 fun read_def thy = gen_read_def thy Attrib.attribute read_axm;
   409 fun read_def thy = gen_read_def thy Attrib.attribute read_axm;
   407 fun read_def_i thy = gen_read_def thy (K I) (K I);
   410 fun read_def_i thy = gen_read_def thy (K I) (K I);
   408 
   411 
   409 fun gen_instance_arity prep_arity prep_att read_def do_proof raw_arities (raw_name, raw_atts) raw_defs theory =
   412 fun gen_instance_arity prep_arity prep_att read_def do_proof raw_arities raw_defs theory =
   410   let
   413   let
   411     fun prep_arity' ((tyco, asorts), sort) = prep_arity theory (tyco, asorts, sort);
   414     fun prep_arity' ((tyco, asorts), sort) = prep_arity theory (tyco, asorts, sort);
   412     val arities = map prep_arity' raw_arities;
   415     val arities = map prep_arity' raw_arities;
   413     val arities_pair = map (fn (tyco, asorts, sort) => ((tyco, asorts), sort)) arities;
   416     val arities_pair = map (fn (tyco, asorts, sort) => ((tyco, asorts), sort)) arities;
   414     val _ = if null arities then error "at least one arity must be given" else ();
   417     val _ = if null arities then error "at least one arity must be given" else ();
   415     val _ = case (duplicates (op =) o map #1) arities
   418     val _ = case (duplicates (op =) o map #1) arities
   416      of [] => ()
   419      of [] => ()
   417       | dupl_tycos => error ("type constructors occur more than once in arities: "
   420       | dupl_tycos => error ("type constructors occur more than once in arities: "
   418         ^ (commas o map quote) dupl_tycos);
   421         ^ (commas o map quote) dupl_tycos);
   419     val (bind_always, name) = case raw_name
       
   420      of "" => (false, Thm.def_name ((space_implode "_" o map NameSpace.base)
       
   421                 (maps (fn (tyco, _, sort) => sort @ [tyco])
       
   422                 (sort (fn ((tyco1, _, _), (tyco2, _, _)) => string_ord (tyco1, tyco2)) arities))))
       
   423       | _ => (true, raw_name);
       
   424     val atts = map (prep_att theory) raw_atts;
       
   425     fun get_consts_class tyco ty class =
   422     fun get_consts_class tyco ty class =
   426       let
   423       let
   427         val (_, cs) = AxClass.params_of_class theory class;
   424         val (_, cs) = AxClass.params_of_class theory class;
   428         val subst_ty = map_type_tfree (K ty);
   425         val subst_ty = map_type_tfree (K ty);
   429       in
   426       in
   467       end;
   464       end;
   468     fun add_defs defs thy =
   465     fun add_defs defs thy =
   469       thy
   466       thy
   470       |> PureThy.add_defs_i true (map snd defs)
   467       |> PureThy.add_defs_i true (map snd defs)
   471       |-> (fn thms => pair (map fst defs ~~ thms));
   468       |-> (fn thms => pair (map fst defs ~~ thms));
   472     fun note_all thy =
       
   473       (*FIXME: should avoid binding duplicated names*)
       
   474       let
       
   475         val bind = bind_always orelse not (can (PureThy.get_thms thy) (Name name));
       
   476         val thms = maps (fn (tyco, _, sort) => maps (fn class =>
       
   477           Symtab.lookup_list
       
   478             ((the_default Symtab.empty o Option.map snd o try (the_class_data thy)) class) tyco)
       
   479             (the_ancestry thy sort)) arities;
       
   480       in if bind then
       
   481         thy
       
   482         |> PureThy.note_thmss_i (*qualified*) Thm.internalK [((name, atts), [(thms, [])])]
       
   483         |> snd
       
   484       else
       
   485         thy
       
   486       end;
       
   487     fun after_qed cs thy =
   469     fun after_qed cs thy =
   488       thy
   470       thy
   489       |> fold Sign.add_const_constraint_i (map (apsnd SOME) cs);
   471       |> fold Sign.add_const_constraint_i (map (apsnd SOME) cs);
   490   in
   472   in
   491     theory
   473     theory
   492     |> fold_map get_remove_contraint (map fst cs |> distinct (op =))
   474     |> fold_map get_remove_contraint (map fst cs |> distinct (op =))
   493     ||>> add_defs defs
   475     ||>> add_defs defs
   494     |-> (fn (cs, def_thms) =>
   476     |-> (fn (cs, def_thms) => do_proof (after_qed cs) arities)
   495        fold add_inst_def def_thms
       
   496     #> note_all
       
   497     #> do_proof (map snd def_thms) (after_qed cs) arities)
       
   498   end;
   477   end;
   499 
   478 
   500 fun instance_arity' do_proof = gen_instance_arity Sign.read_arity Attrib.attribute
   479 fun instance_arity' do_proof = gen_instance_arity Sign.read_arity Attrib.attribute
   501   read_def do_proof;
   480   read_def do_proof;
   502 fun instance_arity_i' do_proof = gen_instance_arity Sign.cert_arity (K I)
   481 fun instance_arity_i' do_proof = gen_instance_arity Sign.cert_arity (K I)
   503   read_def_i do_proof;
   482   read_def_i do_proof;
   504 fun tactic_proof tac def_thms after_qed arities =
   483 fun tactic_proof tac after_qed arities =
   505   fold (fn arity => AxClass.prove_arity arity (tac def_thms)) arities
   484   fold (fn arity => AxClass.prove_arity arity tac) arities
   506   #> after_qed;
   485   #> after_qed;
   507 
   486 
   508 in
   487 in
   509 
   488 
   510 val instance_arity = instance_arity' (K axclass_instance_arity_i);
   489 val instance_arity = instance_arity' axclass_instance_arity_i;
   511 val instance_arity_i = instance_arity_i' (K axclass_instance_arity_i);
   490 val instance_arity_i = instance_arity_i' axclass_instance_arity_i;
   512 val prove_instance_arity = instance_arity_i' o tactic_proof;
   491 val prove_instance_arity = instance_arity_i' o tactic_proof;
   513 
   492 
   514 end; (*local*)
   493 end; (*local*)
   515 
   494 
   516 local
   495 local
   524 (*FIXME very ad-hoc, needs proper locale interface*)
   503 (*FIXME very ad-hoc, needs proper locale interface*)
   525 fun gen_instance_sort prep_class prep_sort do_proof (raw_class, raw_sort) theory =
   504 fun gen_instance_sort prep_class prep_sort do_proof (raw_class, raw_sort) theory =
   526   let
   505   let
   527     val class = prep_class theory raw_class;
   506     val class = prep_class theory raw_class;
   528     val sort = prep_sort theory raw_sort;
   507     val sort = prep_sort theory raw_sort;
   529     val loc_name = (#name_locale o fst o the_class_data theory) class;
   508     val loc_name = (#locale o the_class_data theory) class;
   530     val loc_expr =
   509     val loc_expr =
   531       (Locale.Merge o map (Locale.Locale o #name_locale o fst o the_class_data theory)) sort;
   510       (Locale.Merge o map (Locale.Locale o #locale o the_class_data theory)) sort;
   532     val const_names = (map (NameSpace.base o fst o snd)
   511     val const_names = (map (NameSpace.base o fst o snd)
   533       o maps (#consts o fst o the_class_data theory)
   512       o maps (#consts o the_class_data theory)
   534       o the_ancestry theory) [class];
   513       o the_ancestry theory) [class];
   535     fun get_thms thy =
   514     fun get_thms thy =
   536       the_ancestry thy sort
   515       the_ancestry thy sort
   537       |> AList.make (the_propnames thy)
   516       |> AList.make (the_propnames thy)
   538       |> map (apsnd (map (NameSpace.append (Logic.const_of_class loc_name))))
   517       |> map (apsnd (map (NameSpace.append (Logic.const_of_class loc_name))))
   602           (class bname supclasses elems #-> TheoryTarget.begin true)));
   581           (class bname supclasses elems #-> TheoryTarget.begin true)));
   603 
   582 
   604 val instanceP =
   583 val instanceP =
   605   OuterSyntax.command instanceK "prove type arity or subclass relation" K.thy_goal ((
   584   OuterSyntax.command instanceK "prove type arity or subclass relation" K.thy_goal ((
   606       P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname) >> wrap_add_instance_sort
   585       P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname) >> wrap_add_instance_sort
   607       || P.opt_thm_name ":" -- (P.and_list1 parse_arity -- Scan.repeat (P.opt_thm_name ":" -- P.prop))
   586       || P.and_list1 parse_arity -- Scan.repeat (P.opt_thm_name ":" -- P.prop)
   608            >> (fn (("", []), ([((tyco, asorts), sort)], [])) => axclass_instance_arity I [(tyco, asorts, sort)]
   587            >> (fn ([((tyco, asorts), sort)], []) => axclass_instance_arity I [(tyco, asorts, sort)]
   609                 | (natts, (arities, defs)) => instance_arity arities natts defs)
   588                 | (arities, defs) => instance_arity arities defs)
   610     ) >> (Toplevel.print oo Toplevel.theory_to_proof));
   589     ) >> (Toplevel.print oo Toplevel.theory_to_proof));
   611 
   590 
   612 val print_classesP =
   591 val print_classesP =
   613   OuterSyntax.improper_command print_classesK "print classes of this theory" K.diag
   592   OuterSyntax.improper_command print_classesK "print classes of this theory" K.diag
   614     (Scan.succeed (Toplevel.no_timing o Toplevel.unknown_theory
   593     (Scan.succeed (Toplevel.no_timing o Toplevel.unknown_theory