src/Pure/Tools/class_package.ML
changeset 24200 adadbf9b42a4
parent 23953 f7eedf3d09a3
equal deleted inserted replaced
24199:8be734b5f59f 24200:adadbf9b42a4
   233   locale: string,
   233   locale: string,
   234   consts: (string * string) list
   234   consts: (string * string) list
   235     (*locale parameter ~> toplevel theory constant*),
   235     (*locale parameter ~> toplevel theory constant*),
   236   v: string option,
   236   v: string option,
   237   intro: thm
   237   intro: thm
   238 };
   238 } * thm list (*derived defs*);
   239 
   239 
   240 fun rep_classdata (ClassData c) = c;
   240 fun rep_classdata (ClassData c) = c;
   241 
   241 
   242 fun merge_pair f1 f2 ((x1, y1), (x2, y2)) = (f1 (x1, x2), f2 (y1, y2));
   242 fun merge_pair f1 f2 ((x1, y1), (x2, y2)) = (f1 (x1, x2), f2 (y1, y2));
   243 
   243 
   263 
   263 
   264 val ancestry = Graph.all_succs o fst o ClassData.get;
   264 val ancestry = Graph.all_succs o fst o ClassData.get;
   265 
   265 
   266 fun param_map thy =
   266 fun param_map thy =
   267   let
   267   let
   268     fun params thy class =
   268     fun params class =
   269       let
   269       let
   270         val const_typs = (#params o AxClass.get_definition thy) class;
   270         val const_typs = (#params o AxClass.get_definition thy) class;
   271         val const_names = (#consts o the_class_data thy) class;
   271         val const_names = (#consts o fst o the_class_data thy) class;
   272       in
   272       in
   273         (map o apsnd) (fn c => (c, (the o AList.lookup (op =) const_typs) c)) const_names
   273         (map o apsnd) (fn c => (c, (the o AList.lookup (op =) const_typs) c)) const_names
   274       end;
   274       end;
   275   in maps (params thy) o ancestry thy end;
   275   in maps params o ancestry thy end;
       
   276 
       
   277 fun these_defs thy = maps (these o Option.map snd o lookup_class_data thy) o ancestry thy;
   276 
   278 
   277 fun these_intros thy =
   279 fun these_intros thy =
   278   Graph.fold (fn (_, (data, _)) => insert Thm.eq_thm ((#intro o rep_classdata) data))
   280   Graph.fold (fn (_, (data, _)) => insert Thm.eq_thm ((#intro o fst o rep_classdata) data))
   279     ((fst o ClassData.get) thy) [];
   281     ((fst o ClassData.get) thy) [];
   280 
   282 
   281 fun print_classes thy =
   283 fun print_classes thy =
   282   let
   284   let
   283     val algebra = Sign.classes_of thy;
   285     val algebra = Sign.classes_of thy;
   295       ^ setmp show_sorts false (Sign.string_of_typ thy o Type.strip_sorts) ty);
   297       ^ setmp show_sorts false (Sign.string_of_typ thy o Type.strip_sorts) ty);
   296     fun mk_entry class = (Pretty.block o Pretty.fbreaks o map_filter I) [
   298     fun mk_entry class = (Pretty.block o Pretty.fbreaks o map_filter I) [
   297       (SOME o Pretty.str) ("class " ^ class ^ ":"),
   299       (SOME o Pretty.str) ("class " ^ class ^ ":"),
   298       (SOME o Pretty.block) [Pretty.str "supersort: ",
   300       (SOME o Pretty.block) [Pretty.str "supersort: ",
   299         (Sign.pretty_sort thy o Sign.certify_sort thy o Sign.super_classes thy) class],
   301         (Sign.pretty_sort thy o Sign.certify_sort thy o Sign.super_classes thy) class],
   300       Option.map (Pretty.str o prefix "locale: " o #locale) (lookup_class_data thy class),
   302       Option.map (Pretty.str o prefix "locale: " o #locale o fst) (lookup_class_data thy class),
   301       ((fn [] => NONE | ps => (SOME o Pretty.block o Pretty.fbreaks) (Pretty.str "parameters:" :: ps)) o map mk_param
   303       ((fn [] => NONE | ps => (SOME o Pretty.block o Pretty.fbreaks) (Pretty.str "parameters:" :: ps)) o map mk_param
   302         o these o Option.map #params o try (AxClass.get_definition thy)) class,
   304         o these o Option.map #params o try (AxClass.get_definition thy)) class,
   303       (SOME o Pretty.block o Pretty.breaks) [
   305       (SOME o Pretty.block o Pretty.breaks) [
   304         Pretty.str "instances:",
   306         Pretty.str "instances:",
   305         Pretty.list "" "" (map (mk_arity class) (the_arities class))
   307         Pretty.list "" "" (map (mk_arity class) (the_arities class))
   314 (* updaters *)
   316 (* updaters *)
   315 
   317 
   316 fun add_class_data ((class, superclasses), (locale, consts, v, intro)) =
   318 fun add_class_data ((class, superclasses), (locale, consts, v, intro)) =
   317   ClassData.map (fn (gr, tab) => (
   319   ClassData.map (fn (gr, tab) => (
   318     gr
   320     gr
   319     |> Graph.new_node (class, ClassData {
   321     |> Graph.new_node (class, ClassData ({ locale = locale, consts = consts,
   320       locale = locale,
   322          v = v, intro = intro }, []))
   321       consts = consts,
       
   322       v = v,
       
   323       intro = intro}
       
   324     )
       
   325     |> fold (curry Graph.add_edge class) superclasses,
   323     |> fold (curry Graph.add_edge class) superclasses,
   326     tab
   324     tab
   327     |> Symtab.update (locale, class)
   325     |> Symtab.update (locale, class)
   328   ));
   326   ));
   329 
   327 
       
   328 fun add_class_const_thm (class, thm) = (ClassData.map o apfst o Graph.map_node class)
       
   329   (fn ClassData (data, thms) => ClassData (data, thm :: thms));
   330 
   330 
   331 (* tactics and methods *)
   331 (* tactics and methods *)
   332 
   332 
   333 fun intro_classes_tac facts st =
   333 fun intro_classes_tac facts st =
   334   let
   334   let
   421     val raw_intro = case pred_intro'
   421     val raw_intro = case pred_intro'
   422      of SOME pred_intro => class_intro |> OF_LAST pred_intro
   422      of SOME pred_intro => class_intro |> OF_LAST pred_intro
   423       | NONE => class_intro;
   423       | NONE => class_intro;
   424     val sort = Sign.super_classes thy class;
   424     val sort = Sign.super_classes thy class;
   425     val typ = TVar ((AxClass.param_tyvarname, 0), sort);
   425     val typ = TVar ((AxClass.param_tyvarname, 0), sort);
       
   426     val defs = these_defs thy sups;
   426   in
   427   in
   427     raw_intro
   428     raw_intro
   428     |> Drule.instantiate' [SOME (Thm.ctyp_of thy typ)] []
   429     |> Drule.instantiate' [SOME (Thm.ctyp_of thy typ)] []
   429     |> strip_all_ofclass thy sort
   430     |> strip_all_ofclass thy sort
   430     |> Thm.strip_shyps
   431     |> Thm.strip_shyps
       
   432     |> MetaSimplifier.rewrite_rule defs
   431     |> Drule.unconstrainTs
   433     |> Drule.unconstrainTs
   432   end;
   434   end;
   433 
   435 
   434 fun interpretation_in_rule thy (class1, class2) =
   436 fun interpretation_in_rule thy (class1, class2) =
   435   let
   437   let
   436     val (params, consts) = split_list (param_map thy [class1]);
   438     val (params, consts) = split_list (param_map thy [class1]);
   437     (*FIXME also remember this at add_class*)
   439     (*FIXME also remember this at add_class*)
   438     fun mk_axioms class =
   440     fun mk_axioms class =
   439       let
   441       let
   440         val name_locale = (#locale o the_class_data thy) class;
   442         val name_locale = (#locale o fst o the_class_data thy) class;
   441         val inst = mk_inst class params consts;
   443         val inst = mk_inst class params consts;
   442       in
   444       in
   443         Locale.global_asms_of thy name_locale
   445         Locale.global_asms_of thy name_locale
   444         |> maps snd
   446         |> maps snd
   445         |> (map o map_aterms) (fn Free (s, _) => (the o Symtab.lookup inst) s | t => t)
   447         |> (map o map_aterms) (fn Free (s, _) => (the o Symtab.lookup inst) s | t => t)
   480       | Locale.Expr i => apsnd (cons i)) raw_elems ([], []);
   482       | Locale.Expr i => apsnd (cons i)) raw_elems ([], []);
   481     val supclasses = map (prep_class thy) raw_supclasses;
   483     val supclasses = map (prep_class thy) raw_supclasses;
   482     val sups = filter (is_some o lookup_class_data thy) supclasses
   484     val sups = filter (is_some o lookup_class_data thy) supclasses
   483       |> Sign.certify_sort thy;
   485       |> Sign.certify_sort thy;
   484     val supsort = Sign.certify_sort thy supclasses;
   486     val supsort = Sign.certify_sort thy supclasses;
   485     val suplocales = map (Locale.Locale o #locale o the_class_data thy) sups;
   487     val suplocales = map (Locale.Locale o #locale o fst o the_class_data thy) sups;
   486     val supexpr = Locale.Merge (suplocales @ includes);
   488     val supexpr = Locale.Merge (suplocales @ includes);
   487     val supparams = (map fst o Locale.parameters_of_expr thy)
   489     val supparams = (map fst o Locale.parameters_of_expr thy)
   488       (Locale.Merge suplocales);
   490       (Locale.Merge suplocales);
   489     val supconsts = AList.make (the o AList.lookup (op =) (param_map thy sups))
   491     val supconsts = AList.make (the o AList.lookup (op =) (param_map thy sups))
   490       (map fst supparams);
   492       (map fst supparams);
   512       let
   514       let
   513         val consts = supconsts @ (map (fst o fst) params ~~ cs);
   515         val consts = supconsts @ (map (fst o fst) params ~~ cs);
   514         fun subst (Free (c, ty)) =
   516         fun subst (Free (c, ty)) =
   515               Const ((fst o the o AList.lookup (op =) consts) c, ty)
   517               Const ((fst o the o AList.lookup (op =) consts) c, ty)
   516           | subst t = t;
   518           | subst t = t;
       
   519         val super_defs = these_defs thy sups;
   517         fun prep_asm ((name, atts), ts) =
   520         fun prep_asm ((name, atts), ts) =
   518           ((NameSpace.base name, map (Attrib.attribute thy) atts),
   521           ((NameSpace.base name, map (Attrib.attribute thy) atts),
   519             (map o map_aterms) subst ts);
   522             (map o map_aterms) ((*MetaSimplifier.rewrite_term thy super_defs [] o *)subst) ts);
   520       in
   523       in
   521         Locale.global_asms_of thy name_locale
   524         Locale.global_asms_of thy name_locale
   522         |> map prep_asm
   525         |> map prep_asm
   523       end;
   526       end;
   524     fun note_intro name_axclass class_intro =
   527     fun note_intro name_axclass class_intro =
   584     thy |> fold (curry singular_instance_subclass class) classes
   587     thy |> fold (curry singular_instance_subclass class) classes
   585   end;
   588   end;
   586 
   589 
   587 fun instance_sort' do_proof (class, sort) theory =
   590 fun instance_sort' do_proof (class, sort) theory =
   588   let
   591   let
   589     val loc_name = (#locale o the_class_data theory) class;
   592     val loc_name = (#locale o fst o the_class_data theory) class;
   590     val loc_expr =
   593     val loc_expr =
   591       (Locale.Merge o map (Locale.Locale o #locale o the_class_data theory)) sort;
   594       (Locale.Merge o map (Locale.Locale o #locale o fst o the_class_data theory)) sort;
   592   in
   595   in
   593     theory
   596     theory
   594     |> do_proof (instance_subsort (class, sort)) (loc_name, loc_expr)
   597     |> do_proof (instance_subsort (class, sort)) (loc_name, loc_expr)
   595   end;
   598   end;
   596 
   599 
   625 
   628 
   626 (** class target **)
   629 (** class target **)
   627 
   630 
   628 fun export_fixes thy class =
   631 fun export_fixes thy class =
   629   let
   632   let
   630     val v = (#v o the_class_data thy) class;
   633     val v = (#v o fst o the_class_data thy) class;
   631     val constrain_sort = curry (Sorts.inter_sort (Sign.classes_of thy)) [class];
   634     val constrain_sort = curry (Sorts.inter_sort (Sign.classes_of thy)) [class];
   632     val subst_typ = Term.map_type_tfree (fn var as (w, sort) =>
   635     val subst_typ = Term.map_type_tfree (fn var as (w, sort) =>
   633       if SOME w = v then TFree (w, constrain_sort sort) else TFree var);
   636       if SOME w = v then TFree (w, constrain_sort sort) else TFree var);
   634     val consts = param_map thy [class];
   637     val consts = param_map thy [class];
   635     fun subst_aterm (t as Free (v, ty)) = (case AList.lookup (op =) consts v
   638     fun subst_aterm (t as Free (v, ty)) = (case AList.lookup (op =) consts v
   654     val (syn', _) = fork_mixfix true NONE syn;
   657     val (syn', _) = fork_mixfix true NONE syn;
   655     fun interpret def =
   658     fun interpret def =
   656       let
   659       let
   657         val def' = symmetric def
   660         val def' = symmetric def
   658         val tac = (ALLGOALS o ProofContext.fact_tac) [def'];
   661         val tac = (ALLGOALS o ProofContext.fact_tac) [def'];
   659         val name_locale = (#locale o the_class_data thy) class;
   662         val name_locale = (#locale o fst o the_class_data thy) class;
   660         val def_eq = Thm.prop_of def';
   663         val def_eq = Thm.prop_of def';
   661         val (params, consts) = split_list (param_map thy [class]);
   664         val (params, consts) = split_list (param_map thy [class]);
   662       in
   665       in
   663         prove_interpretation tac ((false, prfx), []) (Locale.Locale name_locale)
   666         prove_interpretation tac ((false, prfx), []) (Locale.Locale name_locale)
   664           ((mk_instT class, mk_inst class params consts), [def_eq])
   667           ((mk_instT class, mk_inst class params consts), [def_eq])
       
   668         #> add_class_const_thm (class, def')
   665       end;
   669       end;
   666   in
   670   in
   667     thy
   671     thy
   668     |> Sign.hide_consts_i true [abbr']
   672     |> Sign.hide_consts_i true [abbr']
   669     |> Sign.add_path prfx
   673     |> Sign.add_path prfx