src/Pure/Isar/locale.ML
changeset 78065 11d6a1e62841
parent 78064 4e865c45458b
child 78072 001739cb8d08
equal deleted inserted replaced
78064:4e865c45458b 78065:11d6a1e62841
   105 (*** Locales ***)
   105 (*** Locales ***)
   106 
   106 
   107 type dep = {name: string, morphisms: morphism * morphism, pos: Position.T, serial: serial};
   107 type dep = {name: string, morphisms: morphism * morphism, pos: Position.T, serial: serial};
   108 fun eq_dep (dep1: dep, dep2: dep) = #serial dep1 = #serial dep2;
   108 fun eq_dep (dep1: dep, dep2: dep) = #serial dep1 = #serial dep2;
   109 
   109 
       
   110 fun transfer_dep thy ({name, morphisms, pos, serial}: dep) : dep =
       
   111   {name = name, morphisms = apply2 (Morphism.set_context thy) morphisms, pos = pos, serial = serial};
       
   112 
   110 fun make_dep (name, morphisms) : dep =
   113 fun make_dep (name, morphisms) : dep =
   111   {name = name, morphisms = morphisms, pos = Position.thread_data (), serial = serial ()};
   114  {name = name,
       
   115   morphisms = apply2 Morphism.reset_context morphisms,
       
   116   pos = Position.thread_data (),
       
   117   serial = serial ()};
   112 
   118 
   113 (*table of mixin lists, per list mixins in reverse order of declaration;
   119 (*table of mixin lists, per list mixins in reverse order of declaration;
   114   lists indexed by registration/dependency serial,
   120   lists indexed by registration/dependency serial,
   115   entries for empty lists may be omitted*)
   121   entries for empty lists may be omitted*)
   116 type mixin = (morphism * bool) * serial;
   122 type mixin = (morphism * bool) * serial;
   118 
   124 
   119 fun lookup_mixins (mixins: mixins) serial' = Inttab.lookup_list mixins serial';
   125 fun lookup_mixins (mixins: mixins) serial' = Inttab.lookup_list mixins serial';
   120 
   126 
   121 val merge_mixins: mixins * mixins -> mixins = Inttab.merge_list (eq_snd op =);
   127 val merge_mixins: mixins * mixins -> mixins = Inttab.merge_list (eq_snd op =);
   122 
   128 
   123 fun insert_mixin serial' mixin : mixins -> mixins = Inttab.cons_list (serial', (mixin, serial ()));
   129 fun insert_mixin serial' (morph, b) : mixins -> mixins =
       
   130   Inttab.cons_list (serial', ((Morphism.reset_context morph, b), serial ()));
   124 
   131 
   125 fun rename_mixin (old, new) (mixins: mixins) =
   132 fun rename_mixin (old, new) (mixins: mixins) =
   126   (case Inttab.lookup mixins old of
   133   (case Inttab.lookup mixins old of
   127     NONE => mixins
   134     NONE => mixins
   128   | SOME mixin => Inttab.delete old mixins |> Inttab.update_new (new, mixin));
   135   | SOME mixin => Inttab.delete old mixins |> Inttab.update_new (new, mixin));
   214       mk_locale ((parameters, spec, (apply2 o Option.map) Thm.trim_context intros,
   221       mk_locale ((parameters, spec, (apply2 o Option.map) Thm.trim_context intros,
   215           map Thm.trim_context axioms,
   222           map Thm.trim_context axioms,
   216           map Element.trim_context_ctxt hyp_spec),
   223           map Element.trim_context_ctxt hyp_spec),
   217         ((map (fn decl => (decl, serial ())) syntax_decls,
   224         ((map (fn decl => (decl, serial ())) syntax_decls,
   218           map (fn (a, facts) => ((a, map Attrib.trim_context_fact facts), serial ())) notes),
   225           map (fn (a, facts) => ((a, map Attrib.trim_context_fact facts), serial ())) notes),
   219           (map (fn (name, morph) =>
   226           (map (fn (name, morph) => make_dep (name, (morph, Morphism.identity))) dependencies,
   220                 make_dep (name, (Morphism.reset_context morph, Morphism.identity))) dependencies,
       
   221             Inttab.empty)))) #> snd);
   227             Inttab.empty)))) #> snd);
   222           (* FIXME Morphism.identity *)
   228           (* FIXME Morphism.identity *)
   223 
   229 
   224 fun change_locale name =
   230 fun change_locale name =
   225   Locales.map o Name_Space.map_table_entry name o map_locale o apsnd;
   231   Locales.map o Name_Space.map_table_entry name o map_locale o apsnd;
   234 fun intros_of thy = (apply2 o Option.map) (Thm.transfer thy) o #intros o the_locale thy;
   240 fun intros_of thy = (apply2 o Option.map) (Thm.transfer thy) o #intros o the_locale thy;
   235 
   241 
   236 fun axioms_of thy = map (Thm.transfer thy) o #axioms o the_locale thy;
   242 fun axioms_of thy = map (Thm.transfer thy) o #axioms o the_locale thy;
   237 
   243 
   238 fun instance_of thy name morph = params_of thy name |>
   244 fun instance_of thy name morph = params_of thy name |>
   239   map (Morphism.term morph o Free o #1);
   245   map (Morphism.term (Morphism.set_context thy morph) o Free o #1);
   240 
   246 
   241 fun specification_of thy = #spec o the_locale thy;
   247 fun specification_of thy = #spec o the_locale thy;
   242 
   248 
   243 fun hyp_spec_of thy = #hyp_spec o the_locale thy;
   249 fun hyp_spec_of thy = map (Element.transfer_ctxt thy) o #hyp_spec o the_locale thy;
   244 
   250 
   245 fun dependencies_of thy = #dependencies o the_locale thy;
   251 fun dependencies_of thy = map (transfer_dep thy) o #dependencies o the_locale thy;
   246 
   252 
   247 fun mixins_of thy name serial = lookup_mixins (#mixins (the_locale thy name)) serial;
   253 fun mixins_of thy name serial =
       
   254   lookup_mixins (#mixins (the_locale thy name)) serial
       
   255   |> (map o apfst o apfst) (Morphism.set_context thy);
   248 
   256 
   249 
   257 
   250 (* Print instance and qualifiers *)
   258 (* Print instance and qualifiers *)
   251 
   259 
   252 fun pretty_reg_inst ctxt qs (name, ts) =
   260 fun pretty_reg_inst ctxt qs (name, ts) =
   396 
   404 
   397 (* Primitive operations *)
   405 (* Primitive operations *)
   398 
   406 
   399 fun add_reg thy export (name, morph) =
   407 fun add_reg thy export (name, morph) =
   400   let
   408   let
   401     val reg = {morphisms = (morph, export), pos = Position.thread_data (), serial = serial ()};
   409     val reg =
       
   410      {morphisms = (Morphism.reset_context morph, Morphism.reset_context export),
       
   411       pos = Position.thread_data (),
       
   412       serial = serial ()};
   402     val id = (name, instance_of thy name (morph $> export));
   413     val id = (name, instance_of thy name (morph $> export));
   403   in (map_registrations o apfst) (Idtab.insert (K false) (id, reg)) end;
   414   in (map_registrations o apfst) (Idtab.insert (K false) (id, reg)) end;
   404 
   415 
   405 fun add_mixin serial' mixin =
   416 fun add_mixin serial' mixin =
   406   (* registration to be amended identified by its serial id *)
   417   (* registration to be amended identified by its serial id *)
   492     context
   503     context
   493     |> fold_rev (fn (decl, _) => decl morph) syntax_decls
   504     |> fold_rev (fn (decl, _) => decl morph) syntax_decls
   494       handle ERROR msg => activate_err msg "syntax" (name, morph) context
   505       handle ERROR msg => activate_err msg "syntax" (name, morph) context
   495   end;
   506   end;
   496 
   507 
   497 fun activate_notes activ_elem transfer context export' (name, morph) input =
   508 fun activate_notes activ_elem context export' (name, morph) input =
   498   let
   509   let
   499     val thy = Context.theory_of context;
   510     val thy = Context.theory_of context;
   500     val mixin =
   511     val mixin =
   501       (case export' of
   512       (case export' of
   502         NONE => Morphism.identity
   513         NONE => Morphism.identity
   503       | SOME export => collect_mixins context (name, morph $> export) $> export);
   514       | SOME export => collect_mixins context (name, morph $> export) $> export);
   504     val morph' = transfer input $> morph $> mixin;
   515     val morph' = Morphism.set_context thy (morph $> mixin);
   505     val notes' = map (Element.transform_ctxt morph') (lazy_notes thy name);
   516     val notes' = map (Element.transform_ctxt morph') (lazy_notes thy name);
   506   in
   517   in
   507     (notes', input) |-> fold (fn elem => fn res =>
   518     (notes', input) |-> fold (fn elem => fn res =>
   508       activ_elem (Element.transform_ctxt (transfer res) elem) res)
   519       activ_elem (Element.transfer_ctxt thy elem) res)
   509   end handle ERROR msg => activate_err msg "facts" (name, morph) context;
   520   end handle ERROR msg => activate_err msg "facts" (name, morph) context;
   510 
   521 
   511 fun activate_notes_trace activ_elem transfer context export' (name, morph) context' =
   522 fun activate_notes_trace activ_elem context export' (name, morph) context' =
   512   let
   523   let
   513     val _ = trace "facts" (name, morph) context';
   524     val _ = trace "facts" (name, morph) context';
   514   in
   525   in
   515     activate_notes activ_elem transfer context export' (name, morph) context'
   526     activate_notes activ_elem context export' (name, morph) context'
   516   end;
   527   end;
   517 
   528 
   518 fun activate_all name thy activ_elem transfer (marked, input) =
   529 fun activate_all name thy activ_elem (marked, input) =
   519   let
   530   let
   520     val {parameters = (_, params), spec = (asm, defs), ...} = the_locale thy name;
   531     val {parameters = (_, params), spec = (asm, defs), ...} = the_locale thy name;
   521     val input' = input |>
   532     val input' = input |>
   522       (not (null params) ?
   533       (not (null params) ?
   523         activ_elem (Fixes (map (fn ((x, T), mx) => (Binding.name x, SOME T, mx)) params))) |>
   534         activ_elem (Fixes (map (fn ((x, T), mx) => (Binding.name x, SOME T, mx)) params))) |>
   524       (* FIXME type parameters *)
   535       (* FIXME type parameters *)
   525       (case asm of SOME A => activ_elem (Assumes [(Binding.empty_atts, [(A, [])])]) | _ => I) |>
   536       (case asm of SOME A => activ_elem (Assumes [(Binding.empty_atts, [(A, [])])]) | _ => I) |>
   526       (not (null defs) ?
   537       (not (null defs) ?
   527         activ_elem (Defines (map (fn def => (Binding.empty_atts, (def, []))) defs)));
   538         activ_elem (Defines (map (fn def => (Binding.empty_atts, (def, []))) defs)));
   528     val activate = activate_notes activ_elem transfer (Context.Theory thy) NONE;
   539     val activate = activate_notes activ_elem (Context.Theory thy) NONE;
   529   in
   540   in
   530     roundup thy activate Morphism.identity (name, Morphism.identity) (marked, input')
   541     roundup thy activate Morphism.identity (name, Morphism.identity) (marked, input')
   531   end;
   542   end;
   532 
   543 
   533 
   544 
   536 fun activate_facts export dep context =
   547 fun activate_facts export dep context =
   537   context
   548   context
   538   |> Context_Position.set_visible_generic false
   549   |> Context_Position.set_visible_generic false
   539   |> pair (Idents.get context)
   550   |> pair (Idents.get context)
   540   |> roundup (Context.theory_of context)
   551   |> roundup (Context.theory_of context)
   541       (activate_notes_trace init_element Morphism.transfer_morphism'' context export)
   552       (activate_notes_trace init_element context export)
   542       (Morphism.default export) dep
   553       (Morphism.default export) dep
   543   |-> Idents.put
   554   |-> Idents.put
   544   |> Context_Position.restore_visible_generic context;
   555   |> Context_Position.restore_visible_generic context;
   545 
   556 
   546 fun activate_declarations dep = Context.proof_map (fn context =>
   557 fun activate_declarations dep = Context.proof_map (fn context =>
   557     val marked = Idents.get context;
   568     val marked = Idents.get context;
   558   in
   569   in
   559     context
   570     context
   560     |> Context_Position.set_visible_generic false
   571     |> Context_Position.set_visible_generic false
   561     |> pair empty_idents
   572     |> pair empty_idents
   562     |> activate_all name thy init_element Morphism.transfer_morphism''
   573     |> activate_all name thy init_element
   563     |-> (fn marked' => Idents.put (merge_idents (marked, marked')))
   574     |-> (fn marked' => Idents.put (merge_idents (marked, marked')))
   564     |> Context_Position.restore_visible_generic context
   575     |> Context_Position.restore_visible_generic context
   565     |> Context.proof_of
   576     |> Context.proof_of
   566   end;
   577   end;
   567 
   578 
   733     val locale_ctxt = init name thy;
   744     val locale_ctxt = init name thy;
   734     fun cons_elem (elem as Notes _) = show_facts ? cons elem
   745     fun cons_elem (elem as Notes _) = show_facts ? cons elem
   735       | cons_elem (elem as Lazy_Notes _) = show_facts ? cons elem
   746       | cons_elem (elem as Lazy_Notes _) = show_facts ? cons elem
   736       | cons_elem elem = cons elem;
   747       | cons_elem elem = cons elem;
   737     val elems =
   748     val elems =
   738       activate_all name thy cons_elem (K (Morphism.transfer_morphism thy)) (empty_idents, [])
   749       activate_all name thy cons_elem (empty_idents, [])
   739       |> snd |> rev
   750       |> snd |> rev
   740       |> tap consolidate_notes
   751       |> tap consolidate_notes
   741       |> map force_notes;
   752       |> map force_notes;
   742   in
   753   in
   743     Pretty.block (Pretty.keyword1 "locale" :: Pretty.brk 1 :: pretty_name locale_ctxt name ::
   754     Pretty.block (Pretty.keyword1 "locale" :: Pretty.brk 1 :: pretty_name locale_ctxt name ::