src/Pure/Isar/locale.ML
changeset 15596 8665d08085df
parent 15574 b1d1b5bfc464
child 15598 4ab52355bb53
equal deleted inserted replaced
15595:dc8a41c7cefc 15596:8665d08085df
    19 *)
    19 *)
    20 
    20 
    21 signature LOCALE =
    21 signature LOCALE =
    22 sig
    22 sig
    23   type context
    23   type context
       
    24   type multi_attribute
    24 
    25 
    25   (* Constructors for elem, expr and elem_expr are
    26   (* Constructors for elem, expr and elem_expr are
    26      currently only used for inputting locales (outer_parse.ML). *)
    27      currently only used for inputting locales (outer_parse.ML). *)
    27   datatype ('typ, 'term, 'fact, 'att) elem =
    28   datatype ('typ, 'term, 'fact, 'att) elem =
    28     Fixes of (string * 'typ option * mixfix option) list |
    29     Fixes of (string * 'typ option * mixfix option) list |
    41   type 'att element_i
    42   type 'att element_i
    42   type locale
    43   type locale
    43   val intern: Sign.sg -> xstring -> string
    44   val intern: Sign.sg -> xstring -> string
    44   val cond_extern: Sign.sg -> string -> xstring
    45   val cond_extern: Sign.sg -> string -> xstring
    45   val the_locale: theory -> string -> locale
    46   val the_locale: theory -> string -> locale
    46   val map_attrib_element: ('att -> context attribute) -> 'att element ->
    47   val map_attrib_element: ('att -> multi_attribute) -> 'att element ->
    47     context attribute element
    48     multi_attribute element
    48   val map_attrib_element_i: ('att -> context attribute) -> 'att element_i ->
    49   val map_attrib_element_i: ('att -> multi_attribute) -> 'att element_i ->
    49     context attribute element_i
    50     multi_attribute element_i
    50   val map_attrib_elem_or_expr: ('att -> context attribute) ->
    51   val map_attrib_elem_or_expr: ('att -> multi_attribute) ->
    51     'att element elem_expr -> context attribute element elem_expr
    52     'att element elem_expr -> multi_attribute element elem_expr
    52   val map_attrib_elem_or_expr_i: ('att -> context attribute) ->
    53   val map_attrib_elem_or_expr_i: ('att -> multi_attribute) ->
    53     'att element_i elem_expr -> context attribute element_i elem_expr
    54     'att element_i elem_expr -> multi_attribute element_i elem_expr
    54 
    55 
       
    56   (* Processing of locale statements *)
    55   val read_context_statement: xstring option ->
    57   val read_context_statement: xstring option ->
    56     context attribute element elem_expr list ->
    58     multi_attribute element elem_expr list ->
    57     (string * (string list * string list)) list list -> context ->
    59     (string * (string list * string list)) list list -> context ->
    58     string option * (cterm list * cterm list) * context * context * 
    60     string option * (cterm list * cterm list) * context * context * 
    59       (term * (term list * term list)) list list
    61       (term * (term list * term list)) list list
    60   val cert_context_statement: string option ->
    62   val cert_context_statement: string option ->
    61     context attribute element_i elem_expr list ->
    63     multi_attribute element_i elem_expr list ->
    62     (term * (term list * term list)) list list -> context ->
    64     (term * (term list * term list)) list list -> context ->
    63     string option * (cterm list * cterm list) * context * context *
    65     string option * (cterm list * cterm list) * context * context *
    64       (term * (term list * term list)) list list
    66       (term * (term list * term list)) list list
       
    67 
       
    68   (* Diagnostic functions *)
    65   val print_locales: theory -> unit
    69   val print_locales: theory -> unit
    66   val print_locale: theory -> expr -> context attribute element list -> unit
    70   val print_locale: theory -> expr -> multi_attribute element list -> unit
    67   val add_locale: bool -> bstring -> expr -> context attribute element list -> theory -> theory
    71   val print_global_registrations: theory -> string -> unit
    68   val add_locale_i: bool -> bstring -> expr -> context attribute element_i list
    72 
       
    73   val add_locale: bool -> bstring -> expr -> multi_attribute element list -> theory -> theory
       
    74   val add_locale_i: bool -> bstring -> expr -> multi_attribute element_i list
    69     -> theory -> theory
    75     -> theory -> theory
    70   val smart_note_thmss: string -> (string * 'a) option ->
    76   val smart_note_thmss: string -> (string * 'a) option ->
    71     ((bstring * theory attribute list) * (thm list * theory attribute list) list) list ->
    77     ((bstring * theory attribute list) * (thm list * theory attribute list) list) list ->
    72     theory -> theory * (bstring * thm list) list
    78     theory -> theory * (bstring * thm list) list
    73   val note_thmss: string -> xstring ->
    79   val note_thmss: string -> xstring ->
    74     ((bstring * context attribute list) * (thmref * context attribute list) list) list ->
    80     ((bstring * multi_attribute list) * (thmref * multi_attribute list) list) list ->
    75     theory -> theory * (bstring * thm list) list
    81     theory -> theory * (bstring * thm list) list
    76   val note_thmss_i: string -> string ->
    82   val note_thmss_i: string -> string ->
    77     ((bstring * context attribute list) * (thm list * context attribute list) list) list ->
    83     ((bstring * multi_attribute list) * (thm list * multi_attribute list) list) list ->
    78     theory -> theory * (bstring * thm list) list
    84     theory -> theory * (bstring * thm list) list
    79   val add_thmss: string -> ((string * thm list) * context attribute list) list ->
    85   val add_thmss: string -> ((string * thm list) * multi_attribute list) list ->
    80     theory * context -> (theory * context) * (string * thm list) list
    86     theory * context -> (theory * context) * (string * thm list) list
       
    87 
    81   val instantiate: string -> string * context attribute list
    88   val instantiate: string -> string * context attribute list
    82     -> thm list option -> context -> context
    89     -> thm list option -> context -> context
       
    90   val prep_registration:
       
    91     string * theory attribute list -> expr -> string option list -> theory ->
       
    92     theory * ((string * term list) * term list) list * (theory -> theory)
       
    93   val global_activate_thm:
       
    94     string * term list -> thm -> theory -> theory
       
    95 
    83   val setup: (theory -> theory) list
    96   val setup: (theory -> theory) list
    84 end;
    97 end;
    85 
    98 
    86 structure Locale: LOCALE =
    99 structure Locale: LOCALE =
    87 struct
   100 struct
    88 
   101 
    89 (** locale elements and expressions **)
   102 (** locale elements and expressions **)
    90 
   103 
    91 type context = ProofContext.context;
   104 type context = ProofContext.context;
       
   105 
       
   106 (* Locales store theory attributes (for activation in theories)
       
   107    and context attributes (for activation in contexts) *)
       
   108 type multi_attribute = theory attribute * context attribute;
    92 
   109 
    93 datatype ('typ, 'term, 'fact, 'att) elem =
   110 datatype ('typ, 'term, 'fact, 'att) elem =
    94   Fixes of (string * 'typ option * mixfix option) list |
   111   Fixes of (string * 'typ option * mixfix option) list |
    95   Assumes of ((string * 'att list) * ('term * ('term list * 'term list)) list) list |
   112   Assumes of ((string * 'att list) * ('term * ('term list * 'term list)) list) list |
    96   Defines of ((string * 'att list) * ('term * 'term list)) list |
   113   Defines of ((string * 'att list) * ('term * 'term list)) list |
   119        to the (assumed) locale parameters.  Axioms contains the projections
   136        to the (assumed) locale parameters.  Axioms contains the projections
   120        from the locale predicate to the normalised assumptions of the locale
   137        from the locale predicate to the normalised assumptions of the locale
   121        (cf. [1], normalisation of locale expressions.)
   138        (cf. [1], normalisation of locale expressions.)
   122     *)
   139     *)
   123   import: expr,                                       (*dynamic import*)
   140   import: expr,                                       (*dynamic import*)
   124   elems: (context attribute element_i * stamp) list,  (*static content*)
   141   elems: (multi_attribute element_i * stamp) list,  (*static content*)
   125   params: (string * typ option) list * string list}   (*all/local params*)
   142   params: (string * typ option) list * string list}   (*all/local params*)
   126 
   143 
   127 
   144 
   128 (** theory data **)
   145 (** theory data **)
       
   146 
       
   147 structure Termlisttab = TableFun(type key = term list
       
   148   val ord = Library.list_ord Term.term_ord);
   129 
   149 
   130 structure LocalesArgs =
   150 structure LocalesArgs =
   131 struct
   151 struct
   132   val name = "Isar/locales";
   152   val name = "Isar/locales";
   133   type T = NameSpace.T * locale Symtab.table;
   153   type T = NameSpace.T * locale Symtab.table *
   134 
   154       ((string * theory attribute list) * thm list) Termlisttab.table
   135   val empty = (NameSpace.empty, Symtab.empty);
   155         Symtab.table;
       
   156     (* 1st entry: locale namespace,
       
   157        2nd entry: locales of the theory,
       
   158        3rd entry: registrations: theorems instantiating locale assumptions,
       
   159          with prefix and attributes, indexed by locale name and parameter
       
   160          instantiation *)
       
   161 
       
   162   val empty = (NameSpace.empty, Symtab.empty, Symtab.empty);
   136   val copy = I;
   163   val copy = I;
   137   val prep_ext = I;
   164   val prep_ext = I;
   138 
   165 
   139   (*joining of locale elements: only facts may be added later!*)
   166   fun join_locs ({predicate, import, elems, params}: locale,
   140   fun join ({predicate, import, elems, params}: locale, {elems = elems', ...}: locale) =
   167       {elems = elems', ...}: locale) =
   141     SOME {predicate = predicate, import = import, elems = gen_merge_lists eq_snd elems elems',
   168     SOME {predicate = predicate, import = import,
       
   169       elems = gen_merge_lists eq_snd elems elems',
   142       params = params};
   170       params = params};
   143   fun merge ((space1, locs1), (space2, locs2)) =
   171   (* joining of registrations: prefix and attributes of left theory,
   144     (NameSpace.merge (space1, space2), Symtab.join join (locs1, locs2));
   172      thmsss are equal *)
   145 
   173   fun join_regs (reg, _) = SOME reg;
   146   fun print _ (space, locs) =
   174   fun merge ((space1, locs1, regs1), (space2, locs2, regs2)) =
       
   175     (NameSpace.merge (space1, space2), Symtab.join join_locs (locs1, locs2),
       
   176      Symtab.join (SOME o Termlisttab.join join_regs) (regs1, regs2));
       
   177 
       
   178   fun print _ (space, locs, _) =
   147     Pretty.strs ("locales:" :: map (NameSpace.cond_extern space o #1) (Symtab.dest locs))
   179     Pretty.strs ("locales:" :: map (NameSpace.cond_extern space o #1) (Symtab.dest locs))
   148     |> Pretty.writeln;
   180     |> Pretty.writeln;
   149 end;
   181 end;
   150 
   182 
   151 structure LocalesData = TheoryDataFun(LocalesArgs);
   183 structure LocalesData = TheoryDataFun(LocalesArgs);
   156 
   188 
   157 
   189 
   158 (* access locales *)
   190 (* access locales *)
   159 
   191 
   160 fun declare_locale name =
   192 fun declare_locale name =
   161   LocalesData.map (apfst (fn space => (NameSpace.extend (space, [name]))));
   193   LocalesData.map (fn (space, locs, regs) =>
   162 
   194     (NameSpace.extend (space, [name]), locs, regs));
   163 fun put_locale name loc = LocalesData.map (apsnd (fn locs => Symtab.update ((name, loc), locs)));
   195 
       
   196 fun put_locale name loc =
       
   197   LocalesData.map (fn (space, locs, regs) =>
       
   198     (space, Symtab.update ((name, loc), locs), regs));
       
   199 
   164 fun get_locale thy name = Symtab.lookup (#2 (LocalesData.get thy), name);
   200 fun get_locale thy name = Symtab.lookup (#2 (LocalesData.get thy), name);
   165 
   201 
   166 fun the_locale thy name =
   202 fun the_locale thy name =
   167   (case get_locale thy name of
   203   (case get_locale thy name of
   168     SOME loc => loc
   204     SOME loc => loc
   169   | NONE => error ("Unknown locale " ^ quote name));
   205   | NONE => error ("Unknown locale " ^ quote name));
       
   206 
       
   207 
       
   208 (* access registrations *)
       
   209 
       
   210 (* add registration to theory, ignored if already present *)
       
   211 
       
   212 fun global_put_registration (name, ps) attn =
       
   213   LocalesData.map (fn (space, locs, regs) =>
       
   214     (space, locs, let
       
   215         val tab = getOpt (Symtab.lookup (regs, name), Termlisttab.empty);
       
   216       in
       
   217         Symtab.update ((name, Termlisttab.update_new ((ps, (attn, [])), tab)),
       
   218           regs)
       
   219       end handle Termlisttab.DUP _ => regs));
       
   220 
       
   221 (* add theorem to registration in theory,
       
   222    ignored if registration not present *)
       
   223 
       
   224 fun global_put_registration_thm (name, ps) thm =
       
   225   LocalesData.map (fn (space, locs, regs) =>
       
   226     (space, locs, let
       
   227         val tab = valOf (Symtab.lookup (regs, name));
       
   228         val (x, thms) = valOf (Termlisttab.lookup (tab, ps));
       
   229       in
       
   230         Symtab.update ((name, Termlisttab.update ((ps, (x, thm::thms)), tab)),
       
   231           regs)
       
   232       end handle Option => regs))
       
   233 
       
   234 fun global_get_registration thy (name, ps) =
       
   235   case Symtab.lookup (#3 (LocalesData.get thy), name) of
       
   236       NONE => NONE
       
   237     | SOME tab => Termlisttab.lookup (tab, ps);
   170 
   238 
   171 
   239 
   172 (* import hierarchy
   240 (* import hierarchy
   173    implementation could be more efficient, eg. by maintaining a database
   241    implementation could be more efficient, eg. by maintaining a database
   174    of dependencies *)
   242    of dependencies *)
   182          | SOME {import, ...} => imps import low)
   250          | SOME {import, ...} => imps import low)
   183       | imps (Rename (expr, _)) low = imps expr low
   251       | imps (Rename (expr, _)) low = imps expr low
   184       | imps (Merge es) low = exists (fn e => imps e low) es;
   252       | imps (Merge es) low = exists (fn e => imps e low) es;
   185   in
   253   in
   186     imps (Locale (intern sign upper)) (intern sign lower)
   254     imps (Locale (intern sign upper)) (intern sign lower)
       
   255   end;
       
   256 
       
   257 
       
   258 (* registrations *)
       
   259 
       
   260 fun print_global_registrations thy loc =
       
   261   let
       
   262     val sg = Theory.sign_of thy;
       
   263     val loc_int = intern sg loc;
       
   264     val (_, _, regs) = LocalesData.get thy;
       
   265     val prt_term = Pretty.quote o Sign.pretty_term sg;
       
   266     fun prt_inst (ts, ((prfx, _), thms)) = let
       
   267 in
       
   268       Pretty.block [Pretty.str prfx, Pretty.str ":", Pretty.brk 1,
       
   269         Pretty.list "(" ")" (map prt_term ts)]
       
   270 end;
       
   271     val loc_regs = Symtab.lookup (regs, loc_int);
       
   272   in
       
   273     (case loc_regs of
       
   274         NONE => Pretty.str "No registrations."
       
   275       | SOME r => Pretty.big_list "registrations:"
       
   276           (map prt_inst (Termlisttab.dest r)))
       
   277     |> Pretty.writeln
   187   end;
   278   end;
   188 
   279 
   189 
   280 
   190 (* diagnostics *)
   281 (* diagnostics *)
   191 
   282 
   423         fun inst ((((name, ps), axs), elems), env) =
   514         fun inst ((((name, ps), axs), elems), env) =
   424           (((name, map (apsnd (Option.map (inst_type env))) ps), 
   515           (((name, map (apsnd (Option.map (inst_type env))) ps), 
   425             map (inst_thm ctxt env) axs), map (inst_elem ctxt env) elems);
   516             map (inst_thm ctxt env) axs), map (inst_elem ctxt env) elems);
   426       in map inst (elemss ~~ envs) end;
   517       in map inst (elemss ~~ envs) end;
   427 
   518 
       
   519 (* flatten_expr:
       
   520    Extend list of identifiers by those new in locale expression expr.
       
   521    Compute corresponding list of lists of locale elements (one entry per
       
   522    identifier).
       
   523 
       
   524    Identifiers represent locale fragments and are in an extended form:
       
   525      ((name, ps), (ax_ps, axs))
       
   526    (name, ps) is the locale name with all its parameters.
       
   527    (ax_ps, axs) is the locale axioms with its parameters;
       
   528      axs are always taken from the top level of the locale hierarchy,
       
   529      hence axioms may contain additional parameters from later fragments:
       
   530      ps subset of ax_ps.  axs is either singleton or empty.
       
   531 
       
   532    Elements are enriched by identifier-like information:
       
   533      (((name, ax_ps), axs), elems)
       
   534    The parameters in ax_ps are the axiom parameters, but enriched by type
       
   535    info: now each entry is a pair of string and typ option.  Axioms are
       
   536    type-instantiated.
       
   537 
       
   538 *)
       
   539 
   428 fun flatten_expr ctxt (prev_idents, expr) =
   540 fun flatten_expr ctxt (prev_idents, expr) =
   429   let
   541   let
   430     val thy = ProofContext.theory_of ctxt;
   542     val thy = ProofContext.theory_of ctxt;
       
   543     (* thy used for retrieval of locale info,
       
   544        ctxt for error messages, parameter unification and instantiation
       
   545        of axioms *)
       
   546     (* TODO: consider err_in_locale with thy argument *)
   431 
   547 
   432     fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys
   548     fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys
   433       | renaming (NONE :: xs) (y :: ys) = renaming xs ys
   549       | renaming (NONE :: xs) (y :: ys) = renaming xs ys
   434       | renaming [] _ = []
   550       | renaming [] _ = []
   435       | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^
   551       | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^
   442           else (parms, axs))
   558           else (parms, axs))
   443         | dups => err_in_locale ctxt ("Duplicate parameters: " ^ commas_quote dups) [(name, ps')])
   559         | dups => err_in_locale ctxt ("Duplicate parameters: " ^ commas_quote dups) [(name, ps')])
   444       end;
   560       end;
   445 
   561 
   446     fun identify top (Locale name) =
   562     fun identify top (Locale name) =
   447     (* CB: ids is a list of tuples of the form ((name, ps)  axs),
   563     (* CB: ids_ax is a list of tuples of the form ((name, ps), axs),
   448        where name is a locale name, ps a list of parameter names and axs
   564        where name is a locale name, ps a list of parameter names and axs
   449        a list of axioms relating to the identifier, axs is empty unless
   565        a list of axioms relating to the identifier, axs is empty unless
   450        identify at top level (top = true);
   566        identify at top level (top = true);
   451        parms is accumulated list of parameters *)
   567        parms is accumulated list of parameters *)
   452           let
   568           let
   517   in (prev_idents @ idents, final_elemss) end;
   633   in (prev_idents @ idents, final_elemss) end;
   518 
   634 
   519 end;
   635 end;
   520 
   636 
   521 
   637 
       
   638 (* attributes *)
       
   639 
       
   640 local
       
   641 
       
   642 fun read_att attrib (x, srcs) = (x, map attrib srcs)
       
   643 
       
   644 (* CB: Map attrib over
       
   645    * A context element: add attrib to attribute lists of assumptions,
       
   646      definitions and facts (on both sides for facts).
       
   647    * Locale expression: no effect. *)
       
   648 
       
   649 fun gen_map_attrib_elem _ (Fixes fixes) = Fixes fixes
       
   650   | gen_map_attrib_elem attrib (Assumes asms) = Assumes (map (apfst (read_att attrib)) asms)
       
   651   | gen_map_attrib_elem attrib (Defines defs) = Defines (map (apfst (read_att attrib)) defs)
       
   652   | gen_map_attrib_elem attrib (Notes facts) =
       
   653       Notes (map (apfst (read_att attrib) o apsnd (map (read_att attrib))) facts)
       
   654 
       
   655 fun gen_map_attrib_elem_expr attrib (Elem elem) = Elem (gen_map_attrib_elem attrib elem)
       
   656   | gen_map_attrib_elem_expr _ (Expr expr) = Expr expr;
       
   657 
       
   658 in
       
   659 
       
   660 val map_attrib_element = gen_map_attrib_elem;
       
   661 val map_attrib_element_i = gen_map_attrib_elem;
       
   662 val map_attrib_elem_or_expr = gen_map_attrib_elem_expr;
       
   663 val map_attrib_elem_or_expr_i = gen_map_attrib_elem_expr;
       
   664 
       
   665 end;
       
   666 
       
   667 
   522 (* activate elements *)
   668 (* activate elements *)
   523 
   669 
   524 local
   670 local
   525 
   671 
   526 fun export_axioms axs _ hyps th =
   672 fun export_axioms axs _ hyps th =
   532 
   678 
   533 fun activate_elem _ ((ctxt, axs), Fixes fixes) =
   679 fun activate_elem _ ((ctxt, axs), Fixes fixes) =
   534       ((ctxt |> ProofContext.add_fixes fixes, axs), [])
   680       ((ctxt |> ProofContext.add_fixes fixes, axs), [])
   535   | activate_elem _ ((ctxt, axs), Assumes asms) =
   681   | activate_elem _ ((ctxt, axs), Assumes asms) =
   536       let
   682       let
       
   683         (* extract context attributes *)
       
   684         val (Assumes asms) = map_attrib_element_i snd (Assumes asms);
   537         val ts = List.concat (map (map #1 o #2) asms);
   685         val ts = List.concat (map (map #1 o #2) asms);
   538         val (ps,qs) = splitAt (length ts, axs);
   686         val (ps,qs) = splitAt (length ts, axs);
   539         val (ctxt', _) =
   687         val (ctxt', _) =
   540           ctxt |> ProofContext.fix_frees ts
   688           ctxt |> ProofContext.fix_frees ts
   541           |> ProofContext.assume_i (export_axioms ps) asms;
   689           |> ProofContext.assume_i (export_axioms ps) asms;
   542       in ((ctxt', qs), []) end
   690       in ((ctxt', qs), []) end
   543   | activate_elem _ ((ctxt, axs), Defines defs) =
   691   | activate_elem _ ((ctxt, axs), Defines defs) =
   544       let val (ctxt', _) =
   692       let
       
   693         (* extract context attributes *)
       
   694         val (Defines defs) = map_attrib_element_i snd (Defines defs);
       
   695         val (ctxt', _) =
   545         ctxt |> ProofContext.assume_i ProofContext.export_def
   696         ctxt |> ProofContext.assume_i ProofContext.export_def
   546           (defs |> map (fn ((name, atts), (t, ps)) =>
   697           (defs |> map (fn ((name, atts), (t, ps)) =>
   547             let val (c, t') = ProofContext.cert_def ctxt t
   698             let val (c, t') = ProofContext.cert_def ctxt t
   548             in ((if name = "" then Thm.def_name c else name, atts), [(t', (ps, []))]) end))
   699             in ((if name = "" then Thm.def_name c else name, atts), [(t', (ps, []))]) end))
   549       in ((ctxt', axs), []) end
   700       in ((ctxt', axs), []) end
   550   | activate_elem is_ext ((ctxt, axs), Notes facts) =
   701   | activate_elem is_ext ((ctxt, axs), Notes facts) =
   551       let val (ctxt', res) = ctxt |> ProofContext.note_thmss_i facts
   702       let
       
   703         (* extract context attributes *)
       
   704         val (Notes facts) = map_attrib_element_i snd (Notes facts);
       
   705         val (ctxt', res) = ctxt |> ProofContext.note_thmss_i facts
   552       in ((ctxt', axs), if is_ext then res else []) end;
   706       in ((ctxt', axs), if is_ext then res else []) end;
   553 
   707 
   554 fun activate_elems (((name, ps), axs), elems) ctxt =
   708 fun activate_elems (((name, ps), axs), elems) ctxt =
   555   let val ((ctxt', _), res) =
   709   let val ((ctxt', _), res) =
   556     foldl_map (activate_elem (name = "")) ((ProofContext.qualified true ctxt, axs), elems)
   710     foldl_map (activate_elem (name = "")) ((ProofContext.qualified true ctxt, axs), elems)
   589 fun intern_expr sg (Locale xname) = Locale (intern sg xname)
   743 fun intern_expr sg (Locale xname) = Locale (intern sg xname)
   590   | intern_expr sg (Merge exprs) = Merge (map (intern_expr sg) exprs)
   744   | intern_expr sg (Merge exprs) = Merge (map (intern_expr sg) exprs)
   591   | intern_expr sg (Rename (expr, xs)) = Rename (intern_expr sg expr, xs);
   745   | intern_expr sg (Rename (expr, xs)) = Rename (intern_expr sg expr, xs);
   592 
   746 
   593 
   747 
   594 (* attributes *)
       
   595 
       
   596 local
       
   597 
       
   598 fun read_att attrib (x, srcs) = (x, map attrib srcs)
       
   599 
       
   600 (* CB: Map attrib over
       
   601    * A context element: add attrib to attribute lists of assumptions,
       
   602      definitions and facts (on both sides for facts).
       
   603    * Locale expression: no effect. *)
       
   604 
       
   605 fun gen_map_attrib_elem _ (Fixes fixes) = Fixes fixes
       
   606   | gen_map_attrib_elem attrib (Assumes asms) = Assumes (map (apfst (read_att attrib)) asms)
       
   607   | gen_map_attrib_elem attrib (Defines defs) = Defines (map (apfst (read_att attrib)) defs)
       
   608   | gen_map_attrib_elem attrib (Notes facts) =
       
   609       Notes (map (apfst (read_att attrib) o apsnd (map (read_att attrib))) facts)
       
   610 
       
   611 fun gen_map_attrib_elem_expr attrib (Elem elem) = Elem (gen_map_attrib_elem attrib elem)
       
   612   | gen_map_attrib_elem_expr _ (Expr expr) = Expr expr;
       
   613 
       
   614 in
       
   615 
       
   616 val map_attrib_element = gen_map_attrib_elem;
       
   617 val map_attrib_element_i = gen_map_attrib_elem;
       
   618 val map_attrib_elem_or_expr = gen_map_attrib_elem_expr;
       
   619 val map_attrib_elem_or_expr_i = gen_map_attrib_elem_expr;
       
   620 
       
   621 end;
       
   622 
       
   623 
       
   624 (* parameters *)
   748 (* parameters *)
   625 
   749 
   626 local
   750 local
   627 
   751 
   628 fun prep_fixes prep_vars ctxt fixes =
   752 fun prep_fixes prep_vars ctxt fixes =
   642 (* CB: an internal (Int) locale element was either imported or included,
   766 (* CB: an internal (Int) locale element was either imported or included,
   643    an external (Ext) element appears directly in the locale. *)
   767    an external (Ext) element appears directly in the locale. *)
   644 
   768 
   645 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b;
   769 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b;
   646 
   770 
   647 (* CB: flatten (ids, expr) normalises expr (which is either a locale
   771 (* flatten (ids, expr) normalises expr (which is either a locale
   648    expression or a single context element) wrt.
   772    expression or a single context element) wrt.
   649    to the list ids of already accumulated identifiers.
   773    to the list ids of already accumulated identifiers.
   650    It returns (ids', elemss) where ids' is an extension of ids
   774    It returns (ids', elemss) where ids' is an extension of ids
   651    with identifiers generated for expr, and elemss is the list of
   775    with identifiers generated for expr, and elemss is the list of
   652    context elements generated from expr, decorated with additional
   776    context elements generated from expr.  For details, see flatten_expr.
   653    information (for expr it is the identifier, where parameters additionially
   777    Additionally, for a locale expression, the elems are grouped into a single
   654    contain type information (extracted from the locale record), for a Fixes
   778    Int; individual context elements are marked Ext.  In this case, the
   655    element, it is an identifier with name = "" and parameters with type
   779    identifier-like information of the element is as follows:
   656    information NONE, for other elements it is simply ("", [])).
   780    - for Fixes: (("", ps), []) where the ps have type info NONE
       
   781    - for other elements: (("", []), []).
   657    The implementation of activate_facts relies on identifier names being
   782    The implementation of activate_facts relies on identifier names being
   658    empty strings for external elements.
   783    empty strings for external elements.
   659 TODO: correct this comment wrt axioms. *)
   784 *)
   660 
   785 
   661 fun flatten _ (ids, Elem (Fixes fixes)) =
   786 fun flatten _ (ids, Elem (Fixes fixes)) =
   662       (ids, [((("", map (rpair NONE o #1) fixes), []), Ext (Fixes fixes))])
   787       (ids, [((("", map (rpair NONE o #1) fixes), []), Ext (Fixes fixes))])
   663   | flatten _ (ids, Elem elem) = (ids, [((("", []), []), Ext elem)])
   788   | flatten _ (ids, Elem elem) = (ids, [((("", []), []), Ext elem)])
   664   | flatten (ctxt, prep_expr) (ids, Expr expr) =
   789   | flatten (ctxt, prep_expr) (ids, Expr expr) =
   709 
   834 
   710 end;
   835 end;
   711 
   836 
   712 local
   837 local
   713 
   838 
   714 (* CB: following code (norm_term, abstract_term, abstract_thm, bind_def)
   839 (* CB: normalise Assumes and Defines wrt. previous definitions *)
   715    used in eval_text for defines elements. *)
       
   716 
   840 
   717 val norm_term = Envir.beta_norm oo Term.subst_atomic;
   841 val norm_term = Envir.beta_norm oo Term.subst_atomic;
       
   842 
       
   843 (* CB: following code (abstract_term, abstract_thm, bind_def)
       
   844    used in eval_text for Defines elements. *)
   718 
   845 
   719 fun abstract_term eq =    (*assumes well-formedness according to ProofContext.cert_def*)
   846 fun abstract_term eq =    (*assumes well-formedness according to ProofContext.cert_def*)
   720   let
   847   let
   721     val body = Term.strip_all_body eq;
   848     val body = Term.strip_all_body eq;
   722     val vars = map Free (Term.rename_wrt_term body (Term.strip_all_vars eq));
   849     val vars = map Free (Term.rename_wrt_term body (Term.strip_all_vars eq));
   995 
  1122 
   996     val {predicate = (_, axioms), params = (ps, _), ...} =
  1123     val {predicate = (_, axioms), params = (ps, _), ...} =
   997       the_locale thy (intern sign loc_name);
  1124       the_locale thy (intern sign loc_name);
   998     val fixed_params = param_types ps;
  1125     val fixed_params = param_types ps;
   999     val init = ProofContext.init thy;
  1126     val init = ProofContext.init thy;
  1000     val (ids, raw_elemss) =
  1127     val (_, raw_elemss) =
  1001           flatten (init, intern_expr sign) ([], Expr (Locale loc_name));
  1128           flatten (init, intern_expr sign) ([], Expr (Locale loc_name));
  1002     val ((parms, all_elemss, concl),
  1129     val ((parms, all_elemss, concl),
  1003          (spec as (_, (ints, _)), (xs, env, defs))) =
  1130          (spec as (_, (ints, _)), (xs, env, defs))) =
  1004       read_elemss false (* do_close *) init
  1131       read_elemss false (* do_close *) init
  1005         fixed_params (* could also put [] here??? *) raw_elemss
  1132         fixed_params (* could also put [] here??? *) raw_elemss
  1125              | s => NameSpace.append prfx s);
  1252              | s => NameSpace.append prfx s);
  1126 
  1253 
  1127     fun inst_elem (ctxt, (Ext _)) = ctxt
  1254     fun inst_elem (ctxt, (Ext _)) = ctxt
  1128       | inst_elem (ctxt, (Int (Notes facts))) =
  1255       | inst_elem (ctxt, (Int (Notes facts))) =
  1129               (* instantiate fact *)
  1256               (* instantiate fact *)
  1130           let val facts' =
  1257           let (* extract context attributes *)
       
  1258               val (Notes facts) = map_attrib_element_i snd (Notes facts);
       
  1259               val facts' =
  1131                 map (apsnd (map (apfst (map inst_thm')))) facts
  1260                 map (apsnd (map (apfst (map inst_thm')))) facts
  1132 		handle THM (msg, n, thms) => error ("Exception THM " ^
  1261 		handle THM (msg, n, thms) => error ("Exception THM " ^
  1133 		  string_of_int n ^ " raised\n" ^
  1262 		  string_of_int n ^ " raised\n" ^
  1134 		  "Note: instantiate does not support old-style locales \
  1263 		  "Note: instantiate does not support old-style locales \
  1135                   \declared with (open)\n" ^ msg ^ "\n" ^
  1264                   \declared with (open)\n" ^ msg ^ "\n" ^
  1208   |> Theory.add_path (Sign.base_name name)
  1337   |> Theory.add_path (Sign.base_name name)
  1209   |> PureThy.note_thmss_i (Drule.kind kind) args
  1338   |> PureThy.note_thmss_i (Drule.kind kind) args
  1210   |>> hide_bound_names (map (#1 o #1) args)
  1339   |>> hide_bound_names (map (#1 o #1) args)
  1211   |>> Theory.parent_path;
  1340   |>> Theory.parent_path;
  1212 
  1341 
       
  1342 fun note_thms_qualified' kind (arg as ((name, atts), thms)) thy =
       
  1343   let
       
  1344     val qname = NameSpace.unpack name
       
  1345   in
       
  1346     if length qname <= 1
       
  1347     then PureThy.note_thmss_i kind [arg] thy
       
  1348   else let val (prfx, n) = split_last qname
       
  1349     in thy
       
  1350       |> Theory.add_path (NameSpace.pack prfx)
       
  1351       |> PureThy.note_thmss_i kind [((n, atts), thms)]
       
  1352       |>> funpow (length prfx) Theory.parent_path
       
  1353     end
       
  1354   end;
       
  1355 
       
  1356 (* prfx may be empty (not yet), names (in args) may be qualified *)
       
  1357 
       
  1358 fun note_thmss_qualified' kind prfx args thy =
       
  1359   thy
       
  1360   |> Theory.add_path (Sign.base_name prfx)
       
  1361   |> (fn thy => Library.foldl (fn ((thy, res), arg) =>
       
  1362         let val (thy', res') = note_thms_qualified' (Drule.kind kind) arg thy
       
  1363         in (thy', res @ res') end) ((thy, []), args))
       
  1364 (*  |>> hide_bound_names (map (#1 o #1) args) *)
       
  1365   |>> Theory.parent_path;
       
  1366 
  1213 fun smart_note_thmss kind NONE = PureThy.note_thmss_i (Drule.kind kind)
  1367 fun smart_note_thmss kind NONE = PureThy.note_thmss_i (Drule.kind kind)
  1214   | smart_note_thmss kind (SOME (loc, _)) = note_thmss_qualified kind loc;
  1368   | smart_note_thmss kind (SOME (loc, _)) = note_thmss_qualified kind loc;
  1215   (* CB: only used in Proof.finish_global. *)
  1369   (* CB: only used in Proof.finish_global. *)
  1216 
  1370 
  1217 end;
  1371 end;
  1231     val thy_ctxt = ProofContext.init thy;
  1385     val thy_ctxt = ProofContext.init thy;
  1232     val loc = prep_locale (Theory.sign_of thy) raw_loc;
  1386     val loc = prep_locale (Theory.sign_of thy) raw_loc;
  1233     val (_, (stmt, _), loc_ctxt, _, _) =
  1387     val (_, (stmt, _), loc_ctxt, _, _) =
  1234       cert_context_statement (SOME loc) [] [] thy_ctxt;
  1388       cert_context_statement (SOME loc) [] [] thy_ctxt;
  1235     val args = map (apsnd (map (apfst (get_thms loc_ctxt)))) raw_args;
  1389     val args = map (apsnd (map (apfst (get_thms loc_ctxt)))) raw_args;
       
  1390     (* convert multi attributes to context attributes for
       
  1391        ProofContext.note_thmss_i *)
       
  1392     val args'' = args
       
  1393           |> map (apfst (apsnd (map snd)))
       
  1394           |> map (apsnd (map (apsnd (map snd))));
  1236     val export = ProofContext.export_standard stmt loc_ctxt thy_ctxt;
  1395     val export = ProofContext.export_standard stmt loc_ctxt thy_ctxt;
  1237     val results = map (map export o #2) (#2 (ProofContext.note_thmss_i args loc_ctxt));
  1396     val results = map (map export o #2) (#2 (ProofContext.note_thmss_i args'' loc_ctxt));
  1238     val args' = map (rpair [] o #1 o #1) args ~~ map (single o Thm.no_attributes) results;
  1397     val args' = map (rpair [] o #1 o #1) args ~~ map (single o Thm.no_attributes) results;
  1239   in
  1398   in
  1240     thy
  1399     thy
  1241     |> put_facts loc args
  1400     |> put_facts loc args
  1242     |> note_thmss_qualified kind loc args'
  1401     |> note_thmss_qualified kind loc args'
  1262 
  1421 
  1263 end;
  1422 end;
  1264 
  1423 
  1265 
  1424 
  1266 (* predicate text *)
  1425 (* predicate text *)
  1267 (* CB: generate locale predicates (and delta predicates) *)
  1426 (* CB: generate locale predicates and delta predicates *)
  1268 
  1427 
  1269 local
  1428 local
  1270 
  1429 
  1271 (* introN: name of theorems for introduction rules of locale and
  1430 (* introN: name of theorems for introduction rules of locale and
  1272      delta predicates;
  1431      delta predicates;
  1401 (* add_locale(_i) *)
  1560 (* add_locale(_i) *)
  1402 
  1561 
  1403 local
  1562 local
  1404 
  1563 
  1405 fun gen_add_locale prep_ctxt prep_expr do_pred bname raw_import raw_body thy =
  1564 fun gen_add_locale prep_ctxt prep_expr do_pred bname raw_import raw_body thy =
  1406   (* CB: do_pred = false means old-style locale, declared with (open).
  1565   (* CB: do_pred controls generation of predicates.
  1407      Old-style locales don't define predicates. *)
  1566          true -> with, false -> without predicates. *)
  1408   let
  1567   let
  1409     val sign = Theory.sign_of thy;
  1568     val sign = Theory.sign_of thy;
  1410     val name = Sign.full_name sign bname;
  1569     val name = Sign.full_name sign bname;
  1411     val _ = conditional (isSome (get_locale thy name)) (fn () =>
  1570     val _ = conditional (isSome (get_locale thy name)) (fn () =>
  1412       error ("Duplicate definition of locale " ^ quote name));
  1571       error ("Duplicate definition of locale " ^ quote name));
  1449 
  1608 
  1450 end;
  1609 end;
  1451 
  1610 
  1452 
  1611 
  1453 
  1612 
       
  1613 (** Registration commands **)
       
  1614 
       
  1615 local
       
  1616 
       
  1617 (** instantiate free vars **)
       
  1618 
       
  1619 (* instantiate TFrees *)
       
  1620 
       
  1621 fun tinst_type tinst T = if Symtab.is_empty tinst
       
  1622       then T
       
  1623       else Term.map_type_tfree
       
  1624         (fn (v as (x, _)) => getOpt (Symtab.lookup (tinst, x), (TFree v))) T;
       
  1625 
       
  1626 fun tinst_term tinst t = if Symtab.is_empty tinst
       
  1627       then t
       
  1628       else Term.map_term_types (tinst_type tinst) t;
       
  1629 
       
  1630 fun tinst_thm sg tinst thm = if Symtab.is_empty tinst
       
  1631       then thm
       
  1632       else let
       
  1633           val cert = Thm.cterm_of sg;
       
  1634           val certT = Thm.ctyp_of sg;
       
  1635           val {hyps, prop, ...} = Thm.rep_thm thm;
       
  1636           val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps);
       
  1637           val tinst' = Symtab.dest tinst |>
       
  1638                 List.filter (fn (a, _) => a mem_string tfrees);
       
  1639         in
       
  1640           if null tinst' then thm
       
  1641           else thm |> Drule.implies_intr_list (map cert hyps)
       
  1642             |> Drule.tvars_intr_list (map #1 tinst')
       
  1643             |> (fn (th, al) => th |> Thm.instantiate
       
  1644                 ((map (fn (a, T) => (valOf (assoc (al, a)), certT T)) tinst'),
       
  1645                   []))
       
  1646             |> (fn th => Drule.implies_elim_list th
       
  1647                  (map (Thm.assume o cert o tinst_term tinst) hyps))
       
  1648         end;
       
  1649 
       
  1650 fun tinst_elem _ tinst (Fixes fixes) =
       
  1651       Fixes (map (fn (x, T, mx) => (x, Option.map (tinst_type tinst) T, mx)) fixes)
       
  1652   | tinst_elem _ tinst (Assumes asms) =
       
  1653       Assumes (map (apsnd (map (fn (t, (ps, qs)) =>
       
  1654         (tinst_term tinst t,
       
  1655           (map (tinst_term tinst) ps, map (tinst_term tinst) qs))))) asms)
       
  1656   | tinst_elem _ tinst (Defines defs) =
       
  1657       Defines (map (apsnd (fn (t, ps) =>
       
  1658         (tinst_term tinst t, map (tinst_term tinst) ps))) defs)
       
  1659   | tinst_elem sg tinst (Notes facts) =
       
  1660       Notes (map (apsnd (map (apfst (map (tinst_thm sg tinst))))) facts);
       
  1661 
       
  1662 (* instantiate TFrees and Frees *)
       
  1663 
       
  1664 fun inst_term (inst, tinst) = if Symtab.is_empty inst
       
  1665       then tinst_term tinst
       
  1666       else (* instantiate terms and types simultaneously *)
       
  1667         let
       
  1668           fun instf (Const (x, T)) = Const (x, tinst_type tinst T)
       
  1669             | instf (Free (x, T)) = (case Symtab.lookup (inst, x) of
       
  1670                  NONE => Free (x, tinst_type tinst T)
       
  1671                | SOME t => t)
       
  1672             | instf (Var (xi, T)) = Var (xi, tinst_type tinst T)
       
  1673             | instf (b as Bound _) = b
       
  1674             | instf (Abs (x, T, t)) = Abs (x, tinst_type tinst T, instf t)
       
  1675             | instf (s $ t) = instf s $ instf t
       
  1676         in instf end;
       
  1677 
       
  1678 fun inst_thm sg (inst, tinst) thm = if Symtab.is_empty inst
       
  1679       then tinst_thm sg tinst thm
       
  1680       else let
       
  1681           val cert = Thm.cterm_of sg;
       
  1682           val certT = Thm.ctyp_of sg;
       
  1683           val {hyps, prop, ...} = Thm.rep_thm thm;
       
  1684           (* type instantiations *)
       
  1685           val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps);
       
  1686           val tinst' = Symtab.dest tinst |>
       
  1687                 List.filter (fn (a, _) => a mem_string tfrees);
       
  1688           (* term instantiations;
       
  1689              note: lhss are type instantiated, because
       
  1690                    type insts will be done first*)
       
  1691           val frees = foldr Term.add_term_frees [] (prop :: hyps);
       
  1692           val inst' = Symtab.dest inst |>
       
  1693                 List.mapPartial (fn (a, t) =>
       
  1694                   get_first (fn (Free (x, T)) => 
       
  1695                     if a = x then SOME (Free (x, tinst_type tinst T), t)
       
  1696                     else NONE) frees);
       
  1697         in
       
  1698           if null tinst' andalso null inst' then tinst_thm sg tinst thm
       
  1699           else thm |> Drule.implies_intr_list (map cert hyps)
       
  1700             |> Drule.tvars_intr_list (map #1 tinst')
       
  1701             |> (fn (th, al) => th |> Thm.instantiate
       
  1702                 ((map (fn (a, T) => (valOf (assoc (al, a)), certT T)) tinst'),
       
  1703                   []))
       
  1704             |> Drule.forall_intr_list (map (cert o #1) inst')
       
  1705             |> Drule.forall_elim_list (map (cert o #2) inst') 
       
  1706             |> (fn th => Drule.implies_elim_list th
       
  1707                  (map (Thm.assume o cert o inst_term (inst, tinst)) hyps))
       
  1708         end;
       
  1709 
       
  1710 fun inst_elem _ (_, tinst) (Fixes fixes) =
       
  1711       Fixes (map (fn (x, T, mx) => (x, Option.map (tinst_type tinst) T, mx)) fixes)
       
  1712   | inst_elem _ inst (Assumes asms) =
       
  1713       Assumes (map (apsnd (map (fn (t, (ps, qs)) =>
       
  1714         (inst_term inst t,
       
  1715           (map (inst_term inst) ps, map (inst_term inst) qs))))) asms)
       
  1716   | inst_elem _ inst (Defines defs) =
       
  1717       Defines (map (apsnd (fn (t, ps) =>
       
  1718         (inst_term inst t, map (inst_term inst) ps))) defs)
       
  1719   | inst_elem sg inst (Notes facts) =
       
  1720       Notes (map (apsnd (map (apfst (map (inst_thm sg inst))))) facts);
       
  1721 
       
  1722 fun inst_elems sign inst ((n, ps), elems) =
       
  1723       ((n, map (inst_term inst) ps), map (inst_elem sign inst) elems);
       
  1724 
       
  1725 (* extract proof obligations (assms and defs) from elements *)
       
  1726 
       
  1727 (* check if defining equation has become t == t, these are dropped
       
  1728    in extract_asms_elem, as they lead to trivial proof obligations *)
       
  1729 (* currently disabled *)
       
  1730 fun check_def (_, (def, _)) = SOME def;
       
  1731 (*
       
  1732 fun check_def (_, (def, _)) =
       
  1733       if def |> Logic.dest_equals |> op aconv
       
  1734       then NONE else SOME def;
       
  1735 *)
       
  1736 
       
  1737 fun extract_asms_elem (ts, Fixes _) = ts
       
  1738   | extract_asms_elem (ts, Assumes asms) =
       
  1739       ts @ List.concat (map (fn (_, ams) => map (fn (t, _) => t) ams) asms)
       
  1740   | extract_asms_elem (ts, Defines defs) =
       
  1741       ts @ List.mapPartial check_def defs
       
  1742   | extract_asms_elem (ts, Notes _) = ts;
       
  1743 
       
  1744 fun extract_asms_elems (id, elems) =
       
  1745       (id, Library.foldl extract_asms_elem ([], elems));
       
  1746 
       
  1747 fun extract_asms_elemss elemss =
       
  1748       map extract_asms_elems elemss;
       
  1749 
       
  1750 (* add registration, without theorems, to theory *)
       
  1751 
       
  1752 fun prep_reg_global attn (thy, (id, _)) =
       
  1753       global_put_registration id attn thy;
       
  1754 
       
  1755 (* activate instantiated facts in theory *)
       
  1756 
       
  1757 fun activate_facts_elem _ _ (thy, Fixes _) = thy
       
  1758   | activate_facts_elem _ _ (thy, Assumes _) = thy
       
  1759   | activate_facts_elem _ _ (thy, Defines _) = thy
       
  1760   | activate_facts_elem disch (prfx, atts) (thy, Notes facts) =
       
  1761       let
       
  1762         (* extract theory attributes *)
       
  1763         val (Notes facts) = map_attrib_element_i fst (Notes facts);
       
  1764         val facts' = map (apfst (apsnd (fn a => a @ atts))) facts;
       
  1765         val facts'' = map (apsnd (map (apfst (map disch)))) facts';
       
  1766       in
       
  1767         fst (note_thmss_qualified' "" prfx facts thy)
       
  1768       end;
       
  1769 
       
  1770 fun activate_facts_elems disch (thy, (id, elems)) =
       
  1771       let
       
  1772         val ((prfx, atts2), _) = valOf (global_get_registration thy id)
       
  1773           handle Option => error ("(internal) unknown registration of " ^
       
  1774             quote (fst id) ^ " while activating facts.");
       
  1775       in
       
  1776         Library.foldl (activate_facts_elem disch (prfx, atts2)) (thy, elems)
       
  1777       end;
       
  1778 
       
  1779 fun activate_facts_elemss all_elemss new_elemss thy =
       
  1780       let
       
  1781         val prems = List.concat (List.mapPartial (fn (id, _) =>
       
  1782               Option.map snd (global_get_registration thy id)
       
  1783                 handle Option => error ("(internal) unknown registration of " ^
       
  1784                   quote (fst id) ^ " while activating facts.")) all_elemss);
       
  1785         fun disch thm = let
       
  1786           in Drule.satisfy_hyps prems thm end;
       
  1787       in Library.foldl (activate_facts_elems disch) (thy, new_elemss) end;
       
  1788 
       
  1789 in
       
  1790 
       
  1791 fun prep_registration attn expr insts thy =
       
  1792   let
       
  1793     val ctxt = ProofContext.init thy;
       
  1794     val sign = Theory.sign_of thy;
       
  1795     val tsig = Sign.tsig_of sign;
       
  1796 
       
  1797     val (ids, raw_elemss) =
       
  1798           flatten (ctxt, intern_expr sign) ([], Expr expr);
       
  1799     val do_close = false;  (* effect unknown *)
       
  1800     val ((parms, all_elemss, _), (spec, (xs, defs, _))) =
       
  1801           read_elemss do_close ctxt [] raw_elemss [];
       
  1802 
       
  1803 
       
  1804     (** compute instantiation **)
       
  1805 
       
  1806     (* user input *)
       
  1807     val insts = if length parms < length insts
       
  1808          then error "More arguments than parameters in instantiation."
       
  1809          else insts @ replicate (length parms - length insts) NONE;
       
  1810     val (ps, pTs) = split_list parms;
       
  1811     val pvTs = map Type.varifyT pTs;
       
  1812     val given = List.mapPartial (fn (_, (NONE, _)) => NONE
       
  1813          | (x, (SOME inst, T)) => SOME (x, (inst, T))) (ps ~~ (insts ~~ pvTs));
       
  1814     val (given_ps, given_insts) = split_list given;
       
  1815     val tvars = foldr Term.add_typ_tvars [] pvTs;
       
  1816     val used = foldr Term.add_typ_varnames [] pvTs;
       
  1817     fun sorts (a, i) = assoc (tvars, (a, i));
       
  1818     val (tvs, tvinst) = Sign.read_def_terms (sign, K NONE, sorts) used true
       
  1819          given_insts;
       
  1820     val tinst = Symtab.make (map (fn ((x, 0), T) => (x, Type.unvarifyT T)
       
  1821                   | ((_, n), _) => error "Var in prep_registration") tvinst);
       
  1822     val inst = Symtab.make (given_ps ~~ map Logic.unvarify tvs);
       
  1823 
       
  1824     (* defined params without user input *)
       
  1825     val not_given = List.mapPartial (fn (x, (NONE, T)) => SOME (x, T)
       
  1826          | (_, (SOME _, _)) => NONE) (ps ~~ (insts ~~ pTs));
       
  1827     fun add_def ((inst, tinst), (p, pT)) =
       
  1828       let
       
  1829         val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of
       
  1830                NONE => error ("Instance missing for parameter " ^ quote p)
       
  1831              | SOME (Free (_, T), t) => (t, T);
       
  1832         val d = t |> inst_term (inst, tinst) |> Envir.beta_norm;
       
  1833       in (Symtab.update_new ((p, d), inst), tinst) end;
       
  1834     val (inst, tinst) = Library.foldl add_def ((inst, tinst), not_given);
       
  1835   
       
  1836 
       
  1837     (** compute proof obligations **)
       
  1838 
       
  1839     (* restore small ids *)
       
  1840     val ids' = map (fn ((n, ps), _) =>
       
  1841           (n, map (fn p => Free (p, valOf (assoc (parms, p)))) ps)) ids;
       
  1842 
       
  1843     (* instantiate ids and elements *)
       
  1844     val inst_elemss = map
       
  1845           (fn (id, (_, elems)) => inst_elems sign (inst, tinst) (id, 
       
  1846             map (fn Int e => e) elems)) 
       
  1847           (ids' ~~ all_elemss);
       
  1848 
       
  1849 (*
       
  1850     (* varify ids, props are varified after they are proved *)
       
  1851     val inst_elemss' = map (fn ((n, ps), elems) =>
       
  1852           ((n, map Logic.varify ps), elems)) inst_elemss;
       
  1853 *)
       
  1854 
       
  1855     (* remove fragments already registered with theory *)
       
  1856     val new_inst_elemss = List.filter (fn (id, _) =>
       
  1857           is_none (global_get_registration thy id)) inst_elemss;
       
  1858 
       
  1859 
       
  1860     val propss = extract_asms_elemss new_inst_elemss;
       
  1861 
       
  1862 
       
  1863     (** add registrations to theory,
       
  1864         without theorems, these are added after the proof **)
       
  1865 
       
  1866     val thy' = Library.foldl (prep_reg_global attn) (thy, new_inst_elemss);
       
  1867 
       
  1868   in (thy', propss, activate_facts_elemss inst_elemss new_inst_elemss) end;
       
  1869 
       
  1870 
       
  1871 (* Add registrations and theorems to theory context *)
       
  1872 
       
  1873 val global_activate_thm = global_put_registration_thm
       
  1874 
       
  1875 end;  (* local *)
       
  1876 
       
  1877 
       
  1878 
  1454 (** locale theory setup **)
  1879 (** locale theory setup **)
  1455 
  1880 
  1456 val setup =
  1881 val setup =
  1457  [LocalesData.init,
  1882  [LocalesData.init,
  1458   add_locale_i true "var" empty [Fixes [(Syntax.internal "x", NONE, SOME Syntax.NoSyn)]],
  1883   add_locale_i true "var" empty [Fixes [(Syntax.internal "x", NONE, SOME Syntax.NoSyn)]],