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 |