56 ((string * typ) * mixfix) list |
56 ((string * typ) * mixfix) list |
57 val local_asms_of: theory -> string -> |
57 val local_asms_of: theory -> string -> |
58 ((string * Attrib.src list) * term list) list |
58 ((string * Attrib.src list) * term list) list |
59 val global_asms_of: theory -> string -> |
59 val global_asms_of: theory -> string -> |
60 ((string * Attrib.src list) * term list) list |
60 ((string * Attrib.src list) * term list) list |
|
61 |
|
62 (* Theorems *) |
61 val intros: theory -> string -> thm list * thm list |
63 val intros: theory -> string -> thm list * thm list |
62 val dests: theory -> string -> thm list |
64 val dests: theory -> string -> thm list |
|
65 (* Not part of the official interface. DO NOT USE *) |
63 val facts_of: theory -> string |
66 val facts_of: theory -> string |
64 -> ((string * Attrib.src list) * (thm list * Attrib.src list) list) list list |
67 -> ((string * Attrib.src list) * (thm list * Attrib.src list) list) list list |
65 |
68 |
66 (* Processing of locale statements *) |
69 (* Processing of locale statements *) |
67 val read_context_statement: xstring option -> Element.context element list -> |
70 val read_context_statement: xstring option -> Element.context element list -> |
153 type locale = |
156 type locale = |
154 {axiom: Element.witness list, |
157 {axiom: Element.witness list, |
155 (* For locales that define predicates this is [A [A]], where A is the locale |
158 (* For locales that define predicates this is [A [A]], where A is the locale |
156 specification. Otherwise []. |
159 specification. Otherwise []. |
157 Only required to generate the right witnesses for locales with predicates. *) |
160 Only required to generate the right witnesses for locales with predicates. *) |
158 imports: expr, (*dynamic imports*) |
|
159 elems: (Element.context_i * stamp) list, |
161 elems: (Element.context_i * stamp) list, |
160 (* Static content, neither Fixes nor Constrains elements *) |
162 (* Static content, neither Fixes nor Constrains elements *) |
161 params: ((string * typ) * mixfix) list, (*all params*) |
163 params: ((string * typ) * mixfix) list, (*all params*) |
162 lparams: string list, (*local params*) |
|
163 decls: decl list * decl list, (*type/term_syntax declarations*) |
164 decls: decl list * decl list, (*type/term_syntax declarations*) |
164 regs: ((string * string list) * Element.witness list) list, |
165 regs: ((string * string list) * Element.witness list) list, |
165 (* Registrations: indentifiers and witnesses of locales interpreted in the locale. *) |
166 (* Registrations: indentifiers and witnesses of locales interpreted in the locale. *) |
166 intros: thm list * thm list, |
167 intros: thm list * thm list, |
167 (* Introduction rules: of delta predicate and locale predicate. *) |
168 (* Introduction rules: of delta predicate and locale predicate. *) |
350 val empty = (NameSpace.empty, Symtab.empty); |
351 val empty = (NameSpace.empty, Symtab.empty); |
351 val copy = I; |
352 val copy = I; |
352 val extend = I; |
353 val extend = I; |
353 |
354 |
354 fun join_locales _ |
355 fun join_locales _ |
355 ({axiom, imports, elems, params, lparams, decls = (decls1, decls2), regs, intros, dests}: locale, |
356 ({axiom, elems, params, decls = (decls1, decls2), regs, intros, dests}: locale, |
356 {elems = elems', decls = (decls1', decls2'), regs = regs', ...}: locale) = |
357 {elems = elems', decls = (decls1', decls2'), regs = regs', ...}: locale) = |
357 {axiom = axiom, |
358 {axiom = axiom, |
358 imports = imports, |
|
359 elems = merge_lists (eq_snd (op =)) elems elems', |
359 elems = merge_lists (eq_snd (op =)) elems elems', |
360 params = params, |
360 params = params, |
361 lparams = lparams, |
|
362 decls = |
361 decls = |
363 (Library.merge (eq_snd (op =)) (decls1, decls1'), |
362 (Library.merge (eq_snd (op =)) (decls1, decls1'), |
364 Library.merge (eq_snd (op =)) (decls2, decls2')), |
363 Library.merge (eq_snd (op =)) (decls2, decls2')), |
365 regs = merge_alists (op =) regs regs', |
364 regs = merge_alists (op =) regs regs', |
366 intros = intros, |
365 intros = intros, |
397 thy |> LocalesData.map (fn (space, locs) => |
396 thy |> LocalesData.map (fn (space, locs) => |
398 (Sign.declare_name thy name space, Symtab.update (name, loc) locs)); |
397 (Sign.declare_name thy name space, Symtab.update (name, loc) locs)); |
399 |
398 |
400 fun change_locale name f thy = |
399 fun change_locale name f thy = |
401 let |
400 let |
402 val {axiom, imports, elems, params, lparams, decls, regs, intros, dests} = |
401 val {axiom, elems, params, decls, regs, intros, dests} = |
403 the_locale thy name; |
402 the_locale thy name; |
404 val (axiom', imports', elems', params', lparams', decls', regs', intros', dests') = |
403 val (axiom', elems', params', decls', regs', intros', dests') = |
405 f (axiom, imports, elems, params, lparams, decls, regs, intros, dests); |
404 f (axiom, elems, params, decls, regs, intros, dests); |
406 in |
405 in |
407 thy |
406 thy |
408 |> (LocalesData.map o apsnd) (Symtab.update (name, {axiom = axiom', |
407 |> (LocalesData.map o apsnd) (Symtab.update (name, {axiom = axiom', |
409 imports = imports', elems = elems', params = params', lparams = lparams', |
408 elems = elems', params = params', |
410 decls = decls', regs = regs', intros = intros', dests = dests'})) |
409 decls = decls', regs = regs', intros = intros', dests = dests'})) |
411 end; |
410 end; |
412 |
411 |
413 fun print_locales thy = |
412 fun print_locales thy = |
414 let val (space, locs) = LocalesData.get thy in |
413 let val (space, locs) = LocalesData.get thy in |
469 fun put_local_registration id attn morphs = |
468 fun put_local_registration id attn morphs = |
470 Context.proof_map (put_registration id attn morphs); |
469 Context.proof_map (put_registration id attn morphs); |
471 |
470 |
472 |
471 |
473 fun put_registration_in_locale name id = |
472 fun put_registration_in_locale name id = |
474 change_locale name (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) => |
473 change_locale name (fn (axiom, elems, params, decls, regs, intros, dests) => |
475 (axiom, imports, elems, params, lparams, decls, regs @ [(id, [])], intros, dests)); |
474 (axiom, elems, params, decls, regs @ [(id, [])], intros, dests)); |
476 |
475 |
477 |
476 |
478 (* add witness theorem to registration, ignored if registration not present *) |
477 (* add witness theorem to registration, ignored if registration not present *) |
479 |
478 |
480 fun add_witness (name, ps) thm = |
479 fun add_witness (name, ps) thm = |
483 fun add_global_witness id thm = Context.theory_map (add_witness id thm); |
482 fun add_global_witness id thm = Context.theory_map (add_witness id thm); |
484 fun add_local_witness id thm = Context.proof_map (add_witness id thm); |
483 fun add_local_witness id thm = Context.proof_map (add_witness id thm); |
485 |
484 |
486 |
485 |
487 fun add_witness_in_locale name id thm = |
486 fun add_witness_in_locale name id thm = |
488 change_locale name (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) => |
487 change_locale name (fn (axiom, elems, params, decls, regs, intros, dests) => |
489 let |
488 let |
490 fun add (id', thms) = |
489 fun add (id', thms) = |
491 if id = id' then (id', thm :: thms) else (id', thms); |
490 if id = id' then (id', thm :: thms) else (id', thms); |
492 in (axiom, imports, elems, params, lparams, decls, map add regs, intros, dests) end); |
491 in (axiom, elems, params, decls, map add regs, intros, dests) end); |
493 |
492 |
494 |
493 |
495 (* add equation to registration, ignored if registration not present *) |
494 (* add equation to registration, ignored if registration not present *) |
496 |
495 |
497 fun add_equation (name, ps) thm = |
496 fun add_equation (name, ps) thm = |
731 handle Symtab.DUP x => err_in_expr ctxt |
730 handle Symtab.DUP x => err_in_expr ctxt |
732 ("Conflicting syntax for parameter: " ^ quote x) expr; |
731 ("Conflicting syntax for parameter: " ^ quote x) expr; |
733 |
732 |
734 fun params_of (expr as Locale name) = |
733 fun params_of (expr as Locale name) = |
735 let |
734 let |
736 val {imports, params, ...} = the_locale thy name; |
735 val {params, ...} = the_locale thy name; |
737 val parms = map (fst o fst) params; |
736 in (map (fst o fst) params, params |> map fst |> Symtab.make, |
738 val (parms', types', syn') = params_of imports; |
737 params |> map (apfst fst) |> Symtab.make) end |
739 val all_parms = merge_lists (op =) parms' parms; |
|
740 val all_types = merge_tenvs [] types' (params |> map fst |> Symtab.make); |
|
741 val all_syn = merge_syn expr syn' (params |> map (apfst fst) |> Symtab.make); |
|
742 in (all_parms, all_types, all_syn) end |
|
743 | params_of (expr as Rename (e, xs)) = |
738 | params_of (expr as Rename (e, xs)) = |
744 let |
739 let |
745 val (parms', types', syn') = params_of e; |
740 val (parms', types', syn') = params_of e; |
746 val ren = renaming xs parms'; |
741 val ren = renaming xs parms'; |
747 (* renaming may reduce number of parameters *) |
742 (* renaming may reduce number of parameters *) |
812 if top |
807 if top |
813 then (map (Element.rename ren) parms, |
808 then (map (Element.rename ren) parms, |
814 map_mode (map (Element.morph_witness (Element.rename_morphism ren))) mode) |
809 map_mode (map (Element.morph_witness (Element.rename_morphism ren))) mode) |
815 else (parms, mode)); |
810 else (parms, mode)); |
816 |
811 |
817 (* add (name, ps) and its registrations, recursively; adjust hyps of witnesses *) |
812 (* add (name, pTs) and its registrations, recursively; adjust hyps of witnesses *) |
818 |
813 |
819 fun add_with_regs ((name, pTs), mode) (wits, ids, visited) = |
814 fun add_with_regs ((name, pTs), mode) (wits, ids, visited) = |
820 if member (fn (a, (b, _)) => a = b) visited (name, map #1 pTs) |
815 if member (fn (a, (b, _)) => a = b) visited (name, map #1 pTs) |
821 then (wits, ids, visited) |
816 then (wits, ids, visited) |
822 else |
817 else |
874 where name is a locale name, ps a list of parameter names and axs |
869 where name is a locale name, ps a list of parameter names and axs |
875 a list of axioms relating to the identifier, axs is empty unless |
870 a list of axioms relating to the identifier, axs is empty unless |
876 identify at top level (top = true); |
871 identify at top level (top = true); |
877 parms is accumulated list of parameters *) |
872 parms is accumulated list of parameters *) |
878 let |
873 let |
879 val {axiom, imports, params, ...} = the_locale thy name; |
874 val {axiom, params, ...} = the_locale thy name; |
880 val ps = map (#1 o #1) params; |
875 val ps = map (#1 o #1) params; |
881 val (ids', parms') = identify false imports; |
876 val (_, ids'', _) = add_with_regs ((name, map #1 params), Assumed []) ([], [], []); |
882 (* acyclic import dependencies *) |
|
883 |
|
884 val (_, ids'', _) = add_with_regs ((name, map #1 params), Assumed []) ([], ids', ids'); |
|
885 val ids_ax = if top then fst (fold_map (axiomify ps) ids'' axiom) else ids''; |
877 val ids_ax = if top then fst (fold_map (axiomify ps) ids'' axiom) else ids''; |
886 in (ids_ax, merge_lists (op =) parms' ps) end |
878 in (ids_ax, ps) end |
887 | identify top (Rename (e, xs)) = |
879 | identify top (Rename (e, xs)) = |
888 let |
880 let |
889 val (ids', parms') = identify top e; |
881 val (ids', parms') = identify top e; |
890 val ren = renaming xs parms' |
882 val ren = renaming xs parms' |
891 handle ERROR msg => err_in_locale' ctxt msg ids'; |
883 handle ERROR msg => err_in_locale' ctxt msg ids'; |
1690 val (([(_, [Notes args'])], _), ctxt') = |
1682 val (([(_, [Notes args'])], _), ctxt') = |
1691 activate_facts true cert_facts |
1683 activate_facts true cert_facts |
1692 [((("", []), Assumed []), [Ext (Notes (kind, args))])] ctxt; |
1684 [((("", []), Assumed []), [Ext (Notes (kind, args))])] ctxt; |
1693 val ctxt'' = ctxt' |> ProofContext.theory |
1685 val ctxt'' = ctxt' |> ProofContext.theory |
1694 (change_locale loc |
1686 (change_locale loc |
1695 (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) => |
1687 (fn (axiom, elems, params, decls, regs, intros, dests) => |
1696 (axiom, imports, elems @ [(Notes args', stamp ())], |
1688 (axiom, elems @ [(Notes args', stamp ())], |
1697 params, lparams, decls, regs, intros, dests)) |
1689 params, decls, regs, intros, dests)) |
1698 #> note_thmss_registrations loc args'); |
1690 #> note_thmss_registrations loc args'); |
1699 in ctxt'' end; |
1691 in ctxt'' end; |
1700 |
1692 |
1701 |
1693 |
1702 (* declarations *) |
1694 (* declarations *) |
1705 |
1697 |
1706 fun decl_attrib decl phi = Thm.declaration_attribute (K (decl phi)); |
1698 fun decl_attrib decl phi = Thm.declaration_attribute (K (decl phi)); |
1707 |
1699 |
1708 fun add_decls add loc decl = |
1700 fun add_decls add loc decl = |
1709 ProofContext.theory (change_locale loc |
1701 ProofContext.theory (change_locale loc |
1710 (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) => |
1702 (fn (axiom, elems, params, decls, regs, intros, dests) => |
1711 (axiom, imports, elems, params, lparams, add (decl, stamp ()) decls, regs, intros, dests))) #> |
1703 (axiom, elems, params, add (decl, stamp ()) decls, regs, intros, dests))) #> |
1712 add_thmss loc Thm.internalK |
1704 add_thmss loc Thm.internalK |
1713 [(("", [Attrib.internal (decl_attrib decl)]), [([Drule.dummy_thm], [])])]; |
1705 [(("", [Attrib.internal (decl_attrib decl)]), [([Drule.dummy_thm], [])])]; |
1714 |
1706 |
1715 in |
1707 in |
1716 |
1708 |
1920 val (((import_ctxt, import_elemss), (body_ctxt, body_elemss, syn)), |
1912 val (((import_ctxt, import_elemss), (body_ctxt, body_elemss, syn)), |
1921 text as (parms, ((_, exts'), _), defs)) = |
1913 text as (parms, ((_, exts'), _), defs)) = |
1922 prep_ctxt raw_imports raw_body thy_ctxt; |
1914 prep_ctxt raw_imports raw_body thy_ctxt; |
1923 val elemss = import_elemss @ body_elemss |> |
1915 val elemss = import_elemss @ body_elemss |> |
1924 map_filter (fn ((id, Assumed axs), elems) => SOME (id, elems) | _ => NONE); |
1916 map_filter (fn ((id, Assumed axs), elems) => SOME (id, elems) | _ => NONE); |
1925 val imports = prep_expr thy raw_imports; |
|
1926 |
1917 |
1927 val extraTs = List.foldr Term.add_term_tfrees [] exts' \\ |
1918 val extraTs = List.foldr Term.add_term_tfrees [] exts' \\ |
1928 List.foldr Term.add_typ_tfrees [] (map snd parms); |
1919 List.foldr Term.add_typ_tfrees [] (map snd parms); |
1929 val _ = if null extraTs then () |
1920 val _ = if null extraTs then () |
1930 else warning ("Additional type variable(s) in locale specification " ^ quote bname); |
1921 else warning ("Additional type variable(s) in locale specification " ^ quote bname); |
1962 |> Sign.add_path bname |
1953 |> Sign.add_path bname |
1963 |> Sign.no_base_names |
1954 |> Sign.no_base_names |
1964 |> PureThy.note_thmss Thm.assumptionK facts' |> snd |
1955 |> PureThy.note_thmss Thm.assumptionK facts' |> snd |
1965 |> Sign.restore_naming thy' |
1956 |> Sign.restore_naming thy' |
1966 |> register_locale name {axiom = axs', |
1957 |> register_locale name {axiom = axs', |
1967 imports = empty, |
|
1968 elems = map (fn e => (e, stamp ())) elems'', |
1958 elems = map (fn e => (e, stamp ())) elems'', |
1969 params = params_of elemss''' |> map (fn (x, SOME T) => ((x, T), the (Symtab.lookup syn x))), |
1959 params = params_of elemss''' |> map (fn (x, SOME T) => ((x, T), the (Symtab.lookup syn x))), |
1970 lparams = map #1 (params_of' body_elemss), |
|
1971 decls = ([], []), |
1960 decls = ([], []), |
1972 regs = regs, |
1961 regs = regs, |
1973 intros = intros, |
1962 intros = intros, |
1974 dests = map Element.conclude_witness pred_axioms} |
1963 dests = map Element.conclude_witness pred_axioms} |
1975 |> init name; |
1964 |> init name; |