src/Pure/Isar/locale.ML
changeset 16102 c5f6726d9bb1
parent 16028 a2c790d145ba
child 16103 323838df22fd
equal deleted inserted replaced
16101:37471d84d353 16102:c5f6726d9bb1
    26     Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
    26     Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
    27     Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
    27     Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
    28     Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list
    28     Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list
    29   datatype expr =
    29   datatype expr =
    30     Locale of string |
    30     Locale of string |
    31     Rename of expr * string option list |
    31     Rename of expr * (string * mixfix option) option list |
    32     Merge of expr list
    32     Merge of expr list
    33   val empty: expr
    33   val empty: expr
    34   datatype 'a elem_expr = Elem of 'a | Expr of expr
    34   datatype 'a elem_expr = Elem of 'a | Expr of expr
    35 
    35 
    36   (* Abstract interface to locales *)
    36   (* Abstract interface to locales *)
   105   Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
   105   Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
   106   Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list;
   106   Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list;
   107 
   107 
   108 datatype expr =
   108 datatype expr =
   109   Locale of string |
   109   Locale of string |
   110   Rename of expr * string option list |
   110   Rename of expr * (string * mixfix option) option list |
   111   Merge of expr list;
   111   Merge of expr list;
   112 
   112 
   113 val empty = Merge [];
   113 val empty = Merge [];
   114 
   114 
   115 datatype 'a elem_expr =
   115 datatype 'a elem_expr =
   129        from the locale predicate to the normalised assumptions of the locale
   129        from the locale predicate to the normalised assumptions of the locale
   130        (cf. [1], normalisation of locale expressions.)
   130        (cf. [1], normalisation of locale expressions.)
   131     *)
   131     *)
   132   import: expr,                                       (*dynamic import*)
   132   import: expr,                                       (*dynamic import*)
   133   elems: (element_i * stamp) list,                    (*static content*)
   133   elems: (element_i * stamp) list,                    (*static content*)
   134   params: (string * typ option) list * string list}   (*all/local params*)
   134   params: ((string * typ option) * mixfix option) list * string list}
       
   135                                                       (*all/local params*)
   135 
   136 
   136 
   137 
   137 (* CB: an internal (Int) locale element was either imported or included,
   138 (* CB: an internal (Int) locale element was either imported or included,
   138    an external (Ext) element appears directly in the locale text. *)
   139    an external (Ext) element appears directly in the locale text. *)
   139 
   140 
   253           | ut (s $ t) ts = ut s (t::ts)
   254           | ut (s $ t) ts = ut s (t::ts)
   254     in ut t [] end;
   255     in ut t [] end;
   255 
   256 
   256   (* joining of registrations: prefix and attributs of left theory,
   257   (* joining of registrations: prefix and attributs of left theory,
   257      thms are equal, no attempt to subsumption testing *)
   258      thms are equal, no attempt to subsumption testing *)
   258   fun join x = Termtab.join (fn (reg, _) => SOME reg) x;
   259   fun join (r1, r2) = Termtab.join (fn (reg, _) => SOME reg) (r1, r2);
   259 
   260 
   260   fun dest regs = map (apfst untermify) (Termtab.dest regs);
   261   fun dest regs = map (apfst untermify) (Termtab.dest regs);
   261 
   262 
   262   (* registrations that subsume t *)
   263   (* registrations that subsume t *)
   263   fun subsumers tsig t regs =
   264   fun subsumers tsig t regs =
   588   | intern_attrib_elem_expr _ (Expr expr) = Expr expr;
   589   | intern_attrib_elem_expr _ (Expr expr) = Expr expr;
   589 
   590 
   590 
   591 
   591 (* renaming *)
   592 (* renaming *)
   592 
   593 
   593 fun rename ren x = getOpt (assoc_string (ren, x), x);
   594 (* ren maps names to (new) names and syntax; represented as association list *)
   594 
   595 
   595 fun rename_var ren (x, mx) =
   596 fun rename_var ren (x, mx) =
   596   let val x' = rename ren x in
   597   case assoc_string (ren, x) of
   597     if x = x' then (x, mx)
   598       NONE => (x, mx)
   598     else (x', if mx = NONE then mx else SOME Syntax.NoSyn)    (*drop syntax*)
   599     | SOME (x', NONE) =>
   599   end;
   600         (x', if mx = NONE then mx else SOME Syntax.NoSyn)     (*drop syntax*)
       
   601     | SOME (x', SOME mx') =>
       
   602         if mx = NONE then raise ERROR_MESSAGE
       
   603           ("Attempt to change syntax of structure parameter " ^ quote x)
       
   604         else (x', SOME mx');                                (*change syntax*)
       
   605 
       
   606 fun rename ren x =
       
   607   case assoc_string (ren, x) of
       
   608       NONE => x
       
   609     | SOME (x', _) => x';                                   (*ignore syntax*)
   600 
   610 
   601 fun rename_term ren (Free (x, T)) = Free (rename ren x, T)
   611 fun rename_term ren (Free (x, T)) = Free (rename ren x, T)
   602   | rename_term ren (t $ u) = rename_term ren t $ rename_term ren u
   612   | rename_term ren (t $ u) = rename_term ren t $ rename_term ren u
   603   | rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t)
   613   | rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t)
   604   | rename_term _ a = a;
   614   | rename_term _ a = a;
   722     val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (List.mapPartial I Vs));
   732     val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (List.mapPartial I Vs));
   723   in map (Option.map (Envir.norm_type unifier')) Vs end;
   733   in map (Option.map (Envir.norm_type unifier')) Vs end;
   724 
   734 
   725 fun params_of elemss = gen_distinct eq_fst (List.concat (map (snd o fst) elemss));
   735 fun params_of elemss = gen_distinct eq_fst (List.concat (map (snd o fst) elemss));
   726 fun params_of' elemss = gen_distinct eq_fst (List.concat (map (snd o fst o fst) elemss));
   736 fun params_of' elemss = gen_distinct eq_fst (List.concat (map (snd o fst o fst) elemss));
       
   737 fun params_syn_of syn elemss =
       
   738   gen_distinct eq_fst (List.concat (map (snd o fst) elemss)) |>
       
   739     map (apfst (fn x => (x, valOf (Symtab.lookup (syn, x)))));
       
   740 
   727 
   741 
   728 (* CB: param_types has the following type:
   742 (* CB: param_types has the following type:
   729   ('a * 'b option) list -> ('a * 'b) list *)
   743   ('a * 'b option) list -> ('a * 'b) list *)
   730 fun param_types ps = List.mapPartial (fn (_, NONE) => NONE | (x, SOME T) => SOME (x, T)) ps;
   744 fun param_types ps = List.mapPartial (fn (_, NONE) => NONE | (x, SOME T) => SOME (x, T)) ps;
       
   745 
       
   746 
       
   747 fun merge_syntax ctxt ids ss = Symtab.merge (op =) ss
       
   748   handle Symtab.DUPS xs => err_in_locale ctxt
       
   749     ("Conflicting syntax for parameter(s): " ^ commas_quote xs) (map #1 ids);
   731 
   750 
   732 
   751 
   733 (* flatten expressions *)
   752 (* flatten expressions *)
   734 
   753 
   735 local
   754 local
   749       SOME (q, ids) => err_in_locale ctxt ("Multiple declaration of parameter " ^ quote q)
   768       SOME (q, ids) => err_in_locale ctxt ("Multiple declaration of parameter " ^ quote q)
   750           (map (apsnd (map fst)) ids)
   769           (map (apsnd (map fst)) ids)
   751     | NONE => map (apfst (apfst (apsnd #1))) elemss)
   770     | NONE => map (apfst (apfst (apsnd #1))) elemss)
   752   end;
   771   end;
   753 
   772 
   754 (* CB: unify_parms has the following type:
   773 fun unify_parms ctxt (fixed_parms : (string * typ) list)
   755      ProofContext.context ->
   774   (raw_parmss : (string * typ option) list list) =
   756      (string * Term.typ) list ->
       
   757      (string * Term.typ option) list list ->
       
   758      ((string * Term.sort) * Term.typ) list list *)
       
   759 
       
   760 fun unify_parms ctxt fixed_parms raw_parmss =
       
   761   let
   775   let
   762     val sign = ProofContext.sign_of ctxt;
   776     val sign = ProofContext.sign_of ctxt;
   763     val tsig = Sign.tsig_of sign;
   777     val tsig = Sign.tsig_of sign;
   764     val maxidx = length raw_parmss;
   778     val maxidx = length raw_parmss;
   765     val idx_parmss = (0 upto maxidx - 1) ~~ raw_parmss;
   779     val idx_parmss = (0 upto maxidx - 1) ~~ raw_parmss;
   786     fun inst_parms (i, ps) =
   800     fun inst_parms (i, ps) =
   787       foldr Term.add_typ_tfrees [] (List.mapPartial snd ps)
   801       foldr Term.add_typ_tfrees [] (List.mapPartial snd ps)
   788       |> List.mapPartial (fn (a, S) =>
   802       |> List.mapPartial (fn (a, S) =>
   789           let val T = Envir.norm_type unifier' (TVar ((a, i), S))
   803           let val T = Envir.norm_type unifier' (TVar ((a, i), S))
   790           in if T = TFree (a, S) then NONE else SOME ((a, S), T) end)
   804           in if T = TFree (a, S) then NONE else SOME ((a, S), T) end)
   791   in map inst_parms idx_parmss end;
   805   in map inst_parms idx_parmss end : ((string * Term.sort) * Term.typ) list list;
   792 
   806 
   793 in
   807 in
   794 
       
   795 (* like unify_elemss, but does not touch axioms *)
       
   796 
       
   797 fun unify_elemss' _ _ [] = []
       
   798   | unify_elemss' _ [] [elems] = [elems]
       
   799   | unify_elemss' ctxt fixed_parms elemss =
       
   800       let
       
   801         val envs = unify_parms ctxt fixed_parms (map (#2 o #1 o #1) elemss);
       
   802         fun inst ((((name, ps), axs), elems), env) =
       
   803           (((name, map (apsnd (Option.map (inst_type env))) ps),  axs),
       
   804            map (inst_elem ctxt env) elems);
       
   805       in map inst (elemss ~~ envs) end;
       
   806 
   808 
   807 fun unify_elemss _ _ [] = []
   809 fun unify_elemss _ _ [] = []
   808   | unify_elemss _ [] [elems] = [elems]
   810   | unify_elemss _ [] [elems] = [elems]
   809   | unify_elemss ctxt fixed_parms elemss =
   811   | unify_elemss ctxt fixed_parms elemss =
   810       let
   812       let
   812         fun inst ((((name, ps), axs), elems), env) =
   814         fun inst ((((name, ps), axs), elems), env) =
   813           (((name, map (apsnd (Option.map (inst_type env))) ps), 
   815           (((name, map (apsnd (Option.map (inst_type env))) ps), 
   814             map (inst_thm ctxt env) axs), map (inst_elem ctxt env) elems);
   816             map (inst_thm ctxt env) axs), map (inst_elem ctxt env) elems);
   815       in map inst (elemss ~~ envs) end;
   817       in map inst (elemss ~~ envs) end;
   816 
   818 
       
   819 (* like unify_elemss, but does not touch axioms,
       
   820    additional parameter for enforcing further constraints (eg. syntax) *)
       
   821 
       
   822 fun unify_elemss' _ _ [] [] = []
       
   823   | unify_elemss' _ [] [elems] [] = [elems]
       
   824   | unify_elemss' ctxt fixed_parms elemss c_parms =
       
   825       let
       
   826         val envs = unify_parms ctxt fixed_parms (map (#2 o #1 o #1) elemss @ map single c_parms);
       
   827         fun inst ((((name, ps), axs), elems), env) =
       
   828           (((name, map (apsnd (Option.map (inst_type env))) ps),  axs),
       
   829            map (inst_elem ctxt env) elems);
       
   830       in map inst (elemss ~~ (Library.take (length elemss, envs))) end;
       
   831 
   817 (* flatten_expr:
   832 (* flatten_expr:
   818    Extend list of identifiers by those new in locale expression expr.
   833    Extend list of identifiers by those new in locale expression expr.
   819    Compute corresponding list of lists of locale elements (one entry per
   834    Compute corresponding list of lists of locale elements (one entry per
   820    identifier).
   835    identifier).
   821 
   836 
   833    info: now each entry is a pair of string and typ option.  Axioms are
   848    info: now each entry is a pair of string and typ option.  Axioms are
   834    type-instantiated.
   849    type-instantiated.
   835 
   850 
   836 *)
   851 *)
   837 
   852 
   838 fun flatten_expr ctxt (prev_idents, expr) =
   853 fun flatten_expr ctxt ((prev_idents, prev_syntax), expr) =
   839   let
   854   let
   840     val thy = ProofContext.theory_of ctxt;
   855     val thy = ProofContext.theory_of ctxt;
   841     (* thy used for retrieval of locale info,
   856     (* thy used for retrieval of locale info,
   842        ctxt for error messages, parameter unification and instantiation
   857        ctxt for error messages, parameter unification and instantiation
   843        of axioms *)
   858        of axioms *)
   845 
   860 
   846     fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys
   861     fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys
   847       | renaming (NONE :: xs) (y :: ys) = renaming xs ys
   862       | renaming (NONE :: xs) (y :: ys) = renaming xs ys
   848       | renaming [] _ = []
   863       | renaming [] _ = []
   849       | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^
   864       | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^
   850           commas (map (fn NONE => "_" | SOME x => quote x) xs));
   865           commas (map (fn NONE => "_" | SOME x => quote (fst x)) xs));
   851 
   866 
   852     fun rename_parms top ren ((name, ps), (parms, axs)) =
   867     fun rename_parms top ren ((name, ps), (parms, axs)) =
   853       let val ps' = map (rename ren) ps in
   868       let val ps' = map (rename ren) ps in
   854         (case duplicates ps' of [] => ((name, ps'),
   869         (case duplicates ps' of [] => ((name, ps'),
   855           if top then (map (rename ren) parms, map (rename_thm ren) axs)
   870           if top then (map (rename ren) parms, map (rename_thm ren) axs)
   864        identify at top level (top = true);
   879        identify at top level (top = true);
   865        parms is accumulated list of parameters *)
   880        parms is accumulated list of parameters *)
   866           let
   881           let
   867             val {predicate = (_, axioms), import, params, ...} =
   882             val {predicate = (_, axioms), import, params, ...} =
   868               the_locale thy name;
   883               the_locale thy name;
   869             val ps = map #1 (#1 params);
   884             val ps = map (#1 o #1) (#1 params);
   870             val (ids', parms') = identify false import;
   885             val (ids', parms', _) = identify false import;
   871                 (* acyclic import dependencies *)
   886                 (* acyclic import dependencies *)
   872             val ids'' = ids' @ [((name, ps), ([], []))];
   887             val ids'' = ids' @ [((name, ps), ([], []))];
   873             val ids_ax = if top then snd
   888             val ids_ax = if top then snd
       
   889                  (* get the right axioms, only if at top level *)
   874                  (foldl_map (fn (axs, ((name, parms), _)) => let
   890                  (foldl_map (fn (axs, ((name, parms), _)) => let
   875                    val {elems, ...} = the_locale thy name;
   891                    val {elems, ...} = the_locale thy name;
   876                    val ts = List.concat (List.mapPartial (fn (Assumes asms, _) =>
   892                    val ts = List.concat (List.mapPartial (fn (Assumes asms, _) =>
   877                      SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems);
   893                      SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems);
   878                    val (axs1, axs2) = splitAt (length ts, axs);
   894                    val (axs1, axs2) = splitAt (length ts, axs);
   879                  in (axs2, ((name, parms), (ps, axs1))) end) (axioms, ids''))
   895                  in (axs2, ((name, parms), (ps, axs1))) end) (axioms, ids''))
   880                else ids'';
   896                else ids'';
   881           in (ids_ax, merge_lists parms' ps) end
   897             val syn = Symtab.make (map (apfst fst) (#1 params));
       
   898           in (ids_ax, merge_lists parms' ps, syn) end
   882       | identify top (Rename (e, xs)) =
   899       | identify top (Rename (e, xs)) =
   883           let
   900           let
   884             val (ids', parms') = identify top e;
   901             val (ids', parms', syn') = identify top e;
   885             val ren = renaming xs parms'
   902             val ren = renaming xs parms'
   886               handle ERROR_MESSAGE msg => err_in_locale' ctxt msg ids';
   903               handle ERROR_MESSAGE msg => err_in_locale' ctxt msg ids';
   887             val ids'' = gen_distinct eq_fst (map (rename_parms top ren) ids');
   904             val ids'' = gen_distinct eq_fst (map (rename_parms top ren) ids');
   888             val parms'' = distinct (List.concat (map (#2 o #1) ids''));
   905             val parms'' = distinct (List.concat (map (#2 o #1) ids''));
   889           in (ids'', parms'') end
   906             val syn'' = syn' |> Symtab.dest |> map (rename_var ren) |>
       
   907                   Symtab.make;
       
   908             (* check for conflicting syntax? *)
       
   909           in (ids'', parms'', syn'') end
   890       | identify top (Merge es) =
   910       | identify top (Merge es) =
   891           Library.foldl (fn ((ids, parms), e) => let
   911           Library.foldl (fn ((ids, parms, syn), e) => let
   892                      val (ids', parms') = identify top e
   912                      val (ids', parms', syn') = identify top e
   893                    in (gen_merge_lists eq_fst ids ids',
   913                    in (gen_merge_lists eq_fst ids ids',
   894                        merge_lists parms parms') end)
   914                        merge_lists parms parms',
   895             (([], []), es);
   915                        merge_syntax ctxt ids' (syn, syn')) end)
       
   916             (([], [], Symtab.empty), es);
   896 
   917 
   897     (* CB: enrich identifiers by parameter types and 
   918     (* CB: enrich identifiers by parameter types and 
   898        the corresponding elements (with renamed parameters) *)
   919        the corresponding elements (with renamed parameters),
   899 
   920        also takes care of parameter syntax *)
   900     fun eval ((name, xs), axs) =
   921 
       
   922     fun eval syn ((name, xs), axs) =
   901       let
   923       let
   902         val {params = (ps, qs), elems, ...} = the_locale thy name;
   924         val {params = (ps, qs), elems, ...} = the_locale thy name;
   903         val ren = filter_out (op =) (map #1 ps ~~ xs);
   925         val ps' = map #1 ps;
       
   926         val ren = map #1 ps' ~~
       
   927               map (fn x => (x, valOf (Symtab.lookup (syn, x)))) xs;
   904         val (params', elems') =
   928         val (params', elems') =
   905           if null ren then ((ps, qs), map #1 elems)
   929           if null ren then ((ps', qs), map #1 elems)
   906           else ((map (apfst (rename ren)) ps, map (rename ren) qs),
   930           else ((map (apfst (rename ren)) ps', map (rename ren) qs),
   907             map (rename_elem ren o #1) elems);
   931             map (rename_elem ren o #1) elems);
   908         val elems'' = map (rename_facts (space_implode "_" xs)) elems';
   932         val elems'' = map (rename_facts (space_implode "_" xs)) elems';
   909       in (((name, params'), axs), elems'') end;
   933       in (((name, params'), axs), elems'') end;
   910 
   934 
   911     (* compute identifiers, merge with previous ones *)
   935     (* type constraint for renamed parameter with syntax *)
   912     val idents = gen_rems eq_fst (#1 (identify true expr), prev_idents);
   936     fun type_syntax NONE = NONE
       
   937       | type_syntax (SOME mx) = let
       
   938             val Ts = map (fn x => TFree (x, [])) (Term.invent_names [] "'mxa"
       
   939               (Syntax.mixfix_args mx + 1))
       
   940           in Ts |> Library.split_last |> op ---> |> SOME end;
       
   941 
       
   942     (* compute identifiers and syntax, merge with previous ones *)
       
   943     val (ids, _, syn) = identify true expr;
       
   944     val idents = gen_rems eq_fst (ids, prev_idents);
       
   945     val syntax = merge_syntax ctxt ids (syn, prev_syntax);
   913     (* add types to params, check for unique params and unify them *)
   946     (* add types to params, check for unique params and unify them *)
   914     val raw_elemss = unique_parms ctxt (map eval idents);
   947     val raw_elemss = unique_parms ctxt (map (eval syntax) idents);
   915     val elemss = unify_elemss' ctxt [] raw_elemss;
   948     val elemss = unify_elemss' ctxt [] raw_elemss
       
   949          (map (apsnd type_syntax) (Symtab.dest syntax));
   916     (* replace params in ids by params from axioms,
   950     (* replace params in ids by params from axioms,
   917        adjust types in axioms *)
   951        adjust types in axioms *)
   918     val all_params' = params_of' elemss;
   952     val all_params' = params_of' elemss;
   919     val all_params = param_types all_params';
   953     val all_params = param_types all_params';
   920     val elemss' = map (fn (((name, _), (ps, axs)), elems) =>
   954     val elemss' = map (fn (((name, _), (ps, axs)), elems) =>
   926          val [env] = unify_parms ctxt all_params [ps];
   960          val [env] = unify_parms ctxt all_params [ps];
   927          val th' = inst_thm ctxt env th;
   961          val th' = inst_thm ctxt env th;
   928        in th' end;
   962        in th' end;
   929     val final_elemss = map (fn ((id, axs), elems) =>
   963     val final_elemss = map (fn ((id, axs), elems) =>
   930          ((id, map inst_ax axs), elems)) elemss';
   964          ((id, map inst_ax axs), elems)) elemss';
   931   in (prev_idents @ idents, final_elemss) end;
   965   in ((prev_idents @ idents, syntax), final_elemss) end;
   932 
   966 
   933 end;
   967 end;
   934 
   968 
   935 
   969 
   936 (* activate elements *)
   970 (* activate elements *)
  1054 end;
  1088 end;
  1055 
  1089 
  1056 
  1090 
  1057 (* propositions and bindings *)
  1091 (* propositions and bindings *)
  1058 
  1092 
  1059 (* flatten (ids, expr) normalises expr (which is either a locale
  1093 (* flatten ((ids, syn), expr) normalises expr (which is either a locale
  1060    expression or a single context element) wrt.
  1094    expression or a single context element) wrt.
  1061    to the list ids of already accumulated identifiers.
  1095    to the list ids of already accumulated identifiers.
  1062    It returns (ids', elemss) where ids' is an extension of ids
  1096    It returns (ids', syn', elemss) where ids' is an extension of ids
  1063    with identifiers generated for expr, and elemss is the list of
  1097    with identifiers generated for expr, and elemss is the list of
  1064    context elements generated from expr.  For details, see flatten_expr.
  1098    context elements generated from expr.
       
  1099    syn and syn' are symtabs mapping parameter names to their syntax.  syn'
       
  1100    is an extension of syn.
       
  1101    For details, see flatten_expr.
       
  1102 
  1065    Additionally, for a locale expression, the elems are grouped into a single
  1103    Additionally, for a locale expression, the elems are grouped into a single
  1066    Int; individual context elements are marked Ext.  In this case, the
  1104    Int; individual context elements are marked Ext.  In this case, the
  1067    identifier-like information of the element is as follows:
  1105    identifier-like information of the element is as follows:
  1068    - for Fixes: (("", ps), []) where the ps have type info NONE
  1106    - for Fixes: (("", ps), []) where the ps have type info NONE
  1069    - for other elements: (("", []), []).
  1107    - for other elements: (("", []), []).
  1070    The implementation of activate_facts relies on identifier names being
  1108    The implementation of activate_facts relies on identifier names being
  1071    empty strings for external elements.
  1109    empty strings for external elements.
  1072 *)
  1110 *)
  1073 
  1111 
  1074 fun flatten _ (ids, Elem (Fixes fixes)) =
  1112 fun flatten (ctxt, _) ((ids, syn), Elem (Fixes fixes)) = let
  1075       (ids @ [(("", map #1 fixes), ([], []))], [((("", map (rpair NONE o #1) fixes), []), Ext (Fixes fixes))])
  1113 	val ids' = ids @ [(("", map #1 fixes), ([], []))]
  1076   | flatten _ (ids, Elem elem) = (ids @ [(("", []), ([], []))], [((("", []), []), Ext elem)])
  1114       in
  1077   | flatten (ctxt, prep_expr) (ids, Expr expr) =
  1115 	((ids',
  1078       apsnd (map (apsnd Int)) (flatten_expr ctxt (ids, prep_expr expr));
  1116 	 merge_syntax ctxt ids'
       
  1117 	   (syn, Symtab.make (map (fn fx => (#1 fx, #3 fx)) fixes))
       
  1118 	   handle Symtab.DUPS xs => err_in_locale ctxt
       
  1119 	     ("Conflicting syntax for parameters: " ^ commas_quote xs)
       
  1120              (map #1 ids')),
       
  1121 	 [((("", map (rpair NONE o #1) fixes), []), Ext (Fixes fixes))])
       
  1122       end
       
  1123   | flatten _ ((ids, syn), Elem elem) =
       
  1124       ((ids @ [(("", []), ([], []))], syn), [((("", []), []), Ext elem)])
       
  1125   | flatten (ctxt, prep_expr) ((ids, syn), Expr expr) =
       
  1126       apsnd (map (apsnd Int)) (flatten_expr ctxt ((ids, syn), prep_expr expr));
  1079 
  1127 
  1080 local
  1128 local
  1081 
  1129 
  1082 local
  1130 local
       
  1131 
       
  1132 (* paramify type, process mixfix constraint of renamed syntax *)
       
  1133 
       
  1134 fun mx_type _ (x, NONE, mx) = (x, NONE, mx)
       
  1135   | mx_type _ (x, SOME T, NONE) =
       
  1136       (x, SOME (Term.map_type_tfree (TypeInfer.param 0) T), NONE)
       
  1137   | mx_type ctxt (x, SOME T, SOME mx) =
       
  1138       let
       
  1139 val _ = warning "mx_type: mx";
       
  1140 val _ = PolyML.print mx;
       
  1141         val tsig = Sign.tsig_of (ProofContext.sign_of ctxt);
       
  1142         val T' = Type.varifyT T;
       
  1143         val mxTs = map (fn n => TVar ((n, 0), []))
       
  1144           (Term.invent_names (Term.add_typ_tfree_names (T, [])) "'a"
       
  1145             (Syntax.mixfix_args mx + 1));
       
  1146           (* avoid name clashes in unification *)
       
  1147         val mxT = mxTs |> Library.split_last |> op --->;
       
  1148         val (tenv, _) = Type.unify tsig (Vartab.empty, 0) (T', mxT)
       
  1149           handle Type.TUNIFY =>
       
  1150             raise TYPE ("failed to satisfy mixfix-constraint for parameter " ^
       
  1151               quote x ^ "\nunable to unify", [T', mxT], []);
       
  1152         val U = Envir.norm_type tenv T';
       
  1153         val ixns = Term.add_typ_ixns ([], U);
       
  1154         val ren = Vartab.make (ixns ~~ Term.invent_names [] "'a" (length ixns));
       
  1155         val U' = Term.map_type_tvar (fn ((x, i), s) =>
       
  1156           (TypeInfer.param 0 (x, s))) U;
       
  1157 (*        val U' = Term.map_type_tvar (fn (xi, s) =>
       
  1158           (TypeInfer.param 0 (valOf (Vartab.lookup (ren, xi)), s))) U;
       
  1159 *)val _ = warning "mx_type (U, U')";
       
  1160 val _ = PolyML.print (U, U');
       
  1161       in (x, SOME U', SOME mx) end;
  1083 
  1162 
  1084 fun declare_int_elem (ctxt, Fixes fixes) =
  1163 fun declare_int_elem (ctxt, Fixes fixes) =
  1085       (ctxt |> ProofContext.add_fixes (map (fn (x, T, mx) =>
  1164       (ctxt |> ProofContext.add_fixes (map (fn (x, T, mx) =>
  1086         (x, Option.map (Term.map_type_tfree (TypeInfer.param 0)) T, mx)) fixes), [])
  1165         (x, Option.map (Term.map_type_tfree (TypeInfer.param 0)) T, mx)) fixes), [])
  1087   | declare_int_elem (ctxt, _) = (ctxt, []);
  1166   | declare_int_elem (ctxt, _) = (ctxt, []);
  1340 fun prep_context_statement prep_expr prep_elemss prep_facts
  1419 fun prep_context_statement prep_expr prep_elemss prep_facts
  1341     do_close fixed_params import elements raw_concl context =
  1420     do_close fixed_params import elements raw_concl context =
  1342   let
  1421   let
  1343     val sign = ProofContext.sign_of context;
  1422     val sign = ProofContext.sign_of context;
  1344 
  1423 
  1345     val (import_ids, raw_import_elemss) = flatten (context, prep_expr sign) ([], Expr import);
  1424     val ((import_ids, import_syn), raw_import_elemss) = flatten (context, prep_expr sign) (([], Symtab.empty), Expr import);
  1346     (* CB: normalise "includes" among elements *)
  1425     (* CB: normalise "includes" among elements *)
  1347     val (ids, raw_elemsss) = foldl_map (flatten (context, prep_expr sign))
  1426     val ((ids, syn), raw_elemsss) = foldl_map (flatten (context, prep_expr sign))
  1348       (import_ids, elements);
  1427       ((import_ids, import_syn), elements);
  1349 
  1428 
  1350     val raw_elemss = List.concat raw_elemsss;
  1429     val raw_elemss = List.concat raw_elemsss;
  1351     (* CB: raw_import_elemss @ raw_elemss is the normalised list of
  1430     (* CB: raw_import_elemss @ raw_elemss is the normalised list of
  1352        context elements obtained from import and elements. *)
  1431        context elements obtained from import and elements. *)
  1353     val ((parms, all_elemss, concl), (spec, (_, _, defs))) = prep_elemss do_close
  1432     val ((parms, all_elemss, concl), (spec, (_, _, defs))) = prep_elemss do_close
  1367     val stmt = gen_distinct Term.aconv
  1446     val stmt = gen_distinct Term.aconv
  1368        (List.concat (map (fn ((_, axs), _) =>
  1447        (List.concat (map (fn ((_, axs), _) =>
  1369          List.concat (map (#hyps o Thm.rep_thm) axs)) qs));
  1448          List.concat (map (#hyps o Thm.rep_thm) axs)) qs));
  1370     val cstmt = map (cterm_of sign) stmt;
  1449     val cstmt = map (cterm_of sign) stmt;
  1371   in
  1450   in
  1372     ((((import_ctxt, import_elemss), (ctxt, elemss)), (parms, spec, defs)), (cstmt, concl))
  1451     ((((import_ctxt, import_elemss), (ctxt, elemss, syn)), (parms, spec, defs)), (cstmt, concl))
  1373   end;
  1452   end;
  1374 
  1453 
  1375 val gen_context = prep_context_statement intern_expr read_elemss read_facts;
  1454 val gen_context = prep_context_statement intern_expr read_elemss read_facts;
  1376 val gen_context_i = prep_context_statement (K I) cert_elemss cert_facts;
  1455 val gen_context_i = prep_context_statement (K I) cert_elemss cert_facts;
  1377 
  1456 
  1382     val (target_stmt, fixed_params, import) =
  1461     val (target_stmt, fixed_params, import) =
  1383       (case locale of NONE => ([], [], empty)
  1462       (case locale of NONE => ([], [], empty)
  1384       | SOME name =>
  1463       | SOME name =>
  1385           let val {predicate = (stmt, _), params = (ps, _), ...} =
  1464           let val {predicate = (stmt, _), params = (ps, _), ...} =
  1386             the_locale thy name
  1465             the_locale thy name
  1387           in (stmt, param_types ps, Locale name) end);
  1466           in (stmt, param_types (map fst ps), Locale name) end);
  1388     val ((((locale_ctxt, locale_elemss), (elems_ctxt, _)), _), (elems_stmt, concl')) =
  1467     val ((((locale_ctxt, locale_elemss), (elems_ctxt, _, _)), _), (elems_stmt, concl')) =
  1389       prep_ctxt false fixed_params import elems concl ctxt;
  1468       prep_ctxt false fixed_params import elems concl ctxt;
  1390   in (locale, (target_stmt, elems_stmt), locale_ctxt, elems_ctxt, concl') end;
  1469   in (locale, (target_stmt, elems_stmt), locale_ctxt, elems_ctxt, concl') end;
  1391 
  1470 
  1392 in
  1471 in
  1393 
  1472 
  1415 
  1494 
  1416     (** process the locale **)
  1495     (** process the locale **)
  1417 
  1496 
  1418     val {predicate = (_, axioms), params = (ps, _), ...} =
  1497     val {predicate = (_, axioms), params = (ps, _), ...} =
  1419       the_locale thy (intern sign loc_name);
  1498       the_locale thy (intern sign loc_name);
  1420     val fixed_params = param_types ps;
  1499     val fixed_params = param_types (map #1 ps);
  1421     val init = ProofContext.init thy;
  1500     val init = ProofContext.init thy;
  1422     val (_, raw_elemss) =
  1501     val (_, raw_elemss) = flatten (init, intern_expr sign)
  1423           flatten (init, intern_expr sign) ([], Expr (Locale loc_name));
  1502          (([], Symtab.empty), Expr (Locale loc_name));
  1424     val ((parms, all_elemss, concl),
  1503     val ((parms, all_elemss, concl),
  1425          (spec as (_, (ints, _)), (xs, env, defs))) =
  1504          (spec as (_, (ints, _)), (xs, env, defs))) =
  1426       read_elemss false (* do_close *) init
  1505       read_elemss false (* do_close *) init
  1427         fixed_params (* could also put [] here??? *) raw_elemss
  1506         fixed_params (* could also put [] here??? *) raw_elemss
  1428         [] (* concl *);
  1507         [] (* concl *);
  1590 (* print locale *)
  1669 (* print locale *)
  1591 
  1670 
  1592 fun print_locale thy import body =
  1671 fun print_locale thy import body =
  1593   let
  1672   let
  1594     val thy_ctxt = ProofContext.init thy;
  1673     val thy_ctxt = ProofContext.init thy;
  1595     val (((_, import_elemss), (ctxt, elemss)), _) = read_context import body thy_ctxt;
  1674     val (((_, import_elemss), (ctxt, elemss, _)), _) = read_context import body thy_ctxt;
  1596     val all_elems = List.concat (map #2 (import_elemss @ elemss));
  1675     val all_elems = List.concat (map #2 (import_elemss @ elemss));
  1597 
  1676 
  1598     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
  1677     val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
  1599     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
  1678     val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
  1600     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
  1679     val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt;
  1697   let
  1776   let
  1698     val ctxt = ProofContext.init thy;
  1777     val ctxt = ProofContext.init thy;
  1699     val sign = Theory.sign_of thy;
  1778     val sign = Theory.sign_of thy;
  1700 
  1779 
  1701     val (parms, parmTs_o) =
  1780     val (parms, parmTs_o) =
  1702           the_locale thy target |> #params |> fst |> split_list;
  1781           the_locale thy target |> #params |> fst |> map fst |> split_list;
  1703     val parmvTs = map (Type.varifyT o valOf) parmTs_o;
  1782     val parmvTs = map (Type.varifyT o valOf) parmTs_o;
  1704     val ids = flatten (ctxt, intern_expr sign) ([], Expr (Locale target))
  1783     val ids = flatten (ctxt, intern_expr sign) (([], Symtab.empty), Expr (Locale target))
  1705           |> fst |> map fst;
  1784           |> fst |> fst |> map fst;
  1706 
  1785 
  1707     val regs = get_global_registrations thy target;
  1786     val regs = get_global_registrations thy target;
  1708 
  1787 
  1709     (* add args to thy for all registrations *)
  1788     (* add args to thy for all registrations *)
  1710 
  1789 
  1938     val name = Sign.full_name sign bname;
  2017     val name = Sign.full_name sign bname;
  1939     val _ = conditional (isSome (get_locale thy name)) (fn () =>
  2018     val _ = conditional (isSome (get_locale thy name)) (fn () =>
  1940       error ("Duplicate definition of locale " ^ quote name));
  2019       error ("Duplicate definition of locale " ^ quote name));
  1941 
  2020 
  1942     val thy_ctxt = ProofContext.init thy;
  2021     val thy_ctxt = ProofContext.init thy;
  1943     val (((import_ctxt, import_elemss), (body_ctxt, body_elemss)), text) =
  2022     val (((import_ctxt, import_elemss), (body_ctxt, body_elemss, syn)), text) =
  1944       prep_ctxt raw_import raw_body thy_ctxt;
  2023       prep_ctxt raw_import raw_body thy_ctxt;
  1945     val elemss = import_elemss @ body_elemss;
  2024     val elemss = import_elemss @ body_elemss;
  1946 
  2025 
  1947     val (pred_thy, (elemss', predicate as (predicate_statement, predicate_axioms))) =
  2026     val (pred_thy, (elemss', predicate as (predicate_statement, predicate_axioms))) =
  1948       if do_pred then thy |> define_preds bname text elemss
  2027       if do_pred then thy |> define_preds bname text elemss
  1964     pred_thy
  2043     pred_thy
  1965     |> note_thmss_qualified "" name facts' |> #1
  2044     |> note_thmss_qualified "" name facts' |> #1
  1966     |> declare_locale name
  2045     |> declare_locale name
  1967     |> put_locale name {predicate = predicate, import = prep_expr sign raw_import,
  2046     |> put_locale name {predicate = predicate, import = prep_expr sign raw_import,
  1968         elems = map (fn e => (e, stamp ())) (List.concat (map #2 (List.filter (equal "" o #1 o #1) elemss'))),
  2047         elems = map (fn e => (e, stamp ())) (List.concat (map #2 (List.filter (equal "" o #1 o #1) elemss'))),
  1969         params = (params_of elemss', map #1 (params_of body_elemss))}
  2048         params = (params_of elemss' |>
       
  2049           map (fn (x, T) => ((x, T), valOf (Symtab.lookup (syn, x)))), map #1 (params_of body_elemss))}
  1970   end;
  2050   end;
  1971 
  2051 
  1972 in
  2052 in
  1973 
  2053 
  1974 val add_locale = gen_add_locale read_context intern_expr;
  2054 val add_locale = gen_add_locale read_context intern_expr;
  2071   let
  2151   let
  2072     val ctxt = mk_ctxt thy_ctxt;
  2152     val ctxt = mk_ctxt thy_ctxt;
  2073     val sign = ProofContext.sign_of ctxt;
  2153     val sign = ProofContext.sign_of ctxt;
  2074 
  2154 
  2075     val ctxt' = ctxt |> ProofContext.theory_of |> ProofContext.init;
  2155     val ctxt' = ctxt |> ProofContext.theory_of |> ProofContext.init;
  2076     val (ids, raw_elemss) = flatten (ctxt', intern_expr sign) ([], Expr expr);
  2156     val ((ids, _), raw_elemss) = flatten (ctxt', intern_expr sign)
       
  2157           (([], Symtab.empty), Expr expr);
  2077     val do_close = false;  (* effect unknown *)
  2158     val do_close = false;  (* effect unknown *)
  2078     val ((parms, all_elemss, _), (spec, (xs, defs, _))) =
  2159     val ((parms, all_elemss, _), (spec, (xs, defs, _))) =
  2079           read_elemss do_close ctxt' [] raw_elemss [];
  2160           read_elemss do_close ctxt' [] raw_elemss [];
  2080 
  2161 
  2081 
  2162