src/Pure/Isar/locale.ML
changeset 12510 172d18ec3b54
parent 12502 9e7f72e25022
child 12514 4bdbc5a977f6
equal deleted inserted replaced
12509:b461efcfc886 12510:172d18ec3b54
    30   val intern: Sign.sg -> xstring -> string
    30   val intern: Sign.sg -> xstring -> string
    31   val cond_extern: Sign.sg -> string -> xstring
    31   val cond_extern: Sign.sg -> string -> xstring
    32   val the_locale: theory -> string -> locale
    32   val the_locale: theory -> string -> locale
    33   val attribute: ('att -> context attribute) -> ('typ, 'term, 'thm, 'att) elem_expr
    33   val attribute: ('att -> context attribute) -> ('typ, 'term, 'thm, 'att) elem_expr
    34     -> ('typ, 'term, 'thm, context attribute) elem_expr
    34     -> ('typ, 'term, 'thm, context attribute) elem_expr
    35   val activate_context: context -> expr * context attribute element list ->
    35   val activate_context: expr * context attribute element list -> context -> context * context
    36    (context -> context) * (context -> context)
    36   val activate_context_i: expr * context attribute element_i list -> context -> context * context
    37   val activate_context_i: context -> expr * context attribute element_i list ->
       
    38    (context -> context) * (context -> context)
       
    39   val add_locale: bstring -> expr -> context attribute element list -> theory -> theory
    37   val add_locale: bstring -> expr -> context attribute element list -> theory -> theory
    40   val add_locale_i: bstring -> expr -> context attribute element_i list -> theory -> theory
    38   val add_locale_i: bstring -> expr -> context attribute element_i list -> theory -> theory
    41   val print_locales: theory -> unit
    39   val print_locales: theory -> unit
    42   val print_locale: theory -> expr -> unit
    40   val print_locale: theory -> expr -> unit
    43   val add_thmss: string -> ((string * thm list) * context attribute list) list -> theory -> theory
    41   val add_thmss: string -> ((string * thm list) * context attribute list) list -> theory -> theory
    44   val setup: (theory -> theory) list
    42   val setup: (theory -> theory) list
    45 end;
    43 end;
    46 
    44 
    47 structure Locale: LOCALE =
    45 structure Locale: LOCALE =
    48 struct
    46 struct
    49 
       
    50 
       
    51 
    47 
    52 (** locale elements and expressions **)
    48 (** locale elements and expressions **)
    53 
    49 
    54 type context = ProofContext.context;
    50 type context = ProofContext.context;
    55 
    51 
   140 
   136 
   141 
   137 
   142 
   138 
   143 (** operations on locale elements **)
   139 (** operations on locale elements **)
   144 
   140 
       
   141 (* misc utilities *)
       
   142 
       
   143 fun frozen_tvars ctxt Ts =
       
   144   let
       
   145     val tvars = rev (foldl Term.add_tvarsT ([], Ts));
       
   146     val tfrees = map TFree
       
   147       (Term.invent_type_names (ProofContext.used_types ctxt) (length tvars) ~~ map #2 tvars);
       
   148   in map #1 tvars ~~ tfrees end;
       
   149 
       
   150 fun fixes_of_elemss elemss = flat (map (snd o fst) elemss);
       
   151 
       
   152 
   145 (* prepare elements *)
   153 (* prepare elements *)
       
   154 
       
   155 datatype fact = Int of thm list | Ext of string;
   146 
   156 
   147 local
   157 local
   148 
   158 
   149 fun prep_name ctxt (name, atts) =
   159 fun prep_name ctxt (name, atts) =
   150   if NameSpace.is_qualified name then
   160   if NameSpace.is_qualified name then
   164   | Notes facts =>
   174   | Notes facts =>
   165       Notes (map (fn (a, bs) => (prep_name ctxt a, map (apfst (prep_thms ctxt)) bs)) facts);
   175       Notes (map (fn (a, bs) => (prep_name ctxt a, map (apfst (prep_thms ctxt)) bs)) facts);
   166 
   176 
   167 in
   177 in
   168 
   178 
   169 fun read_elem x = prep_elem ProofContext.read_vars ProofContext.read_propp ProofContext.get_thms x;
   179 fun read_elem x = prep_elem ProofContext.read_vars ProofContext.read_propp (K I) x;
   170 fun cert_elem x = prep_elem ProofContext.cert_vars ProofContext.cert_propp (K I) x;
   180 fun cert_elem x = prep_elem ProofContext.cert_vars ProofContext.cert_propp (K I) x;
       
   181 fun int_facts x = prep_elem I I (K Int) x;
       
   182 fun ext_facts x = prep_elem I I (K Ext) x;
       
   183 fun get_facts x = prep_elem I I
       
   184   (fn ctxt => (fn Int ths => ths | Ext name => ProofContext.get_thms ctxt name)) x;
   171 
   185 
   172 fun read_expr ctxt (Locale xname) = Locale (intern (ProofContext.sign_of ctxt) xname)
   186 fun read_expr ctxt (Locale xname) = Locale (intern (ProofContext.sign_of ctxt) xname)
   173   | read_expr ctxt (Merge exprs) = Merge (map (read_expr ctxt) exprs)
   187   | read_expr ctxt (Merge exprs) = Merge (map (read_expr ctxt) exprs)
   174   | read_expr ctxt (Rename (expr, xs)) = Rename (read_expr ctxt expr, xs);
   188   | read_expr ctxt (Rename (expr, xs)) = Rename (read_expr ctxt expr, xs);
   175 
       
   176 fun read_element ctxt (Elem e) = Elem (read_elem ctxt e)
       
   177   | read_element ctxt (Expr e) = Expr (read_expr ctxt e);
       
   178 
       
   179 fun cert_element ctxt (Elem e) = Elem (cert_elem ctxt e)
       
   180   | cert_element ctxt (Expr e) = Expr e;
       
   181 
   189 
   182 end;
   190 end;
   183 
   191 
   184 
   192 
   185 (* internalize attributes *)
   193 (* internalize attributes *)
   282   | inst_elem env (Notes facts) = Notes (map (apsnd (map (apfst (map (inst_thm env))))) facts);
   290   | inst_elem env (Notes facts) = Notes (map (apsnd (map (apfst (map (inst_thm env))))) facts);
   283 
   291 
   284 
   292 
   285 (* evaluation *)
   293 (* evaluation *)
   286 
   294 
   287 fun frozen_tvars ctxt Ts =
   295 local
   288   let
       
   289     val tvars = rev (foldl Term.add_tvarsT ([], Ts));
       
   290     val tfrees = map TFree
       
   291       (Term.invent_type_names (ProofContext.used_types ctxt) (length tvars) ~~ map #2 tvars);
       
   292   in map #1 tvars ~~ tfrees end;
       
   293 
   296 
   294 fun unify_parms ctxt raw_parmss =
   297 fun unify_parms ctxt raw_parmss =
   295   let
   298   let
   296     val tsig = Sign.tsig_of (ProofContext.sign_of ctxt);
   299     val tsig = Sign.tsig_of (ProofContext.sign_of ctxt);
   297     val maxidx = length raw_parmss;
   300     val maxidx = length raw_parmss;
   336         val envs = unify_parms ctxt (map (#2 o #1) elemss);
   339         val envs = unify_parms ctxt (map (#2 o #1) elemss);
   337         fun inst (((name, ps), elems), env) =
   340         fun inst (((name, ps), elems), env) =
   338           ((name, map (apsnd (apsome (inst_type env))) ps), map (inst_elem env) elems);
   341           ((name, map (apsnd (apsome (inst_type env))) ps), map (inst_elem env) elems);
   339       in map inst (elemss ~~ envs) end;
   342       in map inst (elemss ~~ envs) end;
   340 
   343 
       
   344 in
   341 
   345 
   342 fun eval_expr ctxt expr =
   346 fun eval_expr ctxt expr =
   343   let
   347   let
   344     val thy = ProofContext.theory_of ctxt;
   348     val thy = ProofContext.theory_of ctxt;
   345 
   349 
   387 
   391 
   388     val raw_elemss = unique_parms ctxt (map eval (#1 (identify (([], []), expr))));
   392     val raw_elemss = unique_parms ctxt (map eval (#1 (identify (([], []), expr))));
   389     val elemss = inst_types ctxt raw_elemss;
   393     val elemss = inst_types ctxt raw_elemss;
   390   in elemss end;
   394   in elemss end;
   391 
   395 
       
   396 end;
       
   397 
   392 
   398 
   393 
   399 
   394 (** activation **)
   400 (** activation **)
   395 
   401 
   396 (* internalize elems *)
   402 (* internalize elems *)
       
   403 
       
   404 local
       
   405 
       
   406 fun perform_elems f named_elems = ProofContext.qualified (fn context =>
       
   407   foldl (fn (ctxt, ((name, ps), es)) =>
       
   408     foldl (fn (c, e) => f e c) (ctxt, es) handle ProofContext.CONTEXT (msg, ctxt) =>
       
   409       err_in_locale ctxt msg [(name, map fst ps)]) (context, named_elems));
       
   410 
       
   411 in
   397 
   412 
   398 fun declare_elem gen =
   413 fun declare_elem gen =
   399   let
   414   let
   400     val gen_typ = if gen then Term.map_type_tfree (Type.param []) else I;
   415     val gen_typ = if gen then Term.map_type_tfree (Type.param []) else I;
   401     val gen_term = if gen then Term.map_term_types gen_typ else I;
   416     val gen_term = if gen then Term.map_term_types gen_typ else I;
   419       (map (fn ((name, atts), (t, ps)) =>
   434       (map (fn ((name, atts), (t, ps)) =>
   420         let val (c, t') = ProofContext.cert_def ctxt t
   435         let val (c, t') = ProofContext.cert_def ctxt t
   421         in ((if name = "" then Thm.def_name c else name, atts), [(t', (ps, []))]) end) defs) ctxt))
   436         in ((if name = "" then Thm.def_name c else name, atts), [(t', (ps, []))]) end) defs) ctxt))
   422   | activate_elem (Notes facts) = #1 o ProofContext.have_thmss facts;
   437   | activate_elem (Notes facts) = #1 o ProofContext.have_thmss facts;
   423 
   438 
   424 
       
   425 fun perform_elems f named_elems = ProofContext.qualified (fn context =>
       
   426   foldl (fn (ctxt, ((name, ps), es)) =>
       
   427     foldl (fn (c, e) => f e c) (ctxt, es) handle ProofContext.CONTEXT (msg, ctxt) =>
       
   428       err_in_locale ctxt msg [(name, map fst ps)]) (context, named_elems));
       
   429 
       
   430 fun declare_elemss gen = perform_elems (declare_elem gen);
   439 fun declare_elemss gen = perform_elems (declare_elem gen);
   431 fun activate_elemss x = perform_elems activate_elem x;
   440 fun activate_elemss x = perform_elems activate_elem x;
       
   441 
       
   442 end;
   432 
   443 
   433 
   444 
   434 (* context specifications: import expression + external elements *)
   445 (* context specifications: import expression + external elements *)
   435 
   446 
   436 local
   447 local
   444       (a, map (fn (t, _) => (close_frees ctxt t, ([], []))) propps)))
   455       (a, map (fn (t, _) => (close_frees ctxt t, ([], []))) propps)))
   445   | closeup ctxt (Defines defs) = Defines (defs |> map (fn (a, (t, _)) =>
   456   | closeup ctxt (Defines defs) = Defines (defs |> map (fn (a, (t, _)) =>
   446       (a, (close_frees ctxt (#2 (ProofContext.cert_def ctxt t)), []))))
   457       (a, (close_frees ctxt (#2 (ProofContext.cert_def ctxt t)), []))))
   447   | closeup ctxt elem = elem;
   458   | closeup ctxt elem = elem;
   448 
   459 
   449 fun prepare_context prep_elem prep_expr close context (import, elements) =
   460 fun fixes_of_elem (Fixes fixes) = map (fn (x, T, _) => (x, T)) fixes
   450   let
   461   | fixes_of_elem _ = [];
   451     fun prep_element (ctxt, Elem raw_elem) =
   462 
   452           let val elem = (if close then closeup ctxt else I) (prep_elem ctxt raw_elem)
   463 fun prepare_context prep_expr prep_elem1 prep_elem2 close (import, elements) context =
   453           in (ctxt |> declare_elem false elem, [(("", []), [elem])]) end
   464   let
   454       | prep_element (ctxt, Expr raw_expr) =
   465     fun declare_expr (c, raw_expr) =
       
   466       let
       
   467         val expr = prep_expr c raw_expr;
       
   468         val named_elemss = eval_expr c expr;
       
   469       in (c |> declare_elemss true named_elemss, named_elemss) end;
       
   470 
       
   471     fun declare_element (c, Elem raw_elem) =
   455           let
   472           let
   456             val expr = prep_expr ctxt raw_expr;
   473             val elem = (if close then closeup c else I) (prep_elem2 c (prep_elem1 c raw_elem));
   457             val named_elemss = eval_expr ctxt expr;
   474             val res = [(("", fixes_of_elem elem), [elem])];
   458           in (ctxt |> declare_elemss true named_elemss, named_elemss) end;
   475           in (c |> declare_elemss false res, res) end
   459 
   476       | declare_element (c, Expr raw_expr) =
   460     val (import_ctxt, import_elemss) = prep_element (context, Expr import);
   477           apsnd (map (apsnd (map (int_facts c)))) (declare_expr (c, raw_expr));
   461     val (elements_ctxt, elements_elemss) =
   478 
   462       apsnd flat (foldl_map prep_element (import_ctxt, elements));
   479     fun activate_elems (c, ((name, ps), raw_elems)) =
   463 
   480       let
   464     val xs = flat (map (map #1 o (#2 o #1)) (import_elemss @ elements_elemss));
   481         val elems = map (get_facts c) raw_elems;
   465     val env = frozen_tvars elements_ctxt (mapfilter (ProofContext.default_type elements_ctxt) xs);
   482         val res = ((name, ps), elems);
   466 
   483       in (c |> activate_elemss [res], res) end;
   467     fun inst_elems ((name, ps), elems) = ((name, ps), elems);  (* FIXME *)
   484 
   468 
   485     val (import_ctxt, import_elemss) = declare_expr (context, import);
   469   in (map inst_elems import_elemss, map inst_elems elements_elemss) end;
   486     val (ctxt, elemss) = apsnd flat (foldl_map declare_element (import_ctxt, elements));
   470 
   487     val type_env = frozen_tvars ctxt (mapfilter (ProofContext.default_type ctxt o #1)
   471 fun gen_activate_context prep_elem prep_expr ctxt args =
   488       (fixes_of_elemss import_elemss @ fixes_of_elemss elemss));
   472   pairself activate_elemss (prepare_context prep_elem prep_expr false ctxt args);
   489     val FIXME = PolyML.print type_env;
       
   490 
       
   491     fun inst_elems ((name, ps), elems) = ((name, ps), elems);    (* FIXME *)
       
   492 
       
   493     val import_elemss' = map inst_elems import_elemss;
       
   494     val import_ctxt' = context |> activate_elemss import_elemss';
       
   495     val (ctxt', elemss') = foldl_map activate_elems (import_ctxt', map inst_elems elemss);
       
   496   in ((import_ctxt', import_elemss'), (ctxt', elemss')) end;
       
   497 
       
   498 val prep_context = prepare_context read_expr read_elem ext_facts;
       
   499 val prep_context_i = prepare_context (K I) cert_elem int_facts;
   473 
   500 
   474 in
   501 in
   475 
   502 
   476 val read_context = prepare_context read_elem read_expr true;
   503 val read_context = prep_context true;
   477 val cert_context = prepare_context cert_elem (K I) true;
   504 val cert_context = prep_context_i true;
   478 val activate_context = gen_activate_context read_elem read_expr;
   505 val activate_context = pairself fst oo prep_context false;
   479 val activate_context_i = gen_activate_context cert_elem (K I);
   506 val activate_context_i = pairself fst oo prep_context_i false;
   480 
   507 fun activate_locale name = #1 o activate_context_i (Locale name, []);
   481 fun activate_locale name ctxt =
       
   482   #1 (activate_context_i ctxt (Locale name, [])) ctxt;
       
   483 
   508 
   484 end;
   509 end;
   485 
   510 
   486 
   511 
   487 
   512 
   489 
   514 
   490 fun print_locale thy raw_expr =
   515 fun print_locale thy raw_expr =
   491   let
   516   let
   492     val sg = Theory.sign_of thy;
   517     val sg = Theory.sign_of thy;
   493     val thy_ctxt = ProofContext.init thy;
   518     val thy_ctxt = ProofContext.init thy;
   494 
   519     val (ctxt, elemss) = #1 (read_context (raw_expr, []) thy_ctxt);
   495     val elemss = #1 (read_context thy_ctxt (raw_expr, []));
       
   496     val ctxt = activate_elemss elemss thy_ctxt;
       
   497 
   520 
   498     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
   521     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
   499     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
   522     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
   500     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
   523     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
   501 
   524 
   538     val name = Sign.full_name sign bname;
   561     val name = Sign.full_name sign bname;
   539     val _ = conditional (is_some (get_locale thy name)) (fn () =>
   562     val _ = conditional (is_some (get_locale thy name)) (fn () =>
   540       error ("Duplicate definition of locale " ^ quote name));
   563       error ("Duplicate definition of locale " ^ quote name));
   541 
   564 
   542     val thy_ctxt = ProofContext.init thy;
   565     val thy_ctxt = ProofContext.init thy;
   543 
   566     val ((import_ctxt, import_elemss), (body_ctxt, body_elemss)) =
   544     val (import_elemss, body_elemss) = prep_context thy_ctxt (raw_import, raw_body);
   567       prep_context (raw_import, raw_body) thy_ctxt;
   545     val import = prep_expr thy_ctxt raw_import;
   568     val import_parms = fixes_of_elemss import_elemss;
   546     val import_elemss = eval_expr thy_ctxt import;
   569     val import = (prep_expr thy_ctxt raw_import);
   547 
   570 
   548     val import_ctxt = thy_ctxt |> activate_elemss import_elemss;
   571     val elems = flat (map snd body_elemss);
   549     val body_ctxt = import_ctxt |> activate_elemss body_elemss;
   572     val body_parms = fixes_of_elemss body_elemss;
   550 
       
   551     val elems = flat (map #2 body_elemss);
       
   552     val (import_parms, body_parms) = pairself (flat o map (#2 o #1)) (import_elemss, body_elemss);
       
   553     val text = ([], []);  (* FIXME *)
   573     val text = ([], []);  (* FIXME *)
   554   in
   574   in
   555     thy
   575     thy
   556     |> declare_locale name
   576     |> declare_locale name
   557     |> put_locale name (make_locale import (map (fn e => (e, stamp ())) elems)
   577     |> put_locale name (make_locale import (map (fn e => (e, stamp ())) elems)