src/Pure/Isar/theory_target.ML
author haftmann
Mon Aug 09 16:56:00 2010 +0200 (2010-08-09 ago)
changeset 38303 ad4b59e9d0f9
parent 38302 0cd88fc0e3fa
child 38305 ebc2abe6e160
permissions -rw-r--r--
factored out foundation of `define` into separate function
wenzelm@20894
     1
(*  Title:      Pure/Isar/theory_target.ML
wenzelm@20894
     2
    Author:     Makarius
wenzelm@30437
     3
    Author:     Florian Haftmann, TU Muenchen
wenzelm@20894
     4
haftmann@25542
     5
Common theory/locale/class/instantiation/overloading targets.
wenzelm@20894
     6
*)
wenzelm@20894
     7
wenzelm@20894
     8
signature THEORY_TARGET =
wenzelm@20894
     9
sig
wenzelm@35205
    10
  val peek: local_theory ->
wenzelm@35205
    11
   {target: string,
wenzelm@35205
    12
    is_locale: bool,
wenzelm@35205
    13
    is_class: bool,
wenzelm@35205
    14
    instantiation: string list * (string * sort) list * sort,
haftmann@25864
    15
    overloading: (string * (string * typ) * bool) list}
haftmann@25269
    16
  val init: string option -> theory -> local_theory
wenzelm@35205
    17
  val context_cmd: xstring -> theory -> local_theory
haftmann@25864
    18
  val instantiation: string list * (string * sort) list * sort -> theory -> local_theory
haftmann@29971
    19
  val instantiation_cmd: xstring list * xstring list * xstring -> theory -> local_theory
haftmann@25864
    20
  val overloading: (string * (string * typ) * bool) list -> theory -> local_theory
wenzelm@26049
    21
  val overloading_cmd: (string * string * bool) list -> theory -> local_theory
wenzelm@20894
    22
end;
wenzelm@20894
    23
wenzelm@33553
    24
structure Theory_Target: THEORY_TARGET =
wenzelm@20894
    25
struct
wenzelm@20894
    26
wenzelm@21006
    27
(* context data *)
wenzelm@21006
    28
haftmann@29576
    29
datatype target = Target of {target: string, is_locale: bool,
haftmann@25864
    30
  is_class: bool, instantiation: string list * (string * sort) list * sort,
haftmann@25864
    31
  overloading: (string * (string * typ) * bool) list};
wenzelm@25012
    32
haftmann@29576
    33
fun make_target target is_locale is_class instantiation overloading =
haftmann@29576
    34
  Target {target = target, is_locale = is_locale,
haftmann@25519
    35
    is_class = is_class, instantiation = instantiation, overloading = overloading};
wenzelm@25291
    36
haftmann@29576
    37
val global_target = make_target "" false false ([], [], []) [];
wenzelm@25012
    38
wenzelm@33519
    39
structure Data = Proof_Data
wenzelm@21006
    40
(
wenzelm@25012
    41
  type T = target;
wenzelm@25291
    42
  fun init _ = global_target;
wenzelm@21006
    43
);
wenzelm@21006
    44
wenzelm@25012
    45
val peek = (fn Target args => args) o Data.get;
wenzelm@21006
    46
wenzelm@21006
    47
wenzelm@20894
    48
(* pretty *)
wenzelm@20894
    49
wenzelm@32785
    50
fun pretty_thy ctxt target is_class =
wenzelm@20894
    51
  let
wenzelm@20894
    52
    val thy = ProofContext.theory_of ctxt;
wenzelm@37205
    53
    val target_name =
wenzelm@37205
    54
      [Pretty.command (if is_class then "class" else "locale"),
wenzelm@37205
    55
        Pretty.str (" " ^ Locale.extern thy target)];
wenzelm@30437
    56
    val fixes =
wenzelm@30437
    57
      map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) (#1 (ProofContext.inferred_fixes ctxt));
wenzelm@30437
    58
    val assumes =
wenzelm@30473
    59
      map (fn A => (Attrib.empty_binding, [(Thm.term_of A, [])])) (Assumption.all_assms_of ctxt);
wenzelm@20894
    60
    val elems =
wenzelm@20894
    61
      (if null fixes then [] else [Element.Fixes fixes]) @
wenzelm@20894
    62
      (if null assumes then [] else [Element.Assumes assumes]);
wenzelm@26049
    63
  in
wenzelm@26049
    64
    if target = "" then []
wenzelm@37205
    65
    else if null elems then [Pretty.block target_name]
wenzelm@37205
    66
    else [Pretty.block (Pretty.fbreaks (Pretty.block (target_name @ [Pretty.str " ="]) ::
wenzelm@37205
    67
      map (Pretty.chunks o Element.pretty_ctxt ctxt) elems))]
wenzelm@20894
    68
  end;
wenzelm@20894
    69
wenzelm@32785
    70
fun pretty (Target {target, is_class, instantiation, overloading, ...}) ctxt =
wenzelm@37205
    71
  Pretty.block [Pretty.command "theory", Pretty.brk 1,
haftmann@25607
    72
      Pretty.str (Context.theory_name (ProofContext.theory_of ctxt))] ::
haftmann@25607
    73
    (if not (null overloading) then [Overloading.pretty ctxt]
haftmann@29358
    74
     else if not (null (#1 instantiation)) then [Class_Target.pretty_instantiation ctxt]
wenzelm@32785
    75
     else pretty_thy ctxt target is_class);
haftmann@25607
    76
wenzelm@20894
    77
wenzelm@33456
    78
(* generic declarations *)
wenzelm@33456
    79
wenzelm@33456
    80
local
haftmann@24838
    81
wenzelm@33456
    82
fun direct_decl decl =
wenzelm@33456
    83
  let val decl0 = Morphism.form decl in
wenzelm@33671
    84
    Local_Theory.theory (Context.theory_map decl0) #>
wenzelm@33671
    85
    Local_Theory.target (Context.proof_map decl0)
wenzelm@33456
    86
  end;
wenzelm@33456
    87
wenzelm@33456
    88
fun target_decl add (Target {target, ...}) pervasive decl lthy =
haftmann@24838
    89
  let
wenzelm@33671
    90
    val global_decl = Morphism.transform (Local_Theory.global_morphism lthy) decl;
wenzelm@33671
    91
    val target_decl = Morphism.transform (Local_Theory.target_morphism lthy) decl;
haftmann@24838
    92
  in
wenzelm@25012
    93
    if target = "" then
haftmann@24838
    94
      lthy
haftmann@35127
    95
      |> direct_decl global_decl
haftmann@24838
    96
    else
haftmann@24838
    97
      lthy
wenzelm@33456
    98
      |> pervasive ? direct_decl global_decl
wenzelm@33671
    99
      |> Local_Theory.target (add target target_decl)
haftmann@24838
   100
  end;
haftmann@24838
   101
wenzelm@33456
   102
in
wenzelm@33456
   103
haftmann@29576
   104
val declaration = target_decl Locale.add_declaration;
wenzelm@35798
   105
val syntax_declaration = target_decl Locale.add_syntax_declaration;
haftmann@24838
   106
wenzelm@33456
   107
end;
wenzelm@33456
   108
wenzelm@25105
   109
fun class_target (Target {target, ...}) f =
wenzelm@33671
   110
  Local_Theory.raw_theory f #>
wenzelm@33671
   111
  Local_Theory.target (Class_Target.refresh_syntax target);
haftmann@24838
   112
wenzelm@21611
   113
wenzelm@20894
   114
(* notes *)
wenzelm@20894
   115
wenzelm@21611
   116
fun import_export_proof ctxt (name, raw_th) =
wenzelm@21594
   117
  let
wenzelm@21611
   118
    val thy = ProofContext.theory_of ctxt;
wenzelm@36610
   119
    val thy_ctxt = ProofContext.init_global thy;
wenzelm@21611
   120
    val certT = Thm.ctyp_of thy;
wenzelm@21611
   121
    val cert = Thm.cterm_of thy;
wenzelm@21594
   122
wenzelm@21611
   123
    (*export assumes/defines*)
wenzelm@21611
   124
    val th = Goal.norm_result raw_th;
wenzelm@35624
   125
    val (defs, th') = Local_Defs.export ctxt thy_ctxt th;
wenzelm@30473
   126
    val assms = map (MetaSimplifier.rewrite_rule defs o Thm.assume) (Assumption.all_assms_of ctxt);
wenzelm@21611
   127
    val nprems = Thm.nprems_of th' - Thm.nprems_of th;
wenzelm@21611
   128
wenzelm@21611
   129
    (*export fixes*)
wenzelm@22692
   130
    val tfrees = map TFree (Thm.fold_terms Term.add_tfrees th' []);
wenzelm@22692
   131
    val frees = map Free (Thm.fold_terms Term.add_frees th' []);
wenzelm@21611
   132
    val (th'' :: vs) = (th' :: map (Drule.mk_term o cert) (map Logic.mk_type tfrees @ frees))
wenzelm@21611
   133
      |> Variable.export ctxt thy_ctxt
wenzelm@21611
   134
      |> Drule.zero_var_indexes_list;
wenzelm@21611
   135
wenzelm@21611
   136
    (*thm definition*)
wenzelm@33700
   137
    val result = PureThy.name_thm true true name th'';
wenzelm@21611
   138
wenzelm@21611
   139
    (*import fixes*)
wenzelm@21611
   140
    val (tvars, vars) =
wenzelm@21611
   141
      chop (length tfrees) (map (Thm.term_of o Drule.dest_term) vs)
wenzelm@21611
   142
      |>> map Logic.dest_type;
wenzelm@21611
   143
wenzelm@21611
   144
    val instT = map_filter (fn (TVar v, T) => SOME (v, T) | _ => NONE) (tvars ~~ tfrees);
wenzelm@21611
   145
    val inst = filter (is_Var o fst) (vars ~~ frees);
wenzelm@21611
   146
    val cinstT = map (pairself certT o apfst TVar) instT;
wenzelm@31977
   147
    val cinst = map (pairself (cert o Term.map_types (Term_Subst.instantiateT instT))) inst;
wenzelm@21611
   148
    val result' = Thm.instantiate (cinstT, cinst) result;
wenzelm@21611
   149
wenzelm@21611
   150
    (*import assumes/defines*)
wenzelm@21594
   151
    val assm_tac = FIRST' (map (fn assm => Tactic.compose_tac (false, assm, 0)) assms);
wenzelm@21611
   152
    val result'' =
wenzelm@21611
   153
      (case SINGLE (Seq.INTERVAL assm_tac 1 nprems) result' of
wenzelm@21611
   154
        NONE => raise THM ("Failed to re-import result", 0, [result'])
wenzelm@35739
   155
      | SOME res => Local_Defs.contract ctxt defs (Thm.cprop_of th) res)
wenzelm@21644
   156
      |> Goal.norm_result
wenzelm@33700
   157
      |> PureThy.name_thm false false name;
wenzelm@21611
   158
wenzelm@21611
   159
  in (result'', result) end;
wenzelm@21611
   160
haftmann@38298
   161
fun theory_notes kind global_facts lthy =
haftmann@38294
   162
  let
haftmann@38294
   163
    val thy = ProofContext.theory_of lthy;
haftmann@38294
   164
    val global_facts' = Attrib.map_facts (Attrib.attribute_i thy) global_facts;
haftmann@38294
   165
  in
haftmann@38294
   166
    lthy
haftmann@38294
   167
    |> Local_Theory.theory (PureThy.note_thmss kind global_facts' #> snd)
haftmann@38294
   168
    |> Local_Theory.target (ProofContext.note_thmss kind global_facts' #> snd)
haftmann@38294
   169
  end;
haftmann@38294
   170
haftmann@38294
   171
fun locale_notes locale kind global_facts local_facts lthy = 
haftmann@38294
   172
  let
haftmann@38294
   173
    val global_facts' = Attrib.map_facts (K I) global_facts;
haftmann@38294
   174
    val local_facts' = Element.facts_map (Element.morph_ctxt (Local_Theory.target_morphism lthy)) local_facts;
haftmann@38294
   175
  in
haftmann@38294
   176
    lthy
haftmann@38294
   177
    |> Local_Theory.theory (PureThy.note_thmss kind global_facts' #> snd)
haftmann@38294
   178
    |> Local_Theory.target (Locale.add_thmss locale kind local_facts')
haftmann@38294
   179
  end
haftmann@38294
   180
haftmann@29576
   181
fun notes (Target {target, is_locale, ...}) kind facts lthy =
wenzelm@21585
   182
  let
wenzelm@21594
   183
    val thy = ProofContext.theory_of lthy;
wenzelm@21594
   184
    val facts' = facts
haftmann@28991
   185
      |> map (fn (a, bs) => (a, PureThy.burrow_fact (PureThy.name_multi
wenzelm@33671
   186
          (Local_Theory.full_name lthy (fst a))) bs))
wenzelm@21615
   187
      |> PureThy.map_facts (import_export_proof lthy);
haftmann@38293
   188
    val local_facts = PureThy.map_facts #1 facts';
haftmann@38294
   189
    val global_facts = PureThy.map_facts #2 facts';
wenzelm@21594
   190
  in
wenzelm@33167
   191
    lthy
haftmann@38294
   192
    |> (if is_locale then locale_notes target kind global_facts local_facts
haftmann@38298
   193
        else theory_notes kind global_facts)
haftmann@38293
   194
    |> ProofContext.note_thmss kind (Attrib.map_facts (Attrib.attribute_i thy) local_facts)
wenzelm@20894
   195
  end;
wenzelm@20894
   196
wenzelm@20894
   197
haftmann@38297
   198
(* consts in locales *)
haftmann@38297
   199
haftmann@38297
   200
fun locale_const (Target {target, is_class, ...}) (prmode as (mode, _)) ((b, mx), rhs) phi =
haftmann@38297
   201
  let
haftmann@38297
   202
    val b' = Morphism.binding phi b;
haftmann@38297
   203
    val rhs' = Morphism.term phi rhs;
haftmann@38297
   204
    val arg = (b', Term.close_schematic_term rhs');
haftmann@38297
   205
    val same_shape = Term.aconv_untyped (rhs, rhs');
haftmann@38297
   206
    (* FIXME workaround based on educated guess *)
haftmann@38297
   207
    val prefix' = Binding.prefix_of b';
haftmann@38297
   208
    val is_canonical_class = is_class andalso
haftmann@38297
   209
      (Binding.eq_name (b, b')
haftmann@38297
   210
        andalso not (null prefix')
haftmann@38297
   211
        andalso List.last prefix' = (Class_Target.class_prefix target, false)
haftmann@38297
   212
      orelse same_shape);
haftmann@38297
   213
  in
haftmann@38297
   214
    not is_canonical_class ?
haftmann@38297
   215
      (Context.mapping_result
haftmann@38297
   216
        (Sign.add_abbrev Print_Mode.internal arg)
haftmann@38297
   217
        (ProofContext.add_abbrev Print_Mode.internal arg)
haftmann@38297
   218
      #-> (fn (lhs' as Const (d, _), _) =>
haftmann@38297
   219
          same_shape ?
haftmann@38297
   220
            (Context.mapping (Sign.revert_abbrev mode d) (ProofContext.revert_abbrev mode d) #>
haftmann@38297
   221
             Morphism.form (ProofContext.target_notation true prmode [(lhs', mx)]))))
haftmann@38297
   222
  end;
haftmann@38297
   223
haftmann@38297
   224
wenzelm@37314
   225
(* mixfix notation *)
wenzelm@37314
   226
wenzelm@37314
   227
local
wenzelm@24939
   228
wenzelm@25105
   229
fun fork_mixfix (Target {is_locale, is_class, ...}) mx =
wenzelm@25105
   230
  if not is_locale then (NoSyn, NoSyn, mx)
wenzelm@25105
   231
  else if not is_class then (NoSyn, mx, NoSyn)
wenzelm@25105
   232
  else (mx, NoSyn, NoSyn);
wenzelm@25068
   233
wenzelm@37314
   234
in
wenzelm@37314
   235
wenzelm@37314
   236
fun prep_mixfix ctxt ta (b, extra_tfrees) mx =
wenzelm@37314
   237
  let
wenzelm@37314
   238
    val mx' =
wenzelm@37314
   239
      if null extra_tfrees then mx
wenzelm@37314
   240
      else
wenzelm@37314
   241
        (warning
wenzelm@37314
   242
          ("Additional type variable(s) in specification of " ^ Binding.str_of b ^ ": " ^
wenzelm@37314
   243
            commas (map (Syntax.string_of_typ ctxt o TFree) (sort_wrt #1 extra_tfrees)) ^
wenzelm@37314
   244
            (if mx = NoSyn then ""
wenzelm@37314
   245
             else "\nDropping mixfix syntax " ^ Pretty.string_of (Syntax.pretty_mixfix mx)));
wenzelm@37314
   246
          NoSyn);
wenzelm@37314
   247
  in fork_mixfix ta mx' end;
wenzelm@37314
   248
wenzelm@37314
   249
end;
wenzelm@37314
   250
wenzelm@37314
   251
wenzelm@24939
   252
(* abbrev *)
wenzelm@24939
   253
haftmann@38298
   254
fun theory_abbrev prmode ((b, mx), t) = Local_Theory.theory
haftmann@38298
   255
  (Sign.add_abbrev (#1 prmode) (b, t) #-> (fn (lhs, _) => Sign.notation true prmode [(lhs, mx)]));
haftmann@38298
   256
haftmann@38298
   257
fun locale_abbrev ta prmode ((b, mx), t) xs = Local_Theory.theory_result
haftmann@38298
   258
  (Sign.add_abbrev Print_Mode.internal (b, t)) #-> (fn (lhs, _) =>
haftmann@38298
   259
    syntax_declaration ta false (locale_const ta prmode ((b, mx), Term.list_comb (Logic.unvarify_global lhs, xs))));
haftmann@38298
   260
wenzelm@28083
   261
fun abbrev (ta as Target {target, is_locale, is_class, ...}) prmode ((b, mx), t) lthy =
wenzelm@24939
   262
  let
wenzelm@36610
   263
    val thy_ctxt = ProofContext.init_global (ProofContext.theory_of lthy);
wenzelm@33671
   264
    val target_ctxt = Local_Theory.target_of lthy;
wenzelm@25105
   265
wenzelm@25105
   266
    val t' = Assumption.export_term lthy target_ctxt t;
wenzelm@25105
   267
    val xs = map Free (rev (Variable.add_fixed target_ctxt t' []));
wenzelm@25105
   268
    val u = fold_rev lambda xs t';
wenzelm@37314
   269
wenzelm@37314
   270
    val extra_tfrees =
wenzelm@37314
   271
      subtract (op =) (Term.add_tfreesT (Term.fastype_of u) []) (Term.add_tfrees u []);
wenzelm@37314
   272
    val (mx1, mx2, mx3) = prep_mixfix lthy ta (b, extra_tfrees) mx;
wenzelm@37314
   273
wenzelm@25105
   274
    val global_rhs =
wenzelm@25105
   275
      singleton (Variable.export_terms (Variable.declare_term u target_ctxt) thy_ctxt) u;
wenzelm@25121
   276
  in
wenzelm@25121
   277
    lthy |>
haftmann@38298
   278
     (if is_locale then locale_abbrev ta prmode ((b, mx2), global_rhs) xs #>
haftmann@38298
   279
        is_class ? class_target ta (Class_Target.abbrev target prmode ((b, mx1), t'))
haftmann@38298
   280
      else theory_abbrev prmode ((b, mx3), global_rhs))
wenzelm@37146
   281
    |> ProofContext.add_abbrev Print_Mode.internal (b, t) |> snd
wenzelm@35624
   282
    |> Local_Defs.fixed_abbrev ((b, NoSyn), t)
wenzelm@24939
   283
  end;
wenzelm@24939
   284
wenzelm@24939
   285
wenzelm@25022
   286
(* define *)
wenzelm@24939
   287
wenzelm@35764
   288
local
wenzelm@35764
   289
wenzelm@35764
   290
fun syntax_error c = error ("Illegal mixfix syntax for overloaded constant " ^ quote c);
wenzelm@35764
   291
haftmann@38303
   292
fun foundation (ta as Target {target, is_locale, is_class, ...})
haftmann@38303
   293
    (((b, U), mx), rhs') name' params (extra_tfrees, type_params) lthy =
haftmann@38303
   294
  let
haftmann@38303
   295
    val (mx1, mx2, mx3) = prep_mixfix lthy ta (b, extra_tfrees) mx;
haftmann@38303
   296
    val (const, lthy2) = lthy |>
haftmann@38303
   297
      (case Class_Target.instantiation_param lthy b of
haftmann@38303
   298
        SOME c' =>
haftmann@38303
   299
          if mx3 <> NoSyn then syntax_error c'
haftmann@38303
   300
          else Local_Theory.theory_result (AxClass.declare_overloaded (c', U))
haftmann@38303
   301
            ##> Class_Target.confirm_declaration b
haftmann@38303
   302
      | NONE =>
haftmann@38303
   303
          (case Overloading.operation lthy b of
haftmann@38303
   304
            SOME (c', _) =>
haftmann@38303
   305
              if mx3 <> NoSyn then syntax_error c'
haftmann@38303
   306
              else Local_Theory.theory_result (Overloading.declare (c', U))
haftmann@38303
   307
                ##> Overloading.confirm b
haftmann@38303
   308
          | NONE => Local_Theory.theory_result (Sign.declare_const ((b, U), mx3))));
haftmann@38303
   309
    val Const (head, _) = const;
haftmann@38303
   310
    val lhs' = list_comb (const, params);
haftmann@38303
   311
  in
haftmann@38303
   312
    lthy2
haftmann@38303
   313
    |> pair lhs'
haftmann@38303
   314
    ||>> Local_Theory.theory_result
haftmann@38303
   315
      (case Overloading.operation lthy b of
haftmann@38303
   316
        SOME (_, checked) => Overloading.define checked name' (head, rhs')
haftmann@38303
   317
      | NONE =>
haftmann@38303
   318
          if is_some (Class_Target.instantiation_param lthy b)
haftmann@38303
   319
          then AxClass.define_overloaded name' (head, rhs')
haftmann@38303
   320
          else Thm.add_def false false (name', Logic.mk_equals (lhs', rhs')) #>> snd)
haftmann@38303
   321
    ||> is_locale ? syntax_declaration ta false (locale_const ta Syntax.mode_default ((b, mx2), lhs'))
haftmann@38303
   322
    ||> is_class ? class_target ta (Class_Target.declare target ((b, mx1), (type_params, lhs')))
haftmann@38303
   323
  end;
haftmann@38303
   324
wenzelm@35764
   325
in
wenzelm@35764
   326
haftmann@38303
   327
fun define ta ((b, mx), ((name, atts), rhs)) lthy =
wenzelm@24939
   328
  let
wenzelm@24987
   329
    val thy = ProofContext.theory_of lthy;
wenzelm@36610
   330
    val thy_ctxt = ProofContext.init_global thy;
wenzelm@24939
   331
wenzelm@30437
   332
    val name' = Thm.def_binding_optional b name;
wenzelm@35717
   333
haftmann@38302
   334
    (*term and type parameters*)
wenzelm@35717
   335
    val crhs = Thm.cterm_of thy rhs;
wenzelm@35717
   336
    val (defs, rhs') = Local_Defs.export_cterm lthy thy_ctxt crhs ||> Thm.term_of;
wenzelm@35717
   337
    val rhs_conv = MetaSimplifier.rewrite true defs crhs;
wenzelm@35717
   338
wenzelm@33671
   339
    val xs = Variable.add_fixed (Local_Theory.target_of lthy) rhs' [];
wenzelm@24939
   340
    val T = Term.fastype_of rhs;
wenzelm@35765
   341
    val tfreesT = Term.add_tfreesT T (fold (Term.add_tfreesT o #2) xs []);
wenzelm@37314
   342
    val extra_tfrees = rev (subtract (op =) tfreesT (Term.add_tfrees rhs []));
wenzelm@24939
   343
haftmann@38248
   344
    val type_params = map (Logic.mk_type o TFree) extra_tfrees;
haftmann@38248
   345
    val term_params =
haftmann@38248
   346
      rev (Variable.fixes_of (Local_Theory.target_of lthy))
haftmann@38248
   347
      |> map_filter (fn (_, x) =>
haftmann@38248
   348
        (case AList.lookup (op =) xs x of
haftmann@38248
   349
          SOME T => SOME (Free (x, T))
haftmann@38248
   350
        | NONE => NONE));
haftmann@38248
   351
    val params = type_params @ term_params;
haftmann@38248
   352
haftmann@38248
   353
    val U = map Term.fastype_of params ---> T;
haftmann@38301
   354
haftmann@38301
   355
    (*foundation*)
haftmann@38303
   356
    val ((lhs', global_def), lthy3) = foundation ta
haftmann@38303
   357
      (((b, U), mx), rhs') name' params (extra_tfrees, type_params) lthy;
haftmann@38301
   358
haftmann@38301
   359
    (*local definition*)
haftmann@38302
   360
    val ((lhs, local_def), lthy4) = lthy3
haftmann@38302
   361
      |> Local_Defs.add_def ((b, NoSyn), lhs');
haftmann@38248
   362
    val def = Local_Defs.trans_terms lthy4
wenzelm@25022
   363
      [(*c == global.c xs*)     local_def,
wenzelm@25022
   364
       (*global.c xs == rhs'*)  global_def,
haftmann@25485
   365
       (*rhs' == rhs*)          Thm.symmetric rhs_conv];
wenzelm@24939
   366
wenzelm@25105
   367
    (*note*)
haftmann@38248
   368
    val ([(res_name, [res])], lthy5) = lthy4
haftmann@38300
   369
      |> Local_Theory.notes_kind "" [((name', atts), [([def], [])])];
haftmann@38248
   370
  in ((lhs, (res_name, res)), lthy5) end;
wenzelm@24939
   371
wenzelm@35764
   372
end;
wenzelm@35764
   373
wenzelm@24939
   374
wenzelm@35205
   375
(* init various targets *)
wenzelm@25291
   376
wenzelm@25291
   377
local
wenzelm@20894
   378
haftmann@38247
   379
fun init_data (Target {target, is_locale, is_class, instantiation, overloading}) =
haftmann@29358
   380
  if not (null (#1 instantiation)) then Class_Target.init_instantiation instantiation
haftmann@25519
   381
  else if not (null overloading) then Overloading.init overloading
wenzelm@36610
   382
  else if not is_locale then ProofContext.init_global
haftmann@29576
   383
  else if not is_class then Locale.init target
haftmann@29358
   384
  else Class_Target.init target;
haftmann@25269
   385
haftmann@38247
   386
fun init_target (ta as Target {target, instantiation, overloading, ...}) thy =
haftmann@38247
   387
  thy
haftmann@38247
   388
  |> init_data ta
haftmann@38247
   389
  |> Data.put ta
haftmann@38247
   390
  |> Local_Theory.init NONE (Long_Name.base_name target)
haftmann@38247
   391
     {pretty = pretty ta,
haftmann@38247
   392
      abbrev = abbrev ta,
haftmann@38247
   393
      define = define ta,
haftmann@38247
   394
      notes = notes ta,
haftmann@38247
   395
      declaration = declaration ta,
haftmann@38247
   396
      syntax_declaration = syntax_declaration ta,
haftmann@38247
   397
      reinit = init_target ta o ProofContext.theory_of,
haftmann@38247
   398
      exit = Local_Theory.target_of o
haftmann@38247
   399
        (if not (null (#1 instantiation)) then Class_Target.conclude_instantiation
haftmann@38247
   400
         else if not (null overloading) then Overloading.conclude
haftmann@38247
   401
         else I)};
haftmann@38247
   402
haftmann@38247
   403
fun named_target _ NONE = global_target
haftmann@38247
   404
  | named_target thy (SOME target) =
haftmann@38247
   405
      if Locale.defined thy target
haftmann@38247
   406
      then make_target target true (Class_Target.is_class thy target) ([], [], []) []
haftmann@38247
   407
      else error ("No such locale: " ^ quote target);
wenzelm@20894
   408
wenzelm@26049
   409
fun gen_overloading prep_const raw_ops thy =
wenzelm@26049
   410
  let
wenzelm@36610
   411
    val ctxt = ProofContext.init_global thy;
wenzelm@26049
   412
    val ops = raw_ops |> map (fn (name, const, checked) =>
wenzelm@26049
   413
      (name, Term.dest_Const (prep_const ctxt const), checked));
haftmann@38247
   414
  in thy |> init_target (make_target "" false false ([], [], []) ops) end;
wenzelm@26049
   415
wenzelm@25291
   416
in
wenzelm@20894
   417
haftmann@38247
   418
fun init target thy = init_target (named_target thy target) thy;
haftmann@25269
   419
wenzelm@35205
   420
fun context_cmd "-" thy = init NONE thy
wenzelm@35205
   421
  | context_cmd target thy = init (SOME (Locale.intern thy target)) thy;
wenzelm@33282
   422
haftmann@38247
   423
fun instantiation arities = init_target (make_target "" false false arities []);
wenzelm@35205
   424
fun instantiation_cmd arities thy = instantiation (Class_Target.read_multi_arity thy arities) thy;
haftmann@25519
   425
wenzelm@26049
   426
val overloading = gen_overloading (fn ctxt => Syntax.check_term ctxt o Const);
wenzelm@26049
   427
val overloading_cmd = gen_overloading Syntax.read_term;
haftmann@25462
   428
wenzelm@20894
   429
end;
wenzelm@25291
   430
wenzelm@25291
   431
end;
wenzelm@25291
   432