src/Pure/Isar/locale.ML
changeset 68851 6c9825c1e26b
parent 68029 df9044efd054
child 68852 becaeaa334ae
equal deleted inserted replaced
68850:6d2735ca0271 68851:6c9825c1e26b
    71   val intro_add: attribute
    71   val intro_add: attribute
    72   val unfold_add: attribute
    72   val unfold_add: attribute
    73   val intro_locales_tac: bool -> Proof.context -> thm list -> tactic
    73   val intro_locales_tac: bool -> Proof.context -> thm list -> tactic
    74 
    74 
    75   (* Registrations and dependencies *)
    75   (* Registrations and dependencies *)
    76   val add_registration: string * morphism -> (morphism * bool) option ->
    76   type registration = {dep: string * morphism, mixin: (morphism * bool) option, export: morphism}
    77     morphism -> Context.generic -> Context.generic
    77   val amend_registration: registration -> Context.generic -> Context.generic
    78   val activate_fragment: string * morphism -> (morphism * bool) option -> morphism ->
    78   val add_registration: registration -> Context.generic -> Context.generic
    79     local_theory -> local_theory
    79   val activate_fragment: registration -> local_theory -> local_theory
    80   val activate_fragment_nonbrittle: string * morphism -> (morphism * bool) option -> morphism ->
    80   val activate_fragment_nonbrittle: registration -> local_theory -> local_theory
    81     local_theory -> local_theory
       
    82   val amend_registration: string * morphism -> morphism * bool ->
       
    83     morphism -> Context.generic -> Context.generic
       
    84   val registrations_of: Context.generic -> string -> (string * morphism) list
    81   val registrations_of: Context.generic -> string -> (string * morphism) list
    85   val add_dependency: string -> string * morphism -> (morphism * bool) option ->
    82   val add_dependency: string -> registration -> theory -> theory
    86     morphism -> theory -> theory
       
    87 
    83 
    88   (* Diagnostic *)
    84   (* Diagnostic *)
    89   val hyp_spec_of: theory -> string -> Element.context_i list
    85   val hyp_spec_of: theory -> string -> Element.context_i list
    90   val print_locales: bool -> theory -> unit
    86   val print_locales: bool -> theory -> unit
    91   val print_locale: theory -> bool -> xstring * Position.T -> unit
    87   val print_locale: theory -> bool -> xstring * Position.T -> unit
   514   end;
   510   end;
   515 
   511 
   516 
   512 
   517 (*** Add and extend registrations ***)
   513 (*** Add and extend registrations ***)
   518 
   514 
   519 fun amend_registration (name, morph) mixin export context =
   515 type registration = Locale.registration;
   520   let
   516 
   521     val thy = Context.theory_of context;
   517 fun amend_registration {mixin = NONE, ...} context = context
   522     val ctxt = Context.proof_of context;
   518   | amend_registration {dep = (name, morph), mixin = SOME mixin, export} context =
   523 
   519       let
   524     val regs = Registrations.get context |> fst;
   520         val thy = Context.theory_of context;
   525     val base = instance_of thy name (morph $> export);
   521         val ctxt = Context.proof_of context;
   526     val serial' =
   522 
   527       (case Idtab.lookup regs (name, base) of
   523         val regs = Registrations.get context |> fst;
   528         NONE =>
   524         val base = instance_of thy name (morph $> export);
   529           error ("No interpretation of locale " ^ quote (markup_name ctxt name) ^
   525         val serial' =
   530             " with\nparameter instantiation " ^
   526           (case Idtab.lookup regs (name, base) of
   531             space_implode " " (map (quote o Syntax.string_of_term_global thy) base) ^
   527             NONE =>
   532             " available")
   528               error ("No interpretation of locale " ^ quote (markup_name ctxt name) ^
   533       | SOME (_, serial') => serial');
   529                 " with\nparameter instantiation " ^
   534   in
   530                 space_implode " " (map (quote o Syntax.string_of_term_global thy) base) ^
   535     add_mixin serial' mixin context
   531                 " available")
   536   end;
   532           | SOME (_, serial') => serial');
       
   533       in
       
   534         add_mixin serial' mixin context
       
   535       end;
   537 
   536 
   538 (* Note that a registration that would be subsumed by an existing one will not be
   537 (* Note that a registration that would be subsumed by an existing one will not be
   539    generated, and it will not be possible to amend it. *)
   538    generated, and it will not be possible to amend it. *)
   540 
   539 
   541 fun add_registration (name, base_morph) mixin export context =
   540 fun add_registration {dep = (name, base_morph), mixin, export} context =
   542   let
   541   let
   543     val thy = Context.theory_of context;
   542     val thy = Context.theory_of context;
   544     val mix = (case mixin of NONE => Morphism.identity | SOME (mix, _) => mix);
   543     val mix = (case mixin of NONE => Morphism.identity | SOME (mix, _) => mix);
   545     val morph = base_morph $> mix;
   544     val morph = base_morph $> mix;
   546     val inst = instance_of thy name morph;
   545     val inst = instance_of thy name morph;
   552       (idents, context)
   551       (idents, context)
   553       (* add new registrations with inherited mixins *)
   552       (* add new registrations with inherited mixins *)
   554       |> roundup thy (add_reg thy export) export (name, morph)
   553       |> roundup thy (add_reg thy export) export (name, morph)
   555       |> snd
   554       |> snd
   556       (* add mixin *)
   555       (* add mixin *)
   557       |> (case mixin of NONE => I | SOME mixin => amend_registration (name, morph) mixin export)
   556       |> amend_registration {dep = (name, morph), mixin = mixin, export = export}
   558       (* activate import hierarchy as far as not already active *)
   557       (* activate import hierarchy as far as not already active *)
   559       |> activate_facts (SOME export) (name, morph)
   558       |> activate_facts (SOME export) (name, morph)
   560   end;
   559   end;
   561 
   560 
   562 
   561 
   563 (* locale fragments within local theory *)
   562 (* locale fragments within local theory *)
   564 
   563 
   565 fun activate_fragment_nonbrittle dep_morph mixin export lthy =
   564 fun activate_fragment_nonbrittle registration lthy =
   566   let val n = Local_Theory.level lthy in
   565   let val n = Local_Theory.level lthy in
   567     lthy |> Local_Theory.map_contexts (fn level =>
   566     lthy |> Local_Theory.map_contexts (fn level =>
   568       level = n - 1 ? Context.proof_map (add_registration dep_morph mixin export))
   567       level = n - 1 ? Context.proof_map (add_registration registration))
   569   end;
   568   end;
   570 
   569 
   571 fun activate_fragment dep_morph mixin export =
   570 fun activate_fragment registration =
   572   Local_Theory.mark_brittle #> activate_fragment_nonbrittle dep_morph mixin export;
   571   Local_Theory.mark_brittle #> activate_fragment_nonbrittle registration;
   573 
   572 
   574 
   573 
   575 
   574 
   576 (*** Dependencies ***)
   575 (*** Dependencies ***)
   577 
   576 
   588           " not a sublocale of " ^ quote (extern thy loc))
   587           " not a sublocale of " ^ quote (extern thy loc))
   589       | SOME (_, serial') => change_locale ...
   588       | SOME (_, serial') => change_locale ...
   590   end;
   589   end;
   591 *)
   590 *)
   592 
   591 
   593 fun add_dependency loc (name, morph) mixin export thy =
   592 fun add_dependency loc {dep = (name, morph), mixin, export} thy =
   594   let
   593   let
   595     val serial' = serial ();
   594     val serial' = serial ();
   596     val thy' = thy |>
   595     val thy' = thy |>
   597       (change_locale loc o apsnd)
   596       (change_locale loc o apsnd)
   598         (apfst (cons ((name, (morph, export)), serial')) #>
   597         (apfst (cons ((name, (morph, export)), serial')) #>
   599           apsnd (case mixin of NONE => I | SOME mixin => insert_mixin serial' mixin));
   598           apsnd (case mixin of NONE => I | SOME mixin => insert_mixin serial' mixin));
   600     val context' = Context.Theory thy';
   599     val context' = Context.Theory thy';
   601     val (_, regs) =
   600     val (_, regs) =
   602       fold_rev (roundup thy' cons export)
   601       fold_rev (roundup thy' cons export)
   603         (registrations_of context' loc) (Idents.get context', []);
   602         (registrations_of context' loc) (Idents.get context', []);
   604   in
   603     fun add_dep dep = add_registration {dep = dep, mixin = NONE, export = export};
   605     thy'
   604   in thy' |> fold_rev (Context.theory_map o add_dep) regs end;
   606     |> fold_rev (fn dep => Context.theory_map (add_registration dep NONE export)) regs
       
   607   end;
       
   608 
   605 
   609 
   606 
   610 (*** Storing results ***)
   607 (*** Storing results ***)
   611 
   608 
   612 fun add_facts loc kind facts ctxt =
   609 fun add_facts loc kind facts ctxt =