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 = |
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 |