src/Pure/Isar/locale.ML
changeset 27716 96699d8eb49e
parent 27709 2ba55d217705
child 27761 b95e9ba0ca1d
equal deleted inserted replaced
27715:087db5aacac3 27716:96699d8eb49e
    56     ((string * typ) * mixfix) list
    56     ((string * typ) * mixfix) list
    57   val local_asms_of: theory -> string ->
    57   val local_asms_of: theory -> string ->
    58     ((string * Attrib.src list) * term list) list
    58     ((string * Attrib.src list) * term list) list
    59   val global_asms_of: theory -> string ->
    59   val global_asms_of: theory -> string ->
    60     ((string * Attrib.src list) * term list) list
    60     ((string * Attrib.src list) * term list) list
       
    61 
       
    62   (* Theorems *)
    61   val intros: theory -> string -> thm list * thm list
    63   val intros: theory -> string -> thm list * thm list
    62   val dests: theory -> string -> thm list
    64   val dests: theory -> string -> thm list
       
    65   (* Not part of the official interface.  DO NOT USE *)
    63   val facts_of: theory -> string
    66   val facts_of: theory -> string
    64     -> ((string * Attrib.src list) * (thm list * Attrib.src list) list) list list
    67     -> ((string * Attrib.src list) * (thm list * Attrib.src list) list) list list
    65 
    68 
    66   (* Processing of locale statements *)
    69   (* Processing of locale statements *)
    67   val read_context_statement: xstring option -> Element.context element list ->
    70   val read_context_statement: xstring option -> Element.context element list ->
   153 type locale =
   156 type locale =
   154  {axiom: Element.witness list,
   157  {axiom: Element.witness list,
   155     (* For locales that define predicates this is [A [A]], where A is the locale
   158     (* For locales that define predicates this is [A [A]], where A is the locale
   156        specification.  Otherwise [].
   159        specification.  Otherwise [].
   157        Only required to generate the right witnesses for locales with predicates. *)
   160        Only required to generate the right witnesses for locales with predicates. *)
   158   imports: expr,                                                     (*dynamic imports*)
       
   159   elems: (Element.context_i * stamp) list,
   161   elems: (Element.context_i * stamp) list,
   160     (* Static content, neither Fixes nor Constrains elements *)
   162     (* Static content, neither Fixes nor Constrains elements *)
   161   params: ((string * typ) * mixfix) list,                             (*all params*)
   163   params: ((string * typ) * mixfix) list,                             (*all params*)
   162   lparams: string list,                                             (*local params*)
       
   163   decls: decl list * decl list,                    (*type/term_syntax declarations*)
   164   decls: decl list * decl list,                    (*type/term_syntax declarations*)
   164   regs: ((string * string list) * Element.witness list) list,
   165   regs: ((string * string list) * Element.witness list) list,
   165     (* Registrations: indentifiers and witnesses of locales interpreted in the locale. *)
   166     (* Registrations: indentifiers and witnesses of locales interpreted in the locale. *)
   166   intros: thm list * thm list,
   167   intros: thm list * thm list,
   167     (* Introduction rules: of delta predicate and locale predicate. *)
   168     (* Introduction rules: of delta predicate and locale predicate. *)
   350   val empty = (NameSpace.empty, Symtab.empty);
   351   val empty = (NameSpace.empty, Symtab.empty);
   351   val copy = I;
   352   val copy = I;
   352   val extend = I;
   353   val extend = I;
   353 
   354 
   354   fun join_locales _
   355   fun join_locales _
   355     ({axiom, imports, elems, params, lparams, decls = (decls1, decls2), regs, intros, dests}: locale,
   356     ({axiom, elems, params, decls = (decls1, decls2), regs, intros, dests}: locale,
   356       {elems = elems', decls = (decls1', decls2'), regs = regs', ...}: locale) =
   357       {elems = elems', decls = (decls1', decls2'), regs = regs', ...}: locale) =
   357      {axiom = axiom,
   358      {axiom = axiom,
   358       imports = imports,
       
   359       elems = merge_lists (eq_snd (op =)) elems elems',
   359       elems = merge_lists (eq_snd (op =)) elems elems',
   360       params = params,
   360       params = params,
   361       lparams = lparams,
       
   362       decls =
   361       decls =
   363        (Library.merge (eq_snd (op =)) (decls1, decls1'),
   362        (Library.merge (eq_snd (op =)) (decls1, decls1'),
   364         Library.merge (eq_snd (op =)) (decls2, decls2')),
   363         Library.merge (eq_snd (op =)) (decls2, decls2')),
   365       regs = merge_alists (op =) regs regs',
   364       regs = merge_alists (op =) regs regs',
   366       intros = intros,
   365       intros = intros,
   397   thy |> LocalesData.map (fn (space, locs) =>
   396   thy |> LocalesData.map (fn (space, locs) =>
   398     (Sign.declare_name thy name space, Symtab.update (name, loc) locs));
   397     (Sign.declare_name thy name space, Symtab.update (name, loc) locs));
   399 
   398 
   400 fun change_locale name f thy =
   399 fun change_locale name f thy =
   401   let
   400   let
   402     val {axiom, imports, elems, params, lparams, decls, regs, intros, dests} =
   401     val {axiom, elems, params, decls, regs, intros, dests} =
   403         the_locale thy name;
   402         the_locale thy name;
   404     val (axiom', imports', elems', params', lparams', decls', regs', intros', dests') =
   403     val (axiom', elems', params', decls', regs', intros', dests') =
   405       f (axiom, imports, elems, params, lparams, decls, regs, intros, dests);
   404       f (axiom, elems, params, decls, regs, intros, dests);
   406   in
   405   in
   407     thy
   406     thy
   408     |> (LocalesData.map o apsnd) (Symtab.update (name, {axiom = axiom',
   407     |> (LocalesData.map o apsnd) (Symtab.update (name, {axiom = axiom',
   409           imports = imports', elems = elems', params = params', lparams = lparams',
   408           elems = elems', params = params',
   410           decls = decls', regs = regs', intros = intros', dests = dests'}))
   409           decls = decls', regs = regs', intros = intros', dests = dests'}))
   411   end;
   410   end;
   412 
   411 
   413 fun print_locales thy =
   412 fun print_locales thy =
   414   let val (space, locs) = LocalesData.get thy in
   413   let val (space, locs) = LocalesData.get thy in
   469 fun put_local_registration id attn morphs =
   468 fun put_local_registration id attn morphs =
   470   Context.proof_map (put_registration id attn morphs);
   469   Context.proof_map (put_registration id attn morphs);
   471 
   470 
   472 
   471 
   473 fun put_registration_in_locale name id =
   472 fun put_registration_in_locale name id =
   474   change_locale name (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) =>
   473   change_locale name (fn (axiom, elems, params, decls, regs, intros, dests) =>
   475     (axiom, imports, elems, params, lparams, decls, regs @ [(id, [])], intros, dests));
   474     (axiom, elems, params, decls, regs @ [(id, [])], intros, dests));
   476 
   475 
   477 
   476 
   478 (* add witness theorem to registration, ignored if registration not present *)
   477 (* add witness theorem to registration, ignored if registration not present *)
   479 
   478 
   480 fun add_witness (name, ps) thm =
   479 fun add_witness (name, ps) thm =
   483 fun add_global_witness id thm = Context.theory_map (add_witness id thm);
   482 fun add_global_witness id thm = Context.theory_map (add_witness id thm);
   484 fun add_local_witness id thm = Context.proof_map (add_witness id thm);
   483 fun add_local_witness id thm = Context.proof_map (add_witness id thm);
   485 
   484 
   486 
   485 
   487 fun add_witness_in_locale name id thm =
   486 fun add_witness_in_locale name id thm =
   488   change_locale name (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) =>
   487   change_locale name (fn (axiom, elems, params, decls, regs, intros, dests) =>
   489     let
   488     let
   490       fun add (id', thms) =
   489       fun add (id', thms) =
   491         if id = id' then (id', thm :: thms) else (id', thms);
   490         if id = id' then (id', thm :: thms) else (id', thms);
   492     in (axiom, imports, elems, params, lparams, decls, map add regs, intros, dests) end);
   491     in (axiom, elems, params, decls, map add regs, intros, dests) end);
   493 
   492 
   494 
   493 
   495 (* add equation to registration, ignored if registration not present *)
   494 (* add equation to registration, ignored if registration not present *)
   496 
   495 
   497 fun add_equation (name, ps) thm =
   496 fun add_equation (name, ps) thm =
   731         handle Symtab.DUP x => err_in_expr ctxt
   730         handle Symtab.DUP x => err_in_expr ctxt
   732           ("Conflicting syntax for parameter: " ^ quote x) expr;
   731           ("Conflicting syntax for parameter: " ^ quote x) expr;
   733 
   732 
   734     fun params_of (expr as Locale name) =
   733     fun params_of (expr as Locale name) =
   735           let
   734           let
   736             val {imports, params, ...} = the_locale thy name;
   735             val {params, ...} = the_locale thy name;
   737             val parms = map (fst o fst) params;
   736           in (map (fst o fst) params, params |> map fst |> Symtab.make,
   738             val (parms', types', syn') = params_of imports;
   737                params |> map (apfst fst) |> Symtab.make) end
   739             val all_parms = merge_lists (op =) parms' parms;
       
   740             val all_types = merge_tenvs [] types' (params |> map fst |> Symtab.make);
       
   741             val all_syn = merge_syn expr syn' (params |> map (apfst fst) |> Symtab.make);
       
   742           in (all_parms, all_types, all_syn) end
       
   743       | params_of (expr as Rename (e, xs)) =
   738       | params_of (expr as Rename (e, xs)) =
   744           let
   739           let
   745             val (parms', types', syn') = params_of e;
   740             val (parms', types', syn') = params_of e;
   746             val ren = renaming xs parms';
   741             val ren = renaming xs parms';
   747             (* renaming may reduce number of parameters *)
   742             (* renaming may reduce number of parameters *)
   812          if top
   807          if top
   813          then (map (Element.rename ren) parms,
   808          then (map (Element.rename ren) parms,
   814                map_mode (map (Element.morph_witness (Element.rename_morphism ren))) mode)
   809                map_mode (map (Element.morph_witness (Element.rename_morphism ren))) mode)
   815          else (parms, mode));
   810          else (parms, mode));
   816 
   811 
   817     (* add (name, ps) and its registrations, recursively; adjust hyps of witnesses *)
   812     (* add (name, pTs) and its registrations, recursively; adjust hyps of witnesses *)
   818 
   813 
   819     fun add_with_regs ((name, pTs), mode) (wits, ids, visited) =
   814     fun add_with_regs ((name, pTs), mode) (wits, ids, visited) =
   820         if member (fn (a, (b, _)) => a = b) visited (name, map #1 pTs)
   815         if member (fn (a, (b, _)) => a = b) visited (name, map #1 pTs)
   821         then (wits, ids, visited)
   816         then (wits, ids, visited)
   822         else
   817         else
   874        where name is a locale name, ps a list of parameter names and axs
   869        where name is a locale name, ps a list of parameter names and axs
   875        a list of axioms relating to the identifier, axs is empty unless
   870        a list of axioms relating to the identifier, axs is empty unless
   876        identify at top level (top = true);
   871        identify at top level (top = true);
   877        parms is accumulated list of parameters *)
   872        parms is accumulated list of parameters *)
   878           let
   873           let
   879             val {axiom, imports, params, ...} = the_locale thy name;
   874             val {axiom, params, ...} = the_locale thy name;
   880             val ps = map (#1 o #1) params;
   875             val ps = map (#1 o #1) params;
   881             val (ids', parms') = identify false imports;
   876             val (_, ids'', _) = add_with_regs ((name, map #1 params), Assumed []) ([], [], []);
   882                 (* acyclic import dependencies *)
       
   883 
       
   884             val (_, ids'', _) = add_with_regs ((name, map #1 params), Assumed []) ([], ids', ids');
       
   885             val ids_ax = if top then fst (fold_map (axiomify ps) ids'' axiom) else ids'';
   877             val ids_ax = if top then fst (fold_map (axiomify ps) ids'' axiom) else ids'';
   886             in (ids_ax, merge_lists (op =) parms' ps) end
   878             in (ids_ax, ps) end
   887       | identify top (Rename (e, xs)) =
   879       | identify top (Rename (e, xs)) =
   888           let
   880           let
   889             val (ids', parms') = identify top e;
   881             val (ids', parms') = identify top e;
   890             val ren = renaming xs parms'
   882             val ren = renaming xs parms'
   891               handle ERROR msg => err_in_locale' ctxt msg ids';
   883               handle ERROR msg => err_in_locale' ctxt msg ids';
  1690     val (([(_, [Notes args'])], _), ctxt') =
  1682     val (([(_, [Notes args'])], _), ctxt') =
  1691       activate_facts true cert_facts
  1683       activate_facts true cert_facts
  1692         [((("", []), Assumed []), [Ext (Notes (kind, args))])] ctxt;
  1684         [((("", []), Assumed []), [Ext (Notes (kind, args))])] ctxt;
  1693     val ctxt'' = ctxt' |> ProofContext.theory
  1685     val ctxt'' = ctxt' |> ProofContext.theory
  1694       (change_locale loc
  1686       (change_locale loc
  1695         (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) =>
  1687         (fn (axiom, elems, params, decls, regs, intros, dests) =>
  1696           (axiom, imports, elems @ [(Notes args', stamp ())],
  1688           (axiom, elems @ [(Notes args', stamp ())],
  1697             params, lparams, decls, regs, intros, dests))
  1689             params, decls, regs, intros, dests))
  1698       #> note_thmss_registrations loc args');
  1690       #> note_thmss_registrations loc args');
  1699   in ctxt'' end;
  1691   in ctxt'' end;
  1700 
  1692 
  1701 
  1693 
  1702 (* declarations *)
  1694 (* declarations *)
  1705 
  1697 
  1706 fun decl_attrib decl phi = Thm.declaration_attribute (K (decl phi));
  1698 fun decl_attrib decl phi = Thm.declaration_attribute (K (decl phi));
  1707 
  1699 
  1708 fun add_decls add loc decl =
  1700 fun add_decls add loc decl =
  1709   ProofContext.theory (change_locale loc
  1701   ProofContext.theory (change_locale loc
  1710     (fn (axiom, imports, elems, params, lparams, decls, regs, intros, dests) =>
  1702     (fn (axiom, elems, params, decls, regs, intros, dests) =>
  1711       (axiom, imports, elems, params, lparams, add (decl, stamp ()) decls, regs, intros, dests))) #>
  1703       (axiom, elems, params, add (decl, stamp ()) decls, regs, intros, dests))) #>
  1712   add_thmss loc Thm.internalK
  1704   add_thmss loc Thm.internalK
  1713     [(("", [Attrib.internal (decl_attrib decl)]), [([Drule.dummy_thm], [])])];
  1705     [(("", [Attrib.internal (decl_attrib decl)]), [([Drule.dummy_thm], [])])];
  1714 
  1706 
  1715 in
  1707 in
  1716 
  1708 
  1920     val (((import_ctxt, import_elemss), (body_ctxt, body_elemss, syn)),
  1912     val (((import_ctxt, import_elemss), (body_ctxt, body_elemss, syn)),
  1921       text as (parms, ((_, exts'), _), defs)) =
  1913       text as (parms, ((_, exts'), _), defs)) =
  1922         prep_ctxt raw_imports raw_body thy_ctxt;
  1914         prep_ctxt raw_imports raw_body thy_ctxt;
  1923     val elemss = import_elemss @ body_elemss |>
  1915     val elemss = import_elemss @ body_elemss |>
  1924       map_filter (fn ((id, Assumed axs), elems) => SOME (id, elems) | _ => NONE);
  1916       map_filter (fn ((id, Assumed axs), elems) => SOME (id, elems) | _ => NONE);
  1925     val imports = prep_expr thy raw_imports;
       
  1926 
  1917 
  1927     val extraTs = List.foldr Term.add_term_tfrees [] exts' \\
  1918     val extraTs = List.foldr Term.add_term_tfrees [] exts' \\
  1928       List.foldr Term.add_typ_tfrees [] (map snd parms);
  1919       List.foldr Term.add_typ_tfrees [] (map snd parms);
  1929     val _ = if null extraTs then ()
  1920     val _ = if null extraTs then ()
  1930       else warning ("Additional type variable(s) in locale specification " ^ quote bname);
  1921       else warning ("Additional type variable(s) in locale specification " ^ quote bname);
  1962       |> Sign.add_path bname
  1953       |> Sign.add_path bname
  1963       |> Sign.no_base_names
  1954       |> Sign.no_base_names
  1964       |> PureThy.note_thmss Thm.assumptionK facts' |> snd
  1955       |> PureThy.note_thmss Thm.assumptionK facts' |> snd
  1965       |> Sign.restore_naming thy'
  1956       |> Sign.restore_naming thy'
  1966       |> register_locale name {axiom = axs',
  1957       |> register_locale name {axiom = axs',
  1967         imports = empty,
       
  1968         elems = map (fn e => (e, stamp ())) elems'',
  1958         elems = map (fn e => (e, stamp ())) elems'',
  1969         params = params_of elemss''' |> map (fn (x, SOME T) => ((x, T), the (Symtab.lookup syn x))),
  1959         params = params_of elemss''' |> map (fn (x, SOME T) => ((x, T), the (Symtab.lookup syn x))),
  1970         lparams = map #1 (params_of' body_elemss),
       
  1971         decls = ([], []),
  1960         decls = ([], []),
  1972         regs = regs,
  1961         regs = regs,
  1973         intros = intros,
  1962         intros = intros,
  1974         dests = map Element.conclude_witness pred_axioms}
  1963         dests = map Element.conclude_witness pred_axioms}
  1975       |> init name;
  1964       |> init name;