src/Pure/Isar/locale.ML
changeset 18137 cb916659c89b
parent 18123 1bb572e8cee9
child 18190 b7748c77562f
equal deleted inserted replaced
18136:51385f358b53 18137:cb916659c89b
    30   (implicit locale expressions generated by multiple registrations)
    30   (implicit locale expressions generated by multiple registrations)
    31 *)
    31 *)
    32 
    32 
    33 signature LOCALE =
    33 signature LOCALE =
    34 sig
    34 sig
    35   type context (*= Proof.context*)
       
    36   datatype ('typ, 'term, 'fact) elem =
       
    37     Fixes of (string * 'typ option * mixfix option) list |
       
    38     Constrains of (string * 'typ) list |
       
    39     Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
       
    40     Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
       
    41     Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list
       
    42   type element (*= (string, string, thmref) elem*)
       
    43   type element_i (*= (typ, term, thm list) elem*)
       
    44   datatype expr =
    35   datatype expr =
    45     Locale of string |
    36     Locale of string |
    46     Rename of expr * (string * mixfix option) option list |
    37     Rename of expr * (string * mixfix option) option list |
    47     Merge of expr list
    38     Merge of expr list
    48   val empty: expr
    39   val empty: expr
    49   datatype 'a elem_expr = Elem of 'a | Expr of expr
    40   datatype 'a element = Elem of 'a | Expr of expr
    50 
    41 
    51   (* Abstract interface to locales *)
    42   (* Abstract interface to locales *)
    52   type locale
    43   type locale
    53   val intern: theory -> xstring -> string
    44   val intern: theory -> xstring -> string
    54   val extern: theory -> string -> xstring
    45   val extern: theory -> string -> xstring
    55   val the_locale: theory -> string -> locale
    46   val the_locale: theory -> string -> locale
    56   val intern_attrib_elem: theory ->
       
    57     ('typ, 'term, 'fact) elem -> ('typ, 'term, 'fact) elem
       
    58   val intern_attrib_elem_expr: theory ->
       
    59     ('typ, 'term, 'fact) elem elem_expr -> ('typ, 'term, 'fact) elem elem_expr
       
    60 
    47 
    61   (* Processing of locale statements *)
    48   (* Processing of locale statements *)
    62   val read_context_statement: xstring option -> element elem_expr list ->
    49   val read_context_statement: xstring option -> Element.context element list ->
    63     (string * (string list * string list)) list list -> context ->
    50     (string * (string list * string list)) list list -> ProofContext.context ->
    64     string option * (cterm list * cterm list) * context * context * 
    51     string option * (cterm list * cterm list) * ProofContext.context * ProofContext.context *
    65       (term * (term list * term list)) list list
    52       (term * (term list * term list)) list list
    66   val cert_context_statement: string option -> element_i elem_expr list ->
    53   val cert_context_statement: string option -> Element.context_i element list ->
    67     (term * (term list * term list)) list list -> context ->
    54     (term * (term list * term list)) list list -> ProofContext.context ->
    68     string option * (cterm list * cterm list) * context * context *
    55     string option * (cterm list * cterm list) * ProofContext.context * ProofContext.context *
    69       (term * (term list * term list)) list list
    56       (term * (term list * term list)) list list
    70 
    57 
    71   (* Diagnostic functions *)
    58   (* Diagnostic functions *)
    72   val print_locales: theory -> unit
    59   val print_locales: theory -> unit
    73   val print_locale: theory -> bool -> expr -> element list -> unit
    60   val print_locale: theory -> bool -> expr -> Element.context list -> unit
    74   val print_global_registrations: bool -> string -> theory -> unit
    61   val print_global_registrations: bool -> string -> theory -> unit
    75   val print_local_registrations': bool -> string -> context -> unit
    62   val print_local_registrations': bool -> string -> ProofContext.context -> unit
    76   val print_local_registrations: bool -> string -> context -> unit
    63   val print_local_registrations: bool -> string -> ProofContext.context -> unit
       
    64 
       
    65   val add_locale_context: bool -> bstring -> expr -> Element.context list -> theory
       
    66     -> (Element.context_i list * ProofContext.context) * theory
       
    67   val add_locale_context_i: bool -> bstring -> expr -> Element.context_i list -> theory
       
    68     -> (Element.context_i list * ProofContext.context) * theory
       
    69   val add_locale: bool -> bstring -> expr -> Element.context list -> theory -> theory
       
    70   val add_locale_i: bool -> bstring -> expr -> Element.context_i list -> theory -> theory
    77 
    71 
    78   (* Storing results *)
    72   (* Storing results *)
    79   val add_locale_context: bool -> bstring -> expr -> element list -> theory
       
    80     -> (element_i list * ProofContext.context) * theory
       
    81   val add_locale_context_i: bool -> bstring -> expr -> element_i list -> theory
       
    82     -> (element_i list * ProofContext.context) * theory
       
    83   val add_locale: bool -> bstring -> expr -> element list -> theory -> theory
       
    84   val add_locale_i: bool -> bstring -> expr -> element_i list -> theory -> theory
       
    85   val smart_note_thmss: string -> string option ->
    73   val smart_note_thmss: string -> string option ->
    86     ((bstring * theory attribute list) * (thm list * theory attribute list) list) list ->
    74     ((bstring * theory attribute list) * (thm list * theory attribute list) list) list ->
    87     theory -> theory * (bstring * thm list) list
    75     theory -> theory * (bstring * thm list) list
    88   val note_thmss: string -> xstring ->
    76   val note_thmss: string -> xstring ->
    89     ((bstring * Attrib.src list) * (thmref * Attrib.src list) list) list ->
    77     ((bstring * Attrib.src list) * (thmref * Attrib.src list) list) list ->
    90     theory -> (theory * ProofContext.context) * (bstring * thm list) list
    78     theory -> (theory * ProofContext.context) * (bstring * thm list) list
    91   val note_thmss_i: string -> string ->
    79   val note_thmss_i: string -> string ->
    92     ((bstring * Attrib.src list) * (thm list * Attrib.src list) list) list ->
    80     ((bstring * Attrib.src list) * (thm list * Attrib.src list) list) list ->
    93     theory -> (theory * ProofContext.context) * (bstring * thm list) list
    81     theory -> (theory * ProofContext.context) * (bstring * thm list) list
       
    82 
    94   val theorem: string -> Method.text option -> (thm list list -> theory -> theory) ->
    83   val theorem: string -> Method.text option -> (thm list list -> theory -> theory) ->
    95     string * Attrib.src list -> element elem_expr list ->
    84     string * Attrib.src list -> Element.context element list ->
    96     ((string * Attrib.src list) * (string * (string list * string list)) list) list ->
    85     ((string * Attrib.src list) * (string * (string list * string list)) list) list ->
    97     theory -> Proof.state
    86     theory -> Proof.state
    98   val theorem_i: string -> Method.text option -> (thm list list -> theory -> theory) ->
    87   val theorem_i: string -> Method.text option -> (thm list list -> theory -> theory) ->
    99     string * theory attribute list -> element_i elem_expr list ->
    88     string * theory attribute list -> Element.context_i element list ->
   100     ((string * theory attribute list) * (term * (term list * term list)) list) list ->
    89     ((string * theory attribute list) * (term * (term list * term list)) list) list ->
   101     theory -> Proof.state
    90     theory -> Proof.state
   102   val theorem_in_locale: string -> Method.text option ->
    91   val theorem_in_locale: string -> Method.text option ->
   103     (thm list list -> thm list list -> theory -> theory) ->
    92     (thm list list -> thm list list -> theory -> theory) ->
   104     xstring -> string * Attrib.src list -> element elem_expr list ->
    93     xstring -> string * Attrib.src list -> Element.context element list ->
   105     ((string * Attrib.src list) * (string * (string list * string list)) list) list ->
    94     ((string * Attrib.src list) * (string * (string list * string list)) list) list ->
   106     theory -> Proof.state
    95     theory -> Proof.state
   107   val theorem_in_locale_i: string -> Method.text option ->
    96   val theorem_in_locale_i: string -> Method.text option ->
   108     (thm list list -> thm list list -> theory -> theory) ->
    97     (thm list list -> thm list list -> theory -> theory) ->
   109     string -> string * Attrib.src list -> element_i elem_expr list ->
    98     string -> string * Attrib.src list -> Element.context_i element list ->
   110     ((string * Attrib.src list) * (term * (term list * term list)) list) list ->
    99     ((string * Attrib.src list) * (term * (term list * term list)) list) list ->
   111     theory -> Proof.state
   100     theory -> Proof.state
   112   val smart_theorem: string -> xstring option ->
   101   val smart_theorem: string -> xstring option ->
   113     string * Attrib.src list -> element elem_expr list ->
   102     string * Attrib.src list -> Element.context element list ->
   114     ((string * Attrib.src list) * (string * (string list * string list)) list) list ->
   103     ((string * Attrib.src list) * (string * (string list * string list)) list) list ->
   115     theory -> Proof.state
   104     theory -> Proof.state
   116   val interpretation: string * Attrib.src list -> expr -> string option list ->
   105   val interpretation: string * Attrib.src list -> expr -> string option list ->
   117     theory -> Proof.state
   106     theory -> Proof.state
   118   val interpretation_in_locale: xstring * expr -> theory -> Proof.state
   107   val interpretation_in_locale: xstring * expr -> theory -> Proof.state
   124 struct
   113 struct
   125 
   114 
   126 
   115 
   127 (** locale elements and expressions **)
   116 (** locale elements and expressions **)
   128 
   117 
   129 type context = ProofContext.context;
   118 datatype ctxt = datatype Element.ctxt;
   130 
       
   131 datatype ('typ, 'term, 'fact) elem =
       
   132   Fixes of (string * 'typ option * mixfix option) list |
       
   133   Constrains of (string * 'typ) list |
       
   134   Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
       
   135   Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
       
   136   Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list;
       
   137 
       
   138 type element = (string, string, thmref) elem;
       
   139 type element_i = (typ, term, thm list) elem;
       
   140 
   119 
   141 datatype expr =
   120 datatype expr =
   142   Locale of string |
   121   Locale of string |
   143   Rename of expr * (string * mixfix option) option list |
   122   Rename of expr * (string * mixfix option) option list |
   144   Merge of expr list;
   123   Merge of expr list;
   145 
   124 
   146 val empty = Merge [];
   125 val empty = Merge [];
   147 
   126 
   148 datatype 'a elem_expr =
   127 datatype 'a element =
   149   Elem of 'a | Expr of expr;
   128   Elem of 'a | Expr of expr;
       
   129 
       
   130 fun map_elem f (Elem e) = Elem (f e)
       
   131   | map_elem _ (Expr e) = Expr e;
   150 
   132 
   151 type witness = term * thm;  (*hypothesis as fact*)
   133 type witness = term * thm;  (*hypothesis as fact*)
   152 type locale =
   134 type locale =
   153  {predicate: cterm list * witness list,
   135  {predicate: cterm list * witness list,
   154     (* CB: For locales with "(open)" this entry is ([], []).
   136     (* CB: For locales with "(open)" this entry is ([], []).
   159        to the (assumed) locale parameters.  Axioms contains the projections
   141        to the (assumed) locale parameters.  Axioms contains the projections
   160        from the locale predicate to the normalised assumptions of the locale
   142        from the locale predicate to the normalised assumptions of the locale
   161        (cf. [1], normalisation of locale expressions.)
   143        (cf. [1], normalisation of locale expressions.)
   162     *)
   144     *)
   163   import: expr,                                       (*dynamic import*)
   145   import: expr,                                       (*dynamic import*)
   164   elems: (element_i * stamp) list,                    (*static content*)
   146   elems: (Element.context_i * stamp) list,            (*static content*)
   165   params: ((string * typ) * mixfix option) list * string list,
   147   params: ((string * typ) * mixfix option) list * string list,
   166                                                       (*all/local params*)
   148                                                       (*all/local params*)
   167   regs: ((string * string list) * (term * thm) list) list}
   149   regs: ((string * string list) * (term * thm) list) list}
   168     (* Registrations: indentifiers and witness theorems of locales interpreted
   150     (* Registrations: indentifiers and witness theorems of locales interpreted
   169        in the locale.
   151        in the locale.
   173 (* CB: an internal (Int) locale element was either imported or included,
   155 (* CB: an internal (Int) locale element was either imported or included,
   174    an external (Ext) element appears directly in the locale text. *)
   156    an external (Ext) element appears directly in the locale text. *)
   175 
   157 
   176 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b;
   158 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b;
   177 
   159 
   178 
       
   179 
       
   180 (** term and type instantiation, using symbol tables **)
       
   181 (** functions for term instantiation beta-reduce the result
       
   182     unless the instantiation table is empty (inst_tab_term)
       
   183     or the instantiation has no effect (inst_tab_thm) **)
       
   184 
       
   185 (* instantiate TFrees *)
       
   186 
       
   187 fun tinst_tab_type tinst T = if Symtab.is_empty tinst
       
   188       then T
       
   189       else Term.map_type_tfree
       
   190         (fn (v as (x, _)) => getOpt (Symtab.lookup tinst x, (TFree v))) T;
       
   191 
       
   192 fun tinst_tab_term tinst t = if Symtab.is_empty tinst
       
   193       then t
       
   194       else Term.map_term_types (tinst_tab_type tinst) t;
       
   195 
       
   196 fun tinst_tab_thm thy tinst thm = if Symtab.is_empty tinst
       
   197       then thm
       
   198       else let
       
   199           val cert = Thm.cterm_of thy;
       
   200           val certT = Thm.ctyp_of thy;
       
   201           val {hyps, prop, ...} = Thm.rep_thm thm;
       
   202           val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps);
       
   203           val tinst' = Symtab.dest tinst |>
       
   204                 List.filter (fn (a, _) => a mem_string tfrees);
       
   205         in
       
   206           if null tinst' then thm
       
   207           else thm |> Drule.implies_intr_list (map cert hyps)
       
   208             |> Drule.tvars_intr_list (map #1 tinst')
       
   209             |> (fn (th, al) => th |> Thm.instantiate
       
   210                 ((map (fn (a, T) => (certT (TVar ((the o AList.lookup (op =) al) a)), certT T)) tinst'),
       
   211                   []))
       
   212             |> (fn th => Drule.implies_elim_list th
       
   213                  (map (Thm.assume o cert o tinst_tab_term tinst) hyps))
       
   214         end;
       
   215 
       
   216 (* instantiate TFrees and Frees *)
       
   217 
       
   218 fun inst_tab_term (inst, tinst) = if Symtab.is_empty inst
       
   219       then tinst_tab_term tinst
       
   220       else (* instantiate terms and types simultaneously *)
       
   221         let
       
   222           fun instf (Const (x, T)) = Const (x, tinst_tab_type tinst T)
       
   223             | instf (Free (x, T)) = (case Symtab.lookup inst x of
       
   224                  NONE => Free (x, tinst_tab_type tinst T)
       
   225                | SOME t => t)
       
   226             | instf (Var (xi, T)) = Var (xi, tinst_tab_type tinst T)
       
   227             | instf (b as Bound _) = b
       
   228             | instf (Abs (x, T, t)) = Abs (x, tinst_tab_type tinst T, instf t)
       
   229             | instf (s $ t) = instf s $ instf t
       
   230         in Envir.beta_norm o instf end;
       
   231 
       
   232 fun inst_tab_thm thy (inst, tinst) thm = if Symtab.is_empty inst
       
   233       then tinst_tab_thm thy tinst thm
       
   234       else let
       
   235           val cert = Thm.cterm_of thy;
       
   236           val certT = Thm.ctyp_of thy;
       
   237           val {hyps, prop, ...} = Thm.rep_thm thm;
       
   238           (* type instantiations *)
       
   239           val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps);
       
   240           val tinst' = Symtab.dest tinst |>
       
   241                 List.filter (fn (a, _) => a mem_string tfrees);
       
   242           (* term instantiations;
       
   243              note: lhss are type instantiated, because
       
   244                    type insts will be done first*)
       
   245           val frees = foldr Term.add_term_frees [] (prop :: hyps);
       
   246           val inst' = Symtab.dest inst |>
       
   247                 List.mapPartial (fn (a, t) =>
       
   248                   get_first (fn (Free (x, T)) => 
       
   249                     if a = x then SOME (Free (x, tinst_tab_type tinst T), t)
       
   250                     else NONE) frees);
       
   251         in
       
   252           if null tinst' andalso null inst' then tinst_tab_thm thy tinst thm
       
   253           else thm |> Drule.implies_intr_list (map cert hyps)
       
   254             |> Drule.tvars_intr_list (map #1 tinst')
       
   255             |> (fn (th, al) => th |> Thm.instantiate
       
   256                 ((map (fn (a, T) => (certT (TVar ((the o AList.lookup (op =) al) a)), certT T)) tinst'),
       
   257                   []))
       
   258             |> Drule.forall_intr_list (map (cert o #1) inst')
       
   259             |> Drule.forall_elim_list (map (cert o #2) inst') 
       
   260             |> Drule.fconv_rule (Thm.beta_conversion true)
       
   261             |> (fn th => Drule.implies_elim_list th
       
   262                  (map (Thm.assume o cert o inst_tab_term (inst, tinst)) hyps))
       
   263         end;
       
   264 
       
   265 
       
   266 fun inst_tab_att thy (inst as (_, tinst)) =
       
   267     Args.map_values I (tinst_tab_type tinst)
       
   268     (inst_tab_term inst) (inst_tab_thm thy inst);
       
   269 
       
   270 fun inst_tab_atts thy inst = map (inst_tab_att thy inst);
       
   271 
   160 
   272 
   161 
   273 (** management of registrations in theories and proof contexts **)
   162 (** management of registrations in theories and proof contexts **)
   274 
   163 
   275 structure Registrations :
   164 structure Registrations :
   325             val inst' = inst |> Vartab.dest
   214             val inst' = inst |> Vartab.dest
   326                  |> map (fn ((x, 0), (_, t)) => (x, Logic.unvarify t))
   215                  |> map (fn ((x, 0), (_, t)) => (x, Logic.unvarify t))
   327                  |> Symtab.make;
   216                  |> Symtab.make;
   328           in
   217           in
   329             SOME (attn, map (fn (t, th) =>
   218             SOME (attn, map (fn (t, th) =>
   330               (inst_tab_term (inst', tinst') t, inst_tab_thm sign (inst', tinst') th)) thms)
   219              (Element.inst_term (tinst', inst') t,
       
   220               Element.inst_thm sign (tinst', inst') th)) thms)
   331           end)
   221           end)
   332     end;
   222     end;
   333 
   223 
   334   (* add registration if not subsumed by ones already present,
   224   (* add registration if not subsumed by ones already present,
   335      additionally returns registrations that are strictly subsumed *)
   225      additionally returns registrations that are strictly subsumed *)
   513       val {predicate, import, elems, params, regs} = the_locale thy name;
   403       val {predicate, import, elems, params, regs} = the_locale thy name;
   514       fun add (id', thms) =
   404       fun add (id', thms) =
   515           if id = id' then (id', thm :: thms) else (id', thms);
   405           if id = id' then (id', thm :: thms) else (id', thms);
   516     in
   406     in
   517       put_locale name {predicate = predicate, import = import,
   407       put_locale name {predicate = predicate, import = import,
   518 	elems = elems, params = params, regs = map add regs} thy
   408         elems = elems, params = params, regs = map add regs} thy
   519     end;
   409     end;
   520 
       
   521 (* import hierarchy
       
   522    implementation could be more efficient, eg. by maintaining a database
       
   523    of dependencies *)
       
   524 
       
   525 fun imports thy (upper, lower) =
       
   526   let
       
   527     fun imps (Locale name) low = (name = low) orelse
       
   528       (case get_locale thy name of
       
   529            NONE => false
       
   530          | SOME {import, ...} => imps import low)
       
   531       | imps (Rename (expr, _)) low = imps expr low
       
   532       | imps (Merge es) low = exists (fn e => imps e low) es;
       
   533   in
       
   534     imps (Locale (intern thy upper)) (intern thy lower)
       
   535   end;
       
   536 
   410 
   537 
   411 
   538 (* printing of registrations *)
   412 (* printing of registrations *)
   539 
   413 
   540 fun gen_print_registrations get_regs mk_ctxt msg show_wits loc thy_ctxt =
   414 fun gen_print_registrations get_regs mk_ctxt msg show_wits loc thy_ctxt =
   600       if forall (equal "" o #1) ids then msg
   474       if forall (equal "" o #1) ids then msg
   601       else msg ^ "\n" ^ Pretty.string_of (Pretty.block
   475       else msg ^ "\n" ^ Pretty.string_of (Pretty.block
   602         (Pretty.str "The error(s) above occurred in locale:" :: Pretty.brk 1 :: prt_ids));
   476         (Pretty.str "The error(s) above occurred in locale:" :: Pretty.brk 1 :: prt_ids));
   603   in raise ProofContext.CONTEXT (err_msg, ctxt) end;
   477   in raise ProofContext.CONTEXT (err_msg, ctxt) end;
   604 
   478 
   605 (* Version for identifiers with axioms *)
       
   606 
       
   607 fun err_in_locale' ctxt msg ids' = err_in_locale ctxt msg (map fst ids');
   479 fun err_in_locale' ctxt msg ids' = err_in_locale ctxt msg (map fst ids');
   608 
   480 
   609 
   481 
   610 (** primitives **)
   482 
   611 
   483 (** witnesses -- protected facts **)
   612 (* map elements *)
       
   613 
       
   614 fun map_elem {name, var, typ, term, fact, attrib} =
       
   615   fn Fixes fixes => Fixes (fixes |> map (fn (x, T, mx) =>
       
   616        let val (x', mx') = var (x, mx) in (x', Option.map typ T, mx') end))
       
   617    | Constrains csts => Constrains (csts |> map (fn (x, T) =>
       
   618        let val (x', _) = var (x, SOME Syntax.NoSyn) in (x', typ T) end))
       
   619    | Assumes asms => Assumes (asms |> map (fn ((a, atts), propps) =>
       
   620       ((name a, map attrib atts), propps |> map (fn (t, (ps, qs)) =>
       
   621         (term t, (map term ps, map term qs))))))
       
   622    | Defines defs => Defines (defs |> map (fn ((a, atts), (t, ps)) =>
       
   623       ((name a, map attrib atts), (term t, map term ps))))
       
   624    | Notes facts => Notes (facts |> map (fn ((a, atts), bs) =>
       
   625       ((name a, map attrib atts), bs |> map (fn (ths, btts) => (fact ths, map attrib btts)))));
       
   626 
       
   627 fun map_values typ term thm = map_elem
       
   628   {name = I, var = I, typ = typ, term = term, fact = map thm,
       
   629     attrib = Args.map_values I typ term thm};
       
   630 
       
   631 
       
   632 (* map attributes *)
       
   633 
       
   634 fun map_attrib_elem f = map_elem {name = I, var = I, typ = I, term = I, fact = I, attrib = f};
       
   635 
       
   636 fun intern_attrib_elem thy = map_attrib_elem (Attrib.intern_src thy);
       
   637 
       
   638 fun intern_attrib_elem_expr thy (Elem elem) = Elem (intern_attrib_elem thy elem)
       
   639   | intern_attrib_elem_expr _ (Expr expr) = Expr expr;
       
   640 
       
   641 
       
   642 (* renaming *)
       
   643 
       
   644 (* ren maps names to (new) names and syntax; represented as association list *)
       
   645 
       
   646 fun rename_var ren (x, mx) =
       
   647   case AList.lookup (op =) ren x of
       
   648       NONE => (x, mx)
       
   649     | SOME (x', NONE) =>
       
   650         (x', if mx = NONE then mx else SOME Syntax.NoSyn)     (*drop syntax*)
       
   651     | SOME (x', SOME mx') =>
       
   652         if mx = NONE then raise ERROR_MESSAGE
       
   653           ("Attempt to change syntax of structure parameter " ^ quote x)
       
   654         else (x', SOME mx');                                (*change syntax*)
       
   655 
       
   656 fun rename ren x =
       
   657   case AList.lookup (op =) ren x of
       
   658       NONE => x
       
   659     | SOME (x', _) => x';                                   (*ignore syntax*)
       
   660 
       
   661 fun rename_term ren (Free (x, T)) = Free (rename ren x, T)
       
   662   | rename_term ren (t $ u) = rename_term ren t $ rename_term ren u
       
   663   | rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t)
       
   664   | rename_term _ a = a;
       
   665 
       
   666 fun rename_thm ren th =
       
   667   let
       
   668     val {thy, hyps, prop, maxidx, ...} = Thm.rep_thm th;
       
   669     val cert = Thm.cterm_of thy;
       
   670     val (xs, Ts) = Library.split_list (fold Term.add_frees (prop :: hyps) []);
       
   671     val xs' = map (rename ren) xs;
       
   672     fun cert_frees names = map (cert o Free) (names ~~ Ts);
       
   673     fun cert_vars names = map (cert o Var o apfst (rpair (maxidx + 1))) (names ~~ Ts);
       
   674   in
       
   675     if xs = xs' then th
       
   676     else
       
   677       th
       
   678       |> Drule.implies_intr_list (map cert hyps)
       
   679       |> Drule.forall_intr_list (cert_frees xs)
       
   680       |> Drule.forall_elim_list (cert_vars xs)
       
   681       |> Thm.instantiate ([], cert_vars xs ~~ cert_frees xs')
       
   682       |> (fn th' => Drule.implies_elim_list th' (map (Thm.assume o cert o rename_term ren) hyps))
       
   683   end;
       
   684 
       
   685 fun rename_elem ren =
       
   686   map_values I (rename_term ren) (rename_thm ren) o
       
   687   map_elem {name = I, typ = I, term = I, fact = I, attrib = I, var = rename_var ren};
       
   688 
       
   689 fun rename_facts prfx =
       
   690   map_elem {var = I, typ = I, term = I, fact = I, attrib = I, name = NameSpace.qualified prfx};
       
   691 
       
   692 
       
   693 (* type instantiation *)
       
   694 
       
   695 fun inst_type [] T = T
       
   696   | inst_type env T = Term.map_type_tfree (fn v => AList.lookup (op =) env v |> the_default (TFree v)) T;
       
   697 
       
   698 fun inst_term [] t = t
       
   699   | inst_term env t = Term.map_term_types (inst_type env) t;
       
   700 
       
   701 fun inst_thm _ [] th = th
       
   702   | inst_thm ctxt env th =
       
   703       let
       
   704         val thy = ProofContext.theory_of ctxt;
       
   705         val cert = Thm.cterm_of thy;
       
   706         val certT = Thm.ctyp_of thy;
       
   707         val {hyps, prop, maxidx, ...} = Thm.rep_thm th;
       
   708         val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps);
       
   709         val env' = List.filter (fn ((a, _), _) => a mem_string tfrees) env;
       
   710       in
       
   711         if null env' then th
       
   712         else
       
   713           th
       
   714           |> Drule.implies_intr_list (map cert hyps)
       
   715           |> Drule.tvars_intr_list (map (#1 o #1) env')
       
   716           |> (fn (th', al) => th' |>
       
   717             Thm.instantiate ((map (fn ((a, _), T) =>
       
   718               (certT (TVar ((the o AList.lookup (op =) al) a)), certT T)) env'), []))
       
   719           |> (fn th'' => Drule.implies_elim_list th''
       
   720               (map (Thm.assume o cert o inst_term env') hyps))
       
   721       end;
       
   722 
       
   723 fun inst_elem ctxt env =
       
   724   map_values (inst_type env) (inst_term env) (inst_thm ctxt env);
       
   725 
       
   726 
       
   727 (* term and type instantiation, variant using symbol tables *)
       
   728 
       
   729 (* instantiate TFrees *)
       
   730 
       
   731 fun tinst_tab_elem thy tinst =
       
   732   map_values (tinst_tab_type tinst) (tinst_tab_term tinst) (tinst_tab_thm thy tinst);
       
   733 
       
   734 (* instantiate TFrees and Frees *)
       
   735 
       
   736 fun inst_tab_elem thy (inst as (_, tinst)) =
       
   737   map_values (tinst_tab_type tinst) (inst_tab_term inst) (inst_tab_thm thy inst);
       
   738 
       
   739 fun inst_tab_elems thy inst ((n, ps), elems) =
       
   740       ((n, map (inst_tab_term inst) ps), map (inst_tab_elem thy inst) elems);
       
   741 
       
   742 
       
   743 (* protected thms *)
       
   744 
   484 
   745 fun assume_protected thy t =
   485 fun assume_protected thy t =
   746   (t, Goal.protect (Thm.assume (Thm.cterm_of thy t)));
   486   (t, Goal.protect (Thm.assume (Thm.cterm_of thy t)));
   747 
   487 
   748 fun prove_protected thy t tac =
   488 fun prove_protected thy t tac =
   824 
   564 
   825 
   565 
   826 (* flatten expressions *)
   566 (* flatten expressions *)
   827 
   567 
   828 local
   568 local
   829 
       
   830 (* CB: OUTDATED unique_parms has the following type:
       
   831      'a ->
       
   832      (('b * (('c * 'd) list * Symtab.key list)) * 'e) list ->
       
   833      (('b * ('c * 'd) list) * 'e) list  *)
       
   834 
   569 
   835 fun unique_parms ctxt elemss =
   570 fun unique_parms ctxt elemss =
   836   let
   571   let
   837     val param_decls =
   572     val param_decls =
   838       List.concat (map (fn (((name, (ps, qs)), _), _) => map (rpair (name, ps)) qs) elemss)
   573       List.concat (map (fn (((name, (ps, qs)), _), _) => map (rpair (name, ps)) qs) elemss)
   842       SOME (q, ids) => err_in_locale ctxt ("Multiple declaration of parameter " ^ quote q)
   577       SOME (q, ids) => err_in_locale ctxt ("Multiple declaration of parameter " ^ quote q)
   843           (map (apsnd (map fst)) ids)
   578           (map (apsnd (map fst)) ids)
   844     | NONE => map (apfst (apfst (apsnd #1))) elemss)
   579     | NONE => map (apfst (apfst (apsnd #1))) elemss)
   845   end;
   580   end;
   846 
   581 
   847 fun unify_parms ctxt (fixed_parms : (string * typ) list)
   582 fun unify_parms ctxt fixed_parms raw_parmss =
   848   (raw_parmss : (string * typ option) list list) =
       
   849   let
   583   let
   850     val thy = ProofContext.theory_of ctxt;
   584     val thy = ProofContext.theory_of ctxt;
   851     val maxidx = length raw_parmss;
   585     val maxidx = length raw_parmss;
   852     val idx_parmss = (0 upto maxidx - 1) ~~ raw_parmss;
   586     val idx_parmss = (0 upto maxidx - 1) ~~ raw_parmss;
   853 
   587 
   854     fun varify i = Term.map_type_tfree (fn (a, S) => TVar ((a, i), S));
   588     fun varify i = Term.map_type_tfree (fn (a, S) => TVar ((a, i), S));
   855     fun varify_parms (i, ps) = map (apsnd (varify i)) (param_types ps);
   589     fun varify_parms (i, ps) = map (apsnd (varify i)) (param_types ps);
   856     val parms = fixed_parms @ List.concat (map varify_parms idx_parmss);
   590     val parms = fixed_parms @ List.concat (map varify_parms idx_parmss);
   857 
   591 
   858     fun unify T ((env, maxidx), U) =
   592     fun unify T U envir = Sign.typ_unify thy (U, T) envir
   859       Sign.typ_unify thy (U, T) (env, maxidx)
       
   860       handle Type.TUNIFY =>
   593       handle Type.TUNIFY =>
   861         let val prt = Sign.string_of_typ thy
   594         let val prt = Sign.string_of_typ thy in
   862         in raise TYPE ("unify_parms: failed to unify types " ^
   595           raise TYPE ("unify_parms: failed to unify types " ^
   863           prt U ^ " and " ^ prt T, [U, T], [])
   596             prt U ^ " and " ^ prt T, [U, T], [])
   864         end
   597         end;
   865     fun unify_list (envir, T :: Us) = Library.foldl (unify T) (envir, Us)
   598     fun unify_list (T :: Us) = fold (unify T) Us
   866       | unify_list (envir, []) = envir;
   599       | unify_list [] = I;
   867     val (unifier, _) = Library.foldl unify_list
   600     val (unifier, _) = fold unify_list (map #2 (Symtab.dest (Symtab.make_multi parms)))
   868       ((Vartab.empty, maxidx), map #2 (Symtab.dest (Symtab.make_multi parms)));
   601       (Vartab.empty, maxidx);
   869 
   602 
   870     val parms' = map (apsnd (Envir.norm_type unifier)) (gen_distinct (eq_fst (op =)) parms);
   603     val parms' = map (apsnd (Envir.norm_type unifier)) (gen_distinct (eq_fst (op =)) parms);
   871     val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (map #2 parms'));
   604     val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (map #2 parms'));
   872 
   605 
   873     fun inst_parms (i, ps) =
   606     fun inst_parms (i, ps) =
   874       foldr Term.add_typ_tfrees [] (List.mapPartial snd ps)
   607       foldr Term.add_typ_tfrees [] (List.mapPartial snd ps)
   875       |> List.mapPartial (fn (a, S) =>
   608       |> List.mapPartial (fn (a, S) =>
   876           let val T = Envir.norm_type unifier' (TVar ((a, i), S))
   609           let val T = Envir.norm_type unifier' (TVar ((a, i), S))
   877           in if T = TFree (a, S) then NONE else SOME ((a, S), T) end)
   610           in if T = TFree (a, S) then NONE else SOME (a, T) end)
   878   in map inst_parms idx_parmss end : ((string * sort) * typ) list list;
   611       |> Symtab.make;
       
   612   in map inst_parms idx_parmss end;
   879 
   613 
   880 in
   614 in
   881 
   615 
   882 fun unify_elemss _ _ [] = []
   616 fun unify_elemss _ _ [] = []
   883   | unify_elemss _ [] [elems] = [elems]
   617   | unify_elemss _ [] [elems] = [elems]
   884   | unify_elemss ctxt fixed_parms elemss =
   618   | unify_elemss ctxt fixed_parms elemss =
   885       let
   619       let
       
   620         val thy = ProofContext.theory_of ctxt;
   886         val envs = unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss);
   621         val envs = unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss);
   887         fun inst ((((name, ps), mode), elems), env) =
   622         fun inst ((((name, ps), mode), elems), env) =
   888           (((name, map (apsnd (Option.map (inst_type env))) ps), 
   623           (((name, map (apsnd (Option.map (Element.instT_type env))) ps),
   889               map_mode (map (fn (t, th) => (inst_term env t, inst_thm ctxt env th))) mode),
   624               map_mode (map (fn (t, th) =>
   890             map (inst_elem ctxt env) elems);
   625                 (Element.instT_term env t, Element.instT_thm thy env th))) mode),
       
   626             map (Element.instT_ctxt thy env) elems);
   891       in map inst (elemss ~~ envs) end;
   627       in map inst (elemss ~~ envs) end;
   892 
   628 
   893 (* like unify_elemss, but does not touch mode, additional
   629 (* like unify_elemss, but does not touch mode, additional
   894    parameter c_parms for enforcing further constraints (eg. syntax) *)
   630    parameter c_parms for enforcing further constraints (eg. syntax) *)
   895 
   631 
   896 fun unify_elemss' _ _ [] [] = []
   632 fun unify_elemss' _ _ [] [] = []
   897   | unify_elemss' _ [] [elems] [] = [elems]
   633   | unify_elemss' _ [] [elems] [] = [elems]
   898   | unify_elemss' ctxt fixed_parms elemss c_parms =
   634   | unify_elemss' ctxt fixed_parms elemss c_parms =
   899       let
   635       let
   900         val envs = unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss @ map single c_parms);
   636         val thy = ProofContext.theory_of ctxt;
       
   637         val envs =
       
   638           unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss @ map single c_parms);
   901         fun inst ((((name, ps), (ps', mode)), elems), env) =
   639         fun inst ((((name, ps), (ps', mode)), elems), env) =
   902           (((name, map (apsnd (Option.map (inst_type env))) ps),
   640           (((name, map (apsnd (Option.map (Element.instT_type env))) ps), (ps', mode)),
   903               (ps', mode)),
   641            map (Element.instT_ctxt thy env) elems);
   904            map (inst_elem ctxt env) elems);
       
   905       in map inst (elemss ~~ (Library.take (length elemss, envs))) end;
   642       in map inst (elemss ~~ (Library.take (length elemss, envs))) end;
   906 
   643 
   907 
   644 
   908 (* flatten_expr:
   645 (* flatten_expr:
   909    Extend list of identifiers by those new in locale expression expr.
   646    Extend list of identifiers by those new in locale expression expr.
   927 *)
   664 *)
   928 
   665 
   929 fun flatten_expr ctxt ((prev_idents, prev_syntax), expr) =
   666 fun flatten_expr ctxt ((prev_idents, prev_syntax), expr) =
   930   let
   667   let
   931     val thy = ProofContext.theory_of ctxt;
   668     val thy = ProofContext.theory_of ctxt;
   932     (* thy used for retrieval of locale info,
       
   933        ctxt for error messages, parameter unification and instantiation
       
   934        of axioms *)
       
   935 
   669 
   936     fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys
   670     fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys
   937       | renaming (NONE :: xs) (y :: ys) = renaming xs ys
   671       | renaming (NONE :: xs) (y :: ys) = renaming xs ys
   938       | renaming [] _ = []
   672       | renaming [] _ = []
   939       | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^
   673       | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^
   940           commas (map (fn NONE => "_" | SOME x => quote (fst x)) xs));
   674           commas (map (fn NONE => "_" | SOME x => quote (fst x)) xs));
   941 
   675 
   942     fun rename_parms top ren ((name, ps), (parms, mode)) =
   676     fun rename_parms top ren ((name, ps), (parms, mode)) =
   943       let val ps' = map (rename ren) ps in
   677       let val ps' = map (Element.rename ren) ps in
   944         (case duplicates ps' of
   678         (case duplicates ps' of
   945           [] => ((name, ps'),
   679           [] => ((name, ps'),
   946                  if top then (map (rename ren) parms,
   680                  if top then (map (Element.rename ren) parms,
   947                    map_mode (map (fn (t, th) =>
   681                    map_mode (map (fn (t, th) =>
   948                      (rename_term ren t, rename_thm ren th))) mode)
   682                      (Element.rename_term ren t, Element.rename_thm ren th))) mode)
   949                  else (parms, mode))
   683                  else (parms, mode))
   950         | dups => err_in_locale ctxt ("Duplicate parameters: " ^ commas_quote dups) [(name, ps')])
   684         | dups => err_in_locale ctxt ("Duplicate parameters: " ^ commas_quote dups) [(name, ps')])
   951       end;
   685       end;
   952 
   686 
   953     (* add registrations of (name, ps), recursively;
   687     (* add registrations of (name, ps), recursively;
   961             (* dummy syntax, since required by rename *)
   695             (* dummy syntax, since required by rename *)
   962           val ps'' = map (fn ((p, _), (_, T)) => (p, T)) (ps ~~ ps');
   696           val ps'' = map (fn ((p, _), (_, T)) => (p, T)) (ps ~~ ps');
   963           val [env] = unify_parms ctxt ps [map (apsnd SOME) ps''];
   697           val [env] = unify_parms ctxt ps [map (apsnd SOME) ps''];
   964             (* propagate parameter types, to keep them consistent *)
   698             (* propagate parameter types, to keep them consistent *)
   965           val regs' = map (fn ((name, ps), ths) =>
   699           val regs' = map (fn ((name, ps), ths) =>
   966               ((name, map (rename ren) ps), ths)) regs;
   700               ((name, map (Element.rename ren) ps), ths)) regs;
   967           val new_regs = gen_rems (eq_fst (op =)) (regs', ids);
   701           val new_regs = gen_rems (eq_fst (op =)) (regs', ids);
   968           val new_ids = map fst new_regs;
   702           val new_ids = map fst new_regs;
   969           val new_idTs = map (apsnd (map (fn p => (p, (the o AList.lookup (op =) ps) p)))) new_ids;
   703           val new_idTs = map (apsnd (map (fn p => (p, (the o AList.lookup (op =) ps) p)))) new_ids;
   970 
   704 
   971           val new_ths = new_regs |> map (fn (_, ths') => ths' |> map (fn (t, th) =>
   705           val new_ths = new_regs |> map (fn (_, ths') => ths' |> map (fn (t, th) =>
   972            (t |> inst_term env |> rename_term ren,
   706            (t |> Element.instT_term env |> Element.rename_term ren,
   973             th |> inst_thm ctxt env |> rename_thm ren |> satisfy_protected ths)));
   707             th |> Element.instT_thm thy env |> Element.rename_thm ren |> satisfy_protected ths)));
   974           val new_ids' = map (fn (id, ths) =>
   708           val new_ids' = map (fn (id, ths) =>
   975               (id, ([], Derived ths))) (new_ids ~~ new_ths);
   709               (id, ([], Derived ths))) (new_ids ~~ new_ths);
   976         in
   710         in
   977           fold add_regs new_idTs (ths @ List.concat new_ths, ids @ new_ids')
   711           fold add_regs new_idTs (ths @ List.concat new_ths, ids @ new_ids')
   978         end;
   712         end;
  1019             val ren = renaming xs parms'
   753             val ren = renaming xs parms'
  1020               handle ERROR_MESSAGE msg => err_in_locale' ctxt msg ids';
   754               handle ERROR_MESSAGE msg => err_in_locale' ctxt msg ids';
  1021 
   755 
  1022             val ids'' = gen_distinct (eq_fst (op =)) (map (rename_parms top ren) ids');
   756             val ids'' = gen_distinct (eq_fst (op =)) (map (rename_parms top ren) ids');
  1023             val parms'' = distinct (List.concat (map (#2 o #1) ids''));
   757             val parms'' = distinct (List.concat (map (#2 o #1) ids''));
  1024             val syn'' = syn' |> Symtab.dest |> map (rename_var ren) |>
   758             val syn'' = syn' |> Symtab.dest |> map (Element.rename_var ren) |> Symtab.make;
  1025                   Symtab.make;
       
  1026             (* check for conflicting syntax? *)
   759             (* check for conflicting syntax? *)
  1027           in (ids'', parms'', syn'') end
   760           in (ids'', parms'', syn'') end
  1028       | identify top (Merge es) =
   761       | identify top (Merge es) =
  1029           fold (fn e => fn (ids, parms, syn) =>
   762           fold (fn e => fn (ids, parms, syn) =>
  1030                    let
   763                    let
  1035                       merge_syntax ctxt ids' (syn, syn'))
   768                       merge_syntax ctxt ids' (syn, syn'))
  1036                    end)
   769                    end)
  1037             es ([], [], Symtab.empty);
   770             es ([], [], Symtab.empty);
  1038 
   771 
  1039 
   772 
  1040     (* CB: enrich identifiers by parameter types and 
   773     (* CB: enrich identifiers by parameter types and
  1041        the corresponding elements (with renamed parameters),
   774        the corresponding elements (with renamed parameters),
  1042        also takes care of parameter syntax *)
   775        also takes care of parameter syntax *)
  1043 
   776 
  1044     fun eval syn ((name, xs), axs) =
   777     fun eval syn ((name, xs), axs) =
  1045       let
   778       let
  1047         val ps' = map (apsnd SOME o #1) ps;
   780         val ps' = map (apsnd SOME o #1) ps;
  1048         val ren = map #1 ps' ~~
   781         val ren = map #1 ps' ~~
  1049               map (fn x => (x, valOf (Symtab.lookup syn x))) xs;
   782               map (fn x => (x, valOf (Symtab.lookup syn x))) xs;
  1050         val (params', elems') =
   783         val (params', elems') =
  1051           if null ren then ((ps', qs), map #1 elems)
   784           if null ren then ((ps', qs), map #1 elems)
  1052           else ((map (apfst (rename ren)) ps', map (rename ren) qs),
   785           else ((map (apfst (Element.rename ren)) ps', map (Element.rename ren) qs),
  1053             map (rename_elem ren o #1) elems);
   786             map (Element.rename_ctxt ren o #1) elems);
  1054         val elems'' = map (rename_facts (space_implode "_" xs)) elems';
   787         val elems'' = elems' |> map (Element.map_ctxt
       
   788           {var = I, typ = I, term = I, fact = I, attrib = I,
       
   789             name = NameSpace.qualified (space_implode "_" xs)});
  1055       in (((name, params'), axs), elems'') end;
   790       in (((name, params'), axs), elems'') end;
  1056 
   791 
  1057     (* type constraint for renamed parameter with syntax *)
   792     (* type constraint for renamed parameter with syntax *)
  1058     fun type_syntax NONE = NONE
   793     fun type_syntax NONE = NONE
  1059       | type_syntax (SOME mx) = let
   794       | type_syntax (SOME mx) = let
  1078          elemss;
   813          elemss;
  1079     fun inst_th (t, th) = let
   814     fun inst_th (t, th) = let
  1080          val {hyps, prop, ...} = Thm.rep_thm th;
   815          val {hyps, prop, ...} = Thm.rep_thm th;
  1081          val ps = map (apsnd SOME) (fold Term.add_frees (prop :: hyps) []);
   816          val ps = map (apsnd SOME) (fold Term.add_frees (prop :: hyps) []);
  1082          val [env] = unify_parms ctxt all_params [ps];
   817          val [env] = unify_parms ctxt all_params [ps];
  1083          val t' = inst_term env t;
   818          val t' = Element.instT_term env t;
  1084          val th' = inst_thm ctxt env th;
   819          val th' = Element.instT_thm thy env th;
  1085        in (t', th') end;
   820        in (t', th') end;
  1086     val final_elemss = map (fn ((id, mode), elems) =>
   821     val final_elemss = map (fn ((id, mode), elems) =>
  1087          ((id, map_mode (map inst_th) mode), elems)) elemss';
   822          ((id, map_mode (map inst_th) mode), elems)) elemss';
  1088 
   823 
  1089   in ((prev_idents @ idents, syntax), final_elemss) end;
   824   in ((prev_idents @ idents, syntax), final_elemss) end;
  1156     fold_map (fn (((name, ps), mode), raw_elems) => fn ctxt =>
   891     fold_map (fn (((name, ps), mode), raw_elems) => fn ctxt =>
  1157       let
   892       let
  1158         val elems = map (prep_facts ctxt) raw_elems;
   893         val elems = map (prep_facts ctxt) raw_elems;
  1159         val (ctxt', res) = apsnd List.concat
   894         val (ctxt', res) = apsnd List.concat
  1160             (activate_elems (((name, ps), mode), elems) ctxt);
   895             (activate_elems (((name, ps), mode), elems) ctxt);
  1161         val elems' = map (map_attrib_elem Args.closure) elems;
   896         val elems' = elems |> map (Element.map_ctxt
       
   897           {name = I, var = I, typ = I, term = I, fact = I, attrib = Args.closure});
  1162       in ((((name, ps), elems'), res), ctxt') end);
   898       in ((((name, ps), elems'), res), ctxt') end);
  1163 
   899 
  1164 in
   900 in
  1165 
   901 
  1166 (* CB: activate_facts prep_facts (ctxt, elemss),
   902 (* CB: activate_facts prep_facts (ctxt, elemss),
  1188   in (ctxt', (args', facts)) end;
   924   in (ctxt', (args', facts)) end;
  1189 
   925 
  1190 end;
   926 end;
  1191 
   927 
  1192 
   928 
  1193 (* register elements *)
   929 
  1194 
   930 (** prepare locale elements **)
  1195 (* not used
       
  1196 fun register_elems (((_, ps), (((name, ax_ps), axs), _)), ctxt) =
       
  1197   if name = "" then ctxt
       
  1198       else let val ps' = map (fn (n, SOME T) => Free (n, T)) ax_ps
       
  1199           val ctxt' = put_local_registration (name, ps') ("", []) ctxt
       
  1200         in foldl (fn (ax, ctxt) =>
       
  1201           add_local_witness (name, ps') ax ctxt) ctxt' axs
       
  1202         end;
       
  1203 
       
  1204 fun register_elemss id_elemss ctxt = 
       
  1205   foldl register_elems ctxt id_elemss;
       
  1206 *)
       
  1207 
       
  1208 
       
  1209 (** prepare context elements **)
       
  1210 
   931 
  1211 (* expressions *)
   932 (* expressions *)
  1212 
   933 
  1213 fun intern_expr thy (Locale xname) = Locale (intern thy xname)
   934 fun intern_expr thy (Locale xname) = Locale (intern thy xname)
  1214   | intern_expr thy (Merge exprs) = Merge (map (intern_expr thy) exprs)
   935   | intern_expr thy (Merge exprs) = Merge (map (intern_expr thy) exprs)
  1252    The implementation of activate_facts relies on identifier names being
   973    The implementation of activate_facts relies on identifier names being
  1253    empty strings for external elements.
   974    empty strings for external elements.
  1254 *)
   975 *)
  1255 
   976 
  1256 fun flatten (ctxt, _) ((ids, syn), Elem (Fixes fixes)) = let
   977 fun flatten (ctxt, _) ((ids, syn), Elem (Fixes fixes)) = let
  1257 	val ids' = ids @ [(("", map #1 fixes), ([], Assumed []))]
   978         val ids' = ids @ [(("", map #1 fixes), ([], Assumed []))]
  1258       in
   979       in
  1259 	((ids',
   980         ((ids',
  1260 	 merge_syntax ctxt ids'
   981          merge_syntax ctxt ids'
  1261 	   (syn, Symtab.make (map (fn fx => (#1 fx, #3 fx)) fixes))
   982            (syn, Symtab.make (map (fn fx => (#1 fx, #3 fx)) fixes))
  1262 	   handle Symtab.DUPS xs => err_in_locale ctxt
   983            handle Symtab.DUPS xs => err_in_locale ctxt
  1263 	     ("Conflicting syntax for parameters: " ^ commas_quote xs)
   984              ("Conflicting syntax for parameters: " ^ commas_quote xs)
  1264              (map #1 ids')),
   985              (map #1 ids')),
  1265 	 [((("", map (rpair NONE o #1) fixes), Assumed []), Ext (Fixes fixes))])
   986          [((("", map (rpair NONE o #1) fixes), Assumed []), Ext (Fixes fixes))])
  1266       end
   987       end
  1267   | flatten _ ((ids, syn), Elem elem) =
   988   | flatten _ ((ids, syn), Elem elem) =
  1268       ((ids @ [(("", []), ([], Assumed []))], syn), [((("", []), Assumed []), Ext elem)])
   989       ((ids @ [(("", []), ([], Assumed []))], syn), [((("", []), Assumed []), Ext elem)])
  1269   | flatten (ctxt, prep_expr) ((ids, syn), Expr expr) =
   990   | flatten (ctxt, prep_expr) ((ids, syn), Expr expr) =
  1270       apsnd (map (apsnd Int)) (flatten_expr ctxt ((ids, syn), prep_expr expr));
   991       apsnd (map (apsnd Int)) (flatten_expr ctxt ((ids, syn), prep_expr expr));
  1304     in (ctxt', propps) end
  1025     in (ctxt', propps) end
  1305   | declare_elems _ (ctxt, ((_, Derived _), elems)) = (ctxt, []);
  1026   | declare_elems _ (ctxt, ((_, Derived _), elems)) = (ctxt, []);
  1306 
  1027 
  1307 in
  1028 in
  1308 
  1029 
  1309 (* CB: only called by prep_elemss. *)
       
  1310 
       
  1311 fun declare_elemss prep_parms fixed_params raw_elemss ctxt =
  1030 fun declare_elemss prep_parms fixed_params raw_elemss ctxt =
  1312   let
  1031   let
  1313     (* CB: fix of type bug of goal in target with context elements.
  1032     (* CB: fix of type bug of goal in target with context elements.
  1314        Parameters new in context elements must receive types that are
  1033        Parameters new in context elements must receive types that are
  1315        distinct from types of parameters in target (fixed_params).  *)
  1034        distinct from types of parameters in target (fixed_params).  *)
  1326 
  1045 
  1327 end;
  1046 end;
  1328 
  1047 
  1329 local
  1048 local
  1330 
  1049 
  1331 (* CB: normalise Assumes and Defines wrt. previous definitions *)
       
  1332 
       
  1333 val norm_term = Envir.beta_norm oo Term.subst_atomic;
  1050 val norm_term = Envir.beta_norm oo Term.subst_atomic;
  1334 
       
  1335 
       
  1336 (* CB: following code (abstract_term, abstract_thm, bind_def)
       
  1337    used in eval_text for Defines elements. *)
       
  1338 
  1051 
  1339 fun abstract_term eq =    (*assumes well-formedness according to ProofContext.cert_def*)
  1052 fun abstract_term eq =    (*assumes well-formedness according to ProofContext.cert_def*)
  1340   let
  1053   let
  1341     val body = Term.strip_all_body eq;
  1054     val body = Term.strip_all_body eq;
  1342     val vars = map Free (Term.rename_wrt_term body (Term.strip_all_vars eq));
  1055     val vars = map Free (Term.rename_wrt_term body (Term.strip_all_vars eq));
  1395 
  1108 
  1396   | finish_derived _ _ (Derived _) (Fixes _) = NONE
  1109   | finish_derived _ _ (Derived _) (Fixes _) = NONE
  1397   | finish_derived _ _ (Derived _) (Constrains _) = NONE
  1110   | finish_derived _ _ (Derived _) (Constrains _) = NONE
  1398   | finish_derived sign wits (Derived _) (Assumes asms) = asms
  1111   | finish_derived sign wits (Derived _) (Assumes asms) = asms
  1399       |> map (apsnd (map (fn (a, _) => ([Thm.assume (cterm_of sign a)], []))))
  1112       |> map (apsnd (map (fn (a, _) => ([Thm.assume (cterm_of sign a)], []))))
  1400       |> Notes |> map_values I I (satisfy_protected wits) |> SOME
  1113       |> Notes |> Element.map_ctxt_values I I (satisfy_protected wits) |> SOME
  1401   | finish_derived sign wits (Derived _) (Defines defs) = defs
  1114   | finish_derived sign wits (Derived _) (Defines defs) = defs
  1402       |> map (apsnd (fn (d, _) => [([Thm.assume (cterm_of sign d)], [])]))
  1115       |> map (apsnd (fn (d, _) => [([Thm.assume (cterm_of sign d)], [])]))
  1403       |> Notes |> map_values I I (satisfy_protected wits) |> SOME
  1116       |> Notes |> Element.map_ctxt_values I I (satisfy_protected wits) |> SOME
  1404 
  1117 
  1405   | finish_derived _ wits _ (Notes facts) = (Notes facts)
  1118   | finish_derived _ wits _ (Notes facts) = (Notes facts)
  1406       |> map_values I I (satisfy_protected wits) |> SOME;
  1119       |> Element.map_ctxt_values I I (satisfy_protected wits) |> SOME;
  1407 
  1120 
  1408 (* CB: for finish_elems (Ext) *)
  1121 (* CB: for finish_elems (Ext) *)
  1409 
  1122 
  1410 fun closeup _ false elem = elem
  1123 fun closeup _ false elem = elem
  1411   | closeup ctxt true elem =
  1124   | closeup ctxt true elem =
  1558 (* facts and attributes *)
  1271 (* facts and attributes *)
  1559 
  1272 
  1560 local
  1273 local
  1561 
  1274 
  1562 fun prep_name ctxt name =
  1275 fun prep_name ctxt name =
  1563   (* CB: reject qualified theorem names in locale declarations *)
       
  1564   if NameSpace.is_qualified name then
  1276   if NameSpace.is_qualified name then
  1565     raise ProofContext.CONTEXT ("Illegal qualified name: " ^ quote name, ctxt)
  1277     raise ProofContext.CONTEXT ("Illegal qualified name: " ^ quote name, ctxt)
  1566   else name;
  1278   else name;
  1567 
  1279 
  1568 fun prep_facts _ _ ctxt (Int elem) =
  1280 fun prep_facts _ _ ctxt (Int elem) =
  1569       map_values I I (Thm.transfer (ProofContext.theory_of ctxt)) elem
  1281       Element.map_ctxt_values I I (Thm.transfer (ProofContext.theory_of ctxt)) elem
  1570   | prep_facts get intern ctxt (Ext elem) = elem |> map_elem
  1282   | prep_facts get intern ctxt (Ext elem) = elem |> Element.map_ctxt
  1571      {var = I, typ = I, term = I,
  1283      {var = I, typ = I, term = I,
  1572       name = prep_name ctxt,
  1284       name = prep_name ctxt,
  1573       fact = get ctxt,
  1285       fact = get ctxt,
  1574       attrib = Args.assignable o intern (ProofContext.theory_of ctxt)};
  1286       attrib = Args.assignable o intern (ProofContext.theory_of ctxt)};
  1575 
  1287 
  1648 val cert_context_statement = gen_statement (K I) gen_context_i;
  1360 val cert_context_statement = gen_statement (K I) gen_context_i;
  1649 
  1361 
  1650 end;
  1362 end;
  1651 
  1363 
  1652 
  1364 
  1653 (** define locales **)
       
  1654 
       
  1655 (* print locale *)
  1365 (* print locale *)
  1656 
  1366 
  1657 fun print_locale thy show_facts import body =
  1367 fun print_locale thy show_facts import body =
  1658   let
  1368   let
  1659     val thy_ctxt = ProofContext.init thy;
  1369     val (((_, import_elemss), (ctxt, elemss, _)), _) =
  1660     val (((_, import_elemss), (ctxt, elemss, _)), _) = read_context import body thy_ctxt;
  1370       read_context import body (ProofContext.init thy);
       
  1371     val prt_elem = Element.pretty_ctxt ctxt;
  1661     val all_elems = List.concat (map #2 (import_elemss @ elemss));
  1372     val all_elems = List.concat (map #2 (import_elemss @ elemss));
  1662 
       
  1663     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
       
  1664     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
       
  1665     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
       
  1666     val prt_atts = Args.pretty_attribs ctxt;
       
  1667 
       
  1668     fun prt_syn syn =
       
  1669       let val s = (case syn of NONE => "(structure)" | SOME mx => Syntax.string_of_mixfix mx)
       
  1670       in if s = "" then [] else [Pretty.brk 2, Pretty.str s] end;
       
  1671     fun prt_fix (x, SOME T, syn) = Pretty.block (Pretty.str (x ^ " ::") :: Pretty.brk 1 ::
       
  1672           prt_typ T :: Pretty.brk 1 :: prt_syn syn)
       
  1673       | prt_fix (x, NONE, syn) = Pretty.block (Pretty.str x :: Pretty.brk 1 :: prt_syn syn);
       
  1674     fun prt_cst (x, T) = Pretty.block [Pretty.str (x ^ " ::"), prt_typ T];
       
  1675 
       
  1676     fun prt_name name = Pretty.str (ProofContext.extern_thm ctxt name);
       
  1677     fun prt_name_atts (name, atts) =
       
  1678       if name = "" andalso null atts then []
       
  1679       else [Pretty.block (Pretty.breaks (prt_name name :: prt_atts atts @ [Pretty.str ":"]))];
       
  1680 
       
  1681     fun prt_asm (a, ts) =
       
  1682       Pretty.block (Pretty.breaks (prt_name_atts a @ map (prt_term o fst) ts));
       
  1683     fun prt_def (a, (t, _)) =
       
  1684       Pretty.block (Pretty.breaks (prt_name_atts a @ [prt_term t]));
       
  1685 
       
  1686     fun prt_fact (ths, []) = map prt_thm ths
       
  1687       | prt_fact (ths, atts) =
       
  1688           Pretty.enclose "(" ")" (Pretty.breaks (map prt_thm ths)) :: prt_atts atts;
       
  1689     fun prt_note (a, ths) =
       
  1690       Pretty.block (Pretty.breaks (List.concat (prt_name_atts a :: map prt_fact ths)));
       
  1691 
       
  1692     fun items _ [] = []
       
  1693       | items prfx (x :: xs) = Pretty.block [Pretty.str prfx, Pretty.brk 1, x] :: items "  and" xs;
       
  1694     fun prt_elem (Fixes fixes) = items "fixes" (map prt_fix fixes)
       
  1695       | prt_elem (Constrains csts) = items "constrains" (map prt_cst csts)
       
  1696       | prt_elem (Assumes asms) = items "assumes" (map prt_asm asms)
       
  1697       | prt_elem (Defines defs) = items "defines" (map prt_def defs)
       
  1698       | prt_elem (Notes facts) = items "notes" (map prt_note facts);
       
  1699   in
  1373   in
  1700     Pretty.big_list "context elements:" (all_elems
  1374     Pretty.big_list "locale elements:" (all_elems
  1701       |> (if show_facts then I else filter (fn Notes _ => false | _ => true))
  1375       |> (if show_facts then I else filter (fn Notes _ => false | _ => true))
  1702       |> map (Pretty.chunks o prt_elem))
  1376       |> map (Pretty.chunks o prt_elem))
  1703     |> Pretty.writeln
  1377     |> Pretty.writeln
  1704   end;
  1378   end;
  1705 
  1379 
  1766     val ts = map Logic.unvarify vts;
  1440     val ts = map Logic.unvarify vts;
  1767     val (parms, parmTs) = split_list parms;
  1441     val (parms, parmTs) = split_list parms;
  1768     val parmvTs = map Type.varifyT parmTs;
  1442     val parmvTs = map Type.varifyT parmTs;
  1769     val vtinst = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of ts) Vartab.empty;
  1443     val vtinst = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of ts) Vartab.empty;
  1770     val tinst = Vartab.dest vtinst |> map (fn ((x, 0), (_, T)) => (x, T))
  1444     val tinst = Vartab.dest vtinst |> map (fn ((x, 0), (_, T)) => (x, T))
  1771         |> Symtab.make;            
  1445         |> Symtab.make;
  1772     (* replace parameter names in ids by instantiations *)
  1446     (* replace parameter names in ids by instantiations *)
  1773     val vinst = Symtab.make (parms ~~ vts);
  1447     val vinst = Symtab.make (parms ~~ vts);
  1774     fun vinst_names ps = map (the o Symtab.lookup vinst) ps;
  1448     fun vinst_names ps = map (the o Symtab.lookup vinst) ps;
  1775     val inst = Symtab.make (parms ~~ ts);
  1449     val inst = Symtab.make (parms ~~ ts);
  1776     val ids' = map (apsnd vinst_names) ids;
  1450     val ids' = map (apsnd vinst_names) ids;
  1777     val wits = List.concat (map (snd o valOf o get_global_registration thy) ids');
  1451     val wits = List.concat (map (snd o valOf o get_global_registration thy) ids');
  1778   in ((inst, tinst), wits) end;
  1452   in ((tinst, inst), wits) end;
  1779 
  1453 
  1780 
  1454 
  1781 (* store instantiations of args for all registered interpretations
  1455 (* store instantiations of args for all registered interpretations
  1782    of the theory *)
  1456    of the theory *)
  1783 
  1457 
  1792 
  1466 
  1793     (* add args to thy for all registrations *)
  1467     (* add args to thy for all registrations *)
  1794 
  1468 
  1795     fun activate (thy, (vts, ((prfx, atts2), _))) =
  1469     fun activate (thy, (vts, ((prfx, atts2), _))) =
  1796       let
  1470       let
  1797         val ((inst, tinst), prems) = collect_global_witnesses thy parms ids vts;
  1471         val (insts, prems) = collect_global_witnesses thy parms ids vts;
  1798         val args' = map (fn ((n, atts), [(ths, [])]) =>
  1472         val inst_atts =
       
  1473           Args.map_values I (Element.instT_type (#1 insts))
       
  1474             (Element.inst_term insts) (Element.inst_thm thy insts);
       
  1475         val args' = args |> map (fn ((n, atts), [(ths, [])]) =>
  1799             ((NameSpace.qualified prfx n,
  1476             ((NameSpace.qualified prfx n,
  1800               map (Attrib.global_attribute_i thy)
  1477               map (Attrib.global_attribute_i thy) (map inst_atts atts @ atts2)),
  1801                   (inst_tab_atts thy (inst, tinst) atts @ atts2)),
       
  1802              [(map (Drule.standard o satisfy_protected prems o
  1478              [(map (Drule.standard o satisfy_protected prems o
  1803                 inst_tab_thm thy (inst, tinst)) ths, [])]))
  1479             Element.inst_thm thy insts) ths, [])]));
  1804           args;
       
  1805       in global_note_accesses_i (Drule.kind kind) prfx args' thy |> fst end;
  1480       in global_note_accesses_i (Drule.kind kind) prfx args' thy |> fst end;
  1806   in Library.foldl activate (thy, regs) end;
  1481   in Library.foldl activate (thy, regs) end;
  1807 
  1482 
  1808 
  1483 
  1809 fun smart_note_thmss kind NONE = PureThy.note_thmss_i (Drule.kind kind)
  1484 fun smart_note_thmss kind NONE = PureThy.note_thmss_i (Drule.kind kind)
  1861       |> note_thmss_registrations kind loc args';
  1536       |> note_thmss_registrations kind loc args';
  1862   in (facts, (ctxt', thy')) end;
  1537   in (facts, (ctxt', thy')) end;
  1863 
  1538 
  1864 end;
  1539 end;
  1865 
  1540 
       
  1541 
       
  1542 
       
  1543 (** define locales **)
  1866 
  1544 
  1867 (* predicate text *)
  1545 (* predicate text *)
  1868 (* CB: generate locale predicates and delta predicates *)
  1546 (* CB: generate locale predicates and delta predicates *)
  1869 
  1547 
  1870 local
  1548 local
  1948 
  1626 
  1949 (* CB: changes only "new" elems, these have identifier ("", _). *)
  1627 (* CB: changes only "new" elems, these have identifier ("", _). *)
  1950 
  1628 
  1951 fun change_elemss axioms elemss = (map (conclude_protected o #2) axioms, elemss) |> foldl_map
  1629 fun change_elemss axioms elemss = (map (conclude_protected o #2) axioms, elemss) |> foldl_map
  1952   (fn (axms, (id as ("", _), es)) =>
  1630   (fn (axms, (id as ("", _), es)) =>
  1953     foldl_map assumes_to_notes (axms, map (map_values I I (satisfy_protected axioms)) es)
  1631     foldl_map assumes_to_notes (axms, map (Element.map_ctxt_values I I (satisfy_protected axioms)) es)
  1954     |> apsnd (pair id)
  1632     |> apsnd (pair id)
  1955   | x => x) |> #2;
  1633   | x => x) |> #2;
  1956 
  1634 
  1957 in
  1635 in
  1958 
  1636 
  2019     val (pred_thy, (elemss', predicate as (predicate_statement, predicate_axioms))) =
  1697     val (pred_thy, (elemss', predicate as (predicate_statement, predicate_axioms))) =
  2020       if do_pred then thy |> define_preds bname text elemss
  1698       if do_pred then thy |> define_preds bname text elemss
  2021       else (thy, (elemss, ([], [])));
  1699       else (thy, (elemss, ([], [])));
  2022     val pred_ctxt = ProofContext.init pred_thy;
  1700     val pred_ctxt = ProofContext.init pred_thy;
  2023 
  1701 
  2024     fun axiomify axioms elemss = 
  1702     fun axiomify axioms elemss =
  2025       (axioms, elemss) |> foldl_map (fn (axs, (id, elems)) => let
  1703       (axioms, elemss) |> foldl_map (fn (axs, (id, elems)) => let
  2026                    val ts = List.concat (List.mapPartial (fn (Assumes asms) =>
  1704                    val ts = List.concat (List.mapPartial (fn (Assumes asms) =>
  2027                      SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems);
  1705                      SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems);
  2028                    val (axs1, axs2) = splitAt (length ts, axs);
  1706                    val (axs1, axs2) = splitAt (length ts, axs);
  2029                  in (axs2, ((id, Assumed axs1), elems)) end)
  1707                  in (axs2, ((id, Assumed axs1), elems)) end)
  2062 
  1740 
  2063 (** locale goals **)
  1741 (** locale goals **)
  2064 
  1742 
  2065 local
  1743 local
  2066 
  1744 
       
  1745 fun intern_attrib thy = map_elem (Element.map_ctxt
       
  1746   {name = I, var = I, typ = I, term = I, fact = I, attrib = Attrib.intern_src thy});
       
  1747 
  2067 fun global_goal prep_att =
  1748 fun global_goal prep_att =
  2068   Proof.global_goal ProofDisplay.present_results prep_att ProofContext.bind_propp_schematic_i;
  1749   Proof.global_goal ProofDisplay.present_results prep_att ProofContext.bind_propp_schematic_i;
  2069 
  1750 
  2070 fun gen_theorem prep_att prep_elem prep_stmt kind before_qed after_qed a raw_elems concl thy =
  1751 fun gen_theorem prep_att prep_elem prep_stmt kind before_qed after_qed a raw_elems concl thy =
  2071   let
  1752   let
  2092     val elems_ctxt' = elems_ctxt
  1773     val elems_ctxt' = elems_ctxt
  2093       |> ProofContext.add_view locale_ctxt elems_view
  1774       |> ProofContext.add_view locale_ctxt elems_view
  2094       |> ProofContext.add_view thy_ctxt locale_view;
  1775       |> ProofContext.add_view thy_ctxt locale_view;
  2095     val locale_ctxt' = locale_ctxt
  1776     val locale_ctxt' = locale_ctxt
  2096       |> ProofContext.add_view thy_ctxt locale_view;
  1777       |> ProofContext.add_view thy_ctxt locale_view;
  2097       
  1778 
  2098     val stmt = map (apsnd (K []) o fst) concl ~~ propp;
  1779     val stmt = map (apsnd (K []) o fst) concl ~~ propp;
  2099 
  1780 
  2100     fun after_qed' results =
  1781     fun after_qed' results =
  2101       let val locale_results = results |> (map o map)
  1782       let val locale_results = results |> (map o map)
  2102           (ProofContext.export elems_ctxt' locale_ctxt') in
  1783           (ProofContext.export elems_ctxt' locale_ctxt') in
  2109       end;
  1790       end;
  2110   in global_goal (K I) kind before_qed after_qed' target (name, []) stmt elems_ctxt' end;
  1791   in global_goal (K I) kind before_qed after_qed' target (name, []) stmt elems_ctxt' end;
  2111 
  1792 
  2112 in
  1793 in
  2113 
  1794 
  2114 val theorem = gen_theorem Attrib.global_attribute intern_attrib_elem_expr read_context_statement;
  1795 val theorem = gen_theorem Attrib.global_attribute intern_attrib read_context_statement;
  2115 val theorem_i = gen_theorem (K I) (K I) cert_context_statement;
  1796 val theorem_i = gen_theorem (K I) (K I) cert_context_statement;
  2116 val theorem_in_locale = gen_theorem_in_locale intern Attrib.intern_src
  1797 
  2117   intern_attrib_elem_expr read_context_statement false;
  1798 val theorem_in_locale = gen_theorem_in_locale intern Attrib.intern_src intern_attrib
  2118 val theorem_in_locale_i = gen_theorem_in_locale (K I) (K I) (K I) cert_context_statement false;
  1799   read_context_statement false;
  2119 val theorem_in_locale_no_target =
  1800 
  2120   gen_theorem_in_locale (K I) (K I) (K I) cert_context_statement true;
  1801 val theorem_in_locale_i = gen_theorem_in_locale (K I) (K I) (K I)
       
  1802   cert_context_statement false;
       
  1803 
       
  1804 val theorem_in_locale_no_target = gen_theorem_in_locale (K I) (K I) (K I)
       
  1805   cert_context_statement true;
  2121 
  1806 
  2122 fun smart_theorem kind NONE a [] concl =
  1807 fun smart_theorem kind NONE a [] concl =
  2123       Proof.theorem kind NONE (K I) (SOME "") a concl o ProofContext.init
  1808       Proof.theorem kind NONE (K I) (SOME "") a concl o ProofContext.init
  2124   | smart_theorem kind NONE a elems concl =
  1809   | smart_theorem kind NONE a elems concl =
  2125       theorem kind NONE (K I) a elems concl
  1810       theorem kind NONE (K I) a elems concl
  2269     val inst = Symtab.make (given_ps ~~ map rename vs);
  1954     val inst = Symtab.make (given_ps ~~ map rename vs);
  2270 
  1955 
  2271     (* defined params without user input *)
  1956     (* defined params without user input *)
  2272     val not_given = List.mapPartial (fn (x, (NONE, T)) => SOME (x, T)
  1957     val not_given = List.mapPartial (fn (x, (NONE, T)) => SOME (x, T)
  2273          | (_, (SOME _, _)) => NONE) (ps ~~ (insts ~~ pTs));
  1958          | (_, (SOME _, _)) => NONE) (ps ~~ (insts ~~ pTs));
  2274     fun add_def ((inst, tinst), (p, pT)) =
  1959     fun add_def (p, pT) inst =
  2275       let
  1960       let
  2276         val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of
  1961         val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of
  2277                NONE => error ("Instance missing for parameter " ^ quote p)
  1962                NONE => error ("Instance missing for parameter " ^ quote p)
  2278              | SOME (Free (_, T), t) => (t, T);
  1963              | SOME (Free (_, T), t) => (t, T);
  2279         val d = inst_tab_term (inst, tinst) t;
  1964         val d = Element.inst_term (tinst, inst) t;
  2280       in (Symtab.update_new (p, d) inst, tinst) end;
  1965       in Symtab.update_new (p, d) inst end;
  2281     val (inst, tinst) = Library.foldl add_def ((inst, tinst), not_given);
  1966     val inst = fold add_def not_given inst;
  2282     (* Note: inst and tinst contain no vars. *)
  1967     val insts = (tinst, inst);
       
  1968     (* Note: insts contain no vars. *)
  2283 
  1969 
  2284     (** compute proof obligations **)
  1970     (** compute proof obligations **)
  2285 
  1971 
  2286     (* restore "small" ids *)
  1972     (* restore "small" ids *)
  2287     val ids' = map (fn ((n, ps), (_, mode)) =>
  1973     val ids' = map (fn ((n, ps), (_, mode)) =>
  2288           ((n, map (fn p => Free (p, (the o AList.lookup (op =) parms) p)) ps), mode)) ids;
  1974           ((n, map (fn p => Free (p, (the o AList.lookup (op =) parms) p)) ps), mode)) ids;
  2289     (* instantiate ids and elements *)
  1975     (* instantiate ids and elements *)
  2290     val inst_elemss = map
  1976     val inst_elemss = (ids' ~~ all_elemss) |> map (fn (((n, ps), _), ((_, mode), elems)) =>
  2291           (fn ((id, _), ((_, mode), elems)) =>
  1977       ((n, map (Element.inst_term insts) ps),
  2292              inst_tab_elems thy (inst, tinst) (id, map (fn Int e => e) elems)
  1978         map (fn Int e => Element.inst_ctxt thy insts e) elems)
  2293                |> apfst (fn id => (id, map_mode (map (fn (t, th) =>
  1979       |> apfst (fn id => (id, map_mode (map (fn (t, th) =>
  2294                  (inst_tab_term (inst, tinst) t, inst_tab_thm thy (inst, tinst) th))) mode)))
  1980           (Element.inst_term insts t, Element.inst_thm thy insts th))) mode)));
  2295           (ids' ~~ all_elemss);
       
  2296 
  1981 
  2297     (* remove fragments already registered with theory or context *)
  1982     (* remove fragments already registered with theory or context *)
  2298     val new_inst_elemss = List.filter (fn ((id, _), _) =>
  1983     val new_inst_elemss = List.filter (fn ((id, _), _) =>
  2299           not (test_reg thy_ctxt id)) inst_elemss;
  1984           not (test_reg thy_ctxt id)) inst_elemss;
  2300     val new_ids = map #1 new_inst_elemss;
  1985     val new_ids = map #1 new_inst_elemss;
  2361             thy |> put_registration_in_locale target id
  2046             thy |> put_registration_in_locale target id
  2362                 |> fold (add_witness_in_locale target id) thms
  2047                 |> fold (add_witness_in_locale target id) thms
  2363           | activate_id _ thy = thy;
  2048           | activate_id _ thy = thy;
  2364 
  2049 
  2365         fun activate_reg (vts, ((prfx, atts2), _)) thy = let
  2050         fun activate_reg (vts, ((prfx, atts2), _)) thy = let
  2366             val ((inst, tinst), wits) =
  2051             val (insts, wits) = collect_global_witnesses thy fixed t_ids vts;
  2367                 collect_global_witnesses thy fixed t_ids vts;
  2052             fun inst_parms ps = map
  2368             fun inst_parms ps = map 
       
  2369                   (the o AList.lookup (op =) (map #1 fixed ~~ vts)) ps;
  2053                   (the o AList.lookup (op =) (map #1 fixed ~~ vts)) ps;
  2370             val disch = satisfy_protected wits;
  2054             val disch = satisfy_protected wits;
  2371             val new_elemss = List.filter (fn (((name, ps), _), _) =>
  2055             val new_elemss = List.filter (fn (((name, ps), _), _) =>
  2372                 not (test_global_registration thy (name, inst_parms ps))) (ids_elemss);
  2056                 not (test_global_registration thy (name, inst_parms ps))) (ids_elemss);
  2373             fun activate_assumed_id (((_, Derived _), _), _) thy = thy
  2057             fun activate_assumed_id (((_, Derived _), _), _) thy = thy
  2377                 if test_global_registration thy (name, ps')
  2061                 if test_global_registration thy (name, ps')
  2378                 then thy
  2062                 then thy
  2379                 else thy
  2063                 else thy
  2380                   |> put_global_registration (name, ps') (prfx, atts2)
  2064                   |> put_global_registration (name, ps') (prfx, atts2)
  2381                   |> fold (fn (t, th) => fn thy => add_global_witness (name, ps')
  2065                   |> fold (fn (t, th) => fn thy => add_global_witness (name, ps')
  2382                      (inst_tab_term (inst, tinst) t,
  2066                      (Element.inst_term insts t, disch (Element.inst_thm thy insts th)) thy) thms
  2383                       disch (inst_tab_thm thy (inst, tinst) th)) thy) thms
       
  2384               end;
  2067               end;
  2385 
  2068 
  2386             fun activate_derived_id ((_, Assumed _), _) thy = thy
  2069             fun activate_derived_id ((_, Assumed _), _) thy = thy
  2387               | activate_derived_id (((name, ps), Derived ths), _) thy = let
  2070               | activate_derived_id (((name, ps), Derived ths), _) thy = let
  2388                 val ps' = inst_parms ps;
  2071                 val ps' = inst_parms ps;
  2390                 if test_global_registration thy (name, ps')
  2073                 if test_global_registration thy (name, ps')
  2391                 then thy
  2074                 then thy
  2392                 else thy
  2075                 else thy
  2393                   |> put_global_registration (name, ps') (prfx, atts2)
  2076                   |> put_global_registration (name, ps') (prfx, atts2)
  2394                   |> fold (fn (t, th) => fn thy => add_global_witness (name, ps')
  2077                   |> fold (fn (t, th) => fn thy => add_global_witness (name, ps')
  2395                        (inst_tab_term (inst, tinst) t,
  2078                        (Element.inst_term insts t,
  2396                         disch (inst_tab_thm thy (inst, tinst) (satisfy th))) thy) ths
  2079                         disch (Element.inst_thm thy insts (satisfy th))) thy) ths
  2397               end;
  2080               end;
  2398 
  2081 
  2399             fun activate_elem (Notes facts) thy =
  2082             fun activate_elem (Notes facts) thy =
  2400                 let
  2083                 let
  2401                   val facts' = facts
  2084                   val facts' = facts
  2402                       |> Attrib.map_facts (Attrib.global_attribute_i thy o
  2085                       |> Attrib.map_facts (Attrib.global_attribute_i thy o
  2403                          Args.map_values I (tinst_tab_type tinst)
  2086                          Args.map_values I (Element.instT_type (#1 insts))
  2404                            (inst_tab_term (inst, tinst))
  2087                            (Element.inst_term insts)
  2405                            (disch o inst_tab_thm thy (inst, tinst) o satisfy))
  2088                            (disch o Element.inst_thm thy insts o satisfy))
  2406                       |> map (apfst (apsnd (fn a => a @ map (Attrib.global_attribute thy) atts2)))
  2089                       |> map (apfst (apsnd (fn a => a @ map (Attrib.global_attribute thy) atts2)))
  2407                       |> map (apsnd (map (apfst (map (disch o inst_tab_thm thy (inst, tinst) o satisfy)))))
  2090                       |> map (apsnd (map (apfst (map (disch o Element.inst_thm thy insts o satisfy)))))
  2408                       |> map (apfst (apfst (NameSpace.qualified prfx)))
  2091                       |> map (apfst (apfst (NameSpace.qualified prfx)))
  2409                 in
  2092                 in
  2410                   fst (global_note_accesses_i (Drule.kind "") prfx facts' thy)
  2093                   fst (global_note_accesses_i (Drule.kind "") prfx facts' thy)
  2411                 end
  2094                 end
  2412               | activate_elem _ thy = thy;
  2095               | activate_elem _ thy = thy;
  2440 
  2123 
  2441 in
  2124 in
  2442 
  2125 
  2443 fun interpretation (prfx, atts) expr insts thy =
  2126 fun interpretation (prfx, atts) expr insts thy =
  2444   let
  2127   let
  2445     val thy_ctxt = ProofContext.init thy;
       
  2446     val (propss, activate) = prep_global_registration (prfx, atts) expr insts thy;
  2128     val (propss, activate) = prep_global_registration (prfx, atts) expr insts thy;
  2447     val kind = goal_name thy "interpretation" NONE propss;
  2129     val kind = goal_name thy "interpretation" NONE propss;
  2448     fun after_qed results = activate (prep_result propss results);
  2130     val after_qed = activate o (prep_result propss);
  2449   in
  2131   in
  2450     thy_ctxt
  2132     ProofContext.init thy
  2451     |> Proof.theorem_i kind NONE after_qed NONE ("", []) (prep_propp propss)
  2133     |> Proof.theorem_i kind NONE after_qed NONE ("", []) (prep_propp propss)
  2452     |> refine_protected
  2134     |> refine_protected
  2453   end;
  2135   end;
  2454 
  2136 
  2455 fun interpretation_in_locale (raw_target, expr) thy =
  2137 fun interpretation_in_locale (raw_target, expr) thy =
  2456   let
  2138   let
  2457     val target = intern thy raw_target;
  2139     val target = intern thy raw_target;
  2458     val (propss, activate) = prep_registration_in_locale target expr thy;
  2140     val (propss, activate) = prep_registration_in_locale target expr thy;
  2459     val kind = goal_name thy "interpretation" (SOME target) propss;
  2141     val kind = goal_name thy "interpretation" (SOME target) propss;
  2460     fun after_qed locale_results _ = activate (prep_result propss locale_results);
  2142     val after_qed = K (activate o prep_result propss);
  2461   in
  2143   in
  2462     thy
  2144     thy
  2463     |> theorem_in_locale_no_target kind NONE after_qed target ("", []) [] (prep_propp propss)
  2145     |> theorem_in_locale_no_target kind NONE after_qed target ("", []) [] (prep_propp propss)
  2464     |> refine_protected
  2146     |> refine_protected
  2465   end;
  2147   end;