src/Pure/Isar/locale.ML
changeset 17221 6cd180204582
parent 17203 29b2563f5c11
child 17228 19b460b39dad
equal deleted inserted replaced
17220:b41d8e290bf8 17221:6cd180204582
   166 (* instantiate TFrees *)
   166 (* instantiate TFrees *)
   167 
   167 
   168 fun tinst_tab_type tinst T = if Symtab.is_empty tinst
   168 fun tinst_tab_type tinst T = if Symtab.is_empty tinst
   169       then T
   169       then T
   170       else Term.map_type_tfree
   170       else Term.map_type_tfree
   171         (fn (v as (x, _)) => getOpt (Symtab.lookup (tinst, x), (TFree v))) T;
   171         (fn (v as (x, _)) => getOpt (Symtab.curried_lookup tinst x, (TFree v))) T;
   172 
   172 
   173 fun tinst_tab_term tinst t = if Symtab.is_empty tinst
   173 fun tinst_tab_term tinst t = if Symtab.is_empty tinst
   174       then t
   174       then t
   175       else Term.map_term_types (tinst_tab_type tinst) t;
   175       else Term.map_term_types (tinst_tab_type tinst) t;
   176 
   176 
   199 fun inst_tab_term (inst, tinst) = if Symtab.is_empty inst
   199 fun inst_tab_term (inst, tinst) = if Symtab.is_empty inst
   200       then tinst_tab_term tinst
   200       then tinst_tab_term tinst
   201       else (* instantiate terms and types simultaneously *)
   201       else (* instantiate terms and types simultaneously *)
   202         let
   202         let
   203           fun instf (Const (x, T)) = Const (x, tinst_tab_type tinst T)
   203           fun instf (Const (x, T)) = Const (x, tinst_tab_type tinst T)
   204             | instf (Free (x, T)) = (case Symtab.lookup (inst, x) of
   204             | instf (Free (x, T)) = (case Symtab.curried_lookup inst x of
   205                  NONE => Free (x, tinst_tab_type tinst T)
   205                  NONE => Free (x, tinst_tab_type tinst T)
   206                | SOME t => t)
   206                | SOME t => t)
   207             | instf (Var (xi, T)) = Var (xi, tinst_tab_type tinst T)
   207             | instf (Var (xi, T)) = Var (xi, tinst_tab_type tinst T)
   208             | instf (b as Bound _) = b
   208             | instf (b as Bound _) = b
   209             | instf (Abs (x, T, t)) = Abs (x, tinst_tab_type tinst T, instf t)
   209             | instf (Abs (x, T, t)) = Abs (x, tinst_tab_type tinst T, instf t)
   320     in (case subs of
   320     in (case subs of
   321         [] => let
   321         [] => let
   322                 val sups =
   322                 val sups =
   323                   List.filter (fn (t', _) => Pattern.matches sign (t, t')) (Termtab.dest regs);
   323                   List.filter (fn (t', _) => Pattern.matches sign (t, t')) (Termtab.dest regs);
   324                 val sups' = map (apfst untermify) sups
   324                 val sups' = map (apfst untermify) sups
   325               in (Termtab.update ((t, (attn, [])), regs), sups') end
   325               in (Termtab.curried_update (t, (attn, [])) regs, sups') end
   326       | _ => (regs, []))
   326       | _ => (regs, []))
   327     end;
   327     end;
   328 
   328 
   329   (* add witness theorem to registration,
   329   (* add witness theorem to registration,
   330      only if instantiation is exact, otherwise exception Option raised *)
   330      only if instantiation is exact, otherwise exception Option raised *)
   331   fun add_witness ts thm regs =
   331   fun add_witness ts thm regs =
   332     let
   332     let
   333       val t = termify ts;
   333       val t = termify ts;
   334       val (x, thms) = valOf (Termtab.lookup (regs, t));
   334       val (x, thms) = valOf (Termtab.curried_lookup regs t);
   335     in
   335     in
   336       Termtab.update ((t, (x, thm::thms)), regs)
   336       Termtab.curried_update (t, (x, thm::thms)) regs
   337     end;
   337     end;
   338 end;
   338 end;
   339 
   339 
   340 
   340 
   341 (** theory data **)
   341 (** theory data **)
   396   thy |> GlobalLocalesData.map (fn (space, locs, regs) =>
   396   thy |> GlobalLocalesData.map (fn (space, locs, regs) =>
   397     (Sign.declare_name thy name space, locs, regs));
   397     (Sign.declare_name thy name space, locs, regs));
   398 
   398 
   399 fun put_locale name loc =
   399 fun put_locale name loc =
   400   GlobalLocalesData.map (fn (space, locs, regs) =>
   400   GlobalLocalesData.map (fn (space, locs, regs) =>
   401     (space, Symtab.update ((name, loc), locs), regs));
   401     (space, Symtab.curried_update (name, loc) locs, regs));
   402 
   402 
   403 fun get_locale thy name = Symtab.lookup (#2 (GlobalLocalesData.get thy), name);
   403 fun get_locale thy name = Symtab.curried_lookup (#2 (GlobalLocalesData.get thy)) name;
   404 
   404 
   405 fun the_locale thy name =
   405 fun the_locale thy name =
   406   (case get_locale thy name of
   406   (case get_locale thy name of
   407     SOME loc => loc
   407     SOME loc => loc
   408   | NONE => error ("Unknown locale " ^ quote name));
   408   | NONE => error ("Unknown locale " ^ quote name));
   415    Thms of registrations are never varified. *)
   415    Thms of registrations are never varified. *)
   416 
   416 
   417 (* retrieve registration from theory or context *)
   417 (* retrieve registration from theory or context *)
   418 
   418 
   419 fun gen_get_registrations get thy_ctxt name =
   419 fun gen_get_registrations get thy_ctxt name =
   420   case Symtab.lookup (get thy_ctxt, name) of
   420   case Symtab.curried_lookup (get thy_ctxt) name of
   421       NONE => []
   421       NONE => []
   422     | SOME reg => Registrations.dest reg;
   422     | SOME reg => Registrations.dest reg;
   423 
   423 
   424 val get_global_registrations =
   424 val get_global_registrations =
   425      gen_get_registrations (#3 o GlobalLocalesData.get);
   425      gen_get_registrations (#3 o GlobalLocalesData.get);
   426 val get_local_registrations =
   426 val get_local_registrations =
   427      gen_get_registrations LocalLocalesData.get;
   427      gen_get_registrations LocalLocalesData.get;
   428 
   428 
   429 fun gen_get_registration get thy_of thy_ctxt (name, ps) =
   429 fun gen_get_registration get thy_of thy_ctxt (name, ps) =
   430   case Symtab.lookup (get thy_ctxt, name) of
   430   case Symtab.curried_lookup (get thy_ctxt) name of
   431       NONE => NONE
   431       NONE => NONE
   432     | SOME reg => Registrations.lookup (thy_of thy_ctxt) (reg, ps);
   432     | SOME reg => Registrations.lookup (thy_of thy_ctxt) (reg, ps);
   433 
   433 
   434 val get_global_registration =
   434 val get_global_registration =
   435      gen_get_registration (#3 o GlobalLocalesData.get) I;
   435      gen_get_registration (#3 o GlobalLocalesData.get) I;
   450 
   450 
   451 fun gen_put_registration map_data thy_of (name, ps) attn thy_ctxt =
   451 fun gen_put_registration map_data thy_of (name, ps) attn thy_ctxt =
   452   map_data (fn regs =>
   452   map_data (fn regs =>
   453     let
   453     let
   454       val thy = thy_of thy_ctxt;
   454       val thy = thy_of thy_ctxt;
   455       val reg = getOpt (Symtab.lookup (regs, name), Registrations.empty);
   455       val reg = getOpt (Symtab.curried_lookup regs name, Registrations.empty);
   456       val (reg', sups) = Registrations.insert thy (ps, attn) reg;
   456       val (reg', sups) = Registrations.insert thy (ps, attn) reg;
   457       val _ = if not (null sups) then warning
   457       val _ = if not (null sups) then warning
   458                 ("Subsumed interpretation(s) of locale " ^
   458                 ("Subsumed interpretation(s) of locale " ^
   459                  quote (extern thy name) ^
   459                  quote (extern thy name) ^
   460                  "\nby interpretation(s) with the following prefix(es):\n" ^
   460                  "\nby interpretation(s) with the following prefix(es):\n" ^
   461                   commas_quote (map (fn (_, ((s, _), _)) => s) sups))
   461                   commas_quote (map (fn (_, ((s, _), _)) => s) sups))
   462               else ();
   462               else ();
   463     in Symtab.update ((name, reg'), regs) end) thy_ctxt;
   463     in Symtab.curried_update (name, reg') regs end) thy_ctxt;
   464 
   464 
   465 val put_global_registration =
   465 val put_global_registration =
   466      gen_put_registration (fn f =>
   466      gen_put_registration (fn f =>
   467        GlobalLocalesData.map (fn (space, locs, regs) => (space, locs, f regs))) I;
   467        GlobalLocalesData.map (fn (space, locs, regs) => (space, locs, f regs))) I;
   468 val put_local_registration =
   468 val put_local_registration =
   478 
   478 
   479 
   479 
   480 (* add witness theorem to registration in theory or context,
   480 (* add witness theorem to registration in theory or context,
   481    ignored if registration not present *)
   481    ignored if registration not present *)
   482 
   482 
   483 fun gen_add_witness map (name, ps) thm =
   483 fun gen_add_witness map_regs (name, ps) thm =
   484   map (fn regs =>
   484   map_regs (Symtab.map_entry name (Registrations.add_witness ps thm));
   485       let
       
   486         val reg = valOf (Symtab.lookup (regs, name));
       
   487       in
       
   488         Symtab.update ((name, Registrations.add_witness ps thm reg), regs)
       
   489       end handle Option => regs);
       
   490 
   485 
   491 val add_global_witness =
   486 val add_global_witness =
   492      gen_add_witness (fn f =>
   487      gen_add_witness (fn f =>
   493        GlobalLocalesData.map (fn (space, locs, regs) =>
   488        GlobalLocalesData.map (fn (space, locs, regs) =>
   494          (space, locs, f regs)));
   489          (space, locs, f regs)));
   548           else Pretty.block ((prt_attn attn @
   543           else Pretty.block ((prt_attn attn @
   549             [Pretty.str ":", Pretty.brk 1, prt_inst ts]));
   544             [Pretty.str ":", Pretty.brk 1, prt_inst ts]));
   550 
   545 
   551     val loc_int = intern thy loc;
   546     val loc_int = intern thy loc;
   552     val regs = get_regs thy_ctxt;
   547     val regs = get_regs thy_ctxt;
   553     val loc_regs = Symtab.lookup (regs, loc_int);
   548     val loc_regs = Symtab.curried_lookup regs loc_int;
   554   in
   549   in
   555     (case loc_regs of
   550     (case loc_regs of
   556         NONE => Pretty.str ("No interpretations in " ^ msg ^ ".")
   551         NONE => Pretty.str ("No interpretations in " ^ msg ^ ".")
   557       | SOME r => let
   552       | SOME r => let
   558             val r' = Registrations.dest r;
   553             val r' = Registrations.dest r;
   760 
   755 
   761 fun params_of elemss = gen_distinct eq_fst (List.concat (map (snd o fst) elemss));
   756 fun params_of elemss = gen_distinct eq_fst (List.concat (map (snd o fst) elemss));
   762 fun params_of' elemss = gen_distinct eq_fst (List.concat (map (snd o fst o fst) elemss));
   757 fun params_of' elemss = gen_distinct eq_fst (List.concat (map (snd o fst o fst) elemss));
   763 fun params_syn_of syn elemss =
   758 fun params_syn_of syn elemss =
   764   gen_distinct eq_fst (List.concat (map (snd o fst) elemss)) |>
   759   gen_distinct eq_fst (List.concat (map (snd o fst) elemss)) |>
   765     map (apfst (fn x => (x, valOf (Symtab.lookup (syn, x)))));
   760     map (apfst (fn x => (x, valOf (Symtab.curried_lookup syn x))));
   766 
   761 
   767 
   762 
   768 (* CB: param_types has the following type:
   763 (* CB: param_types has the following type:
   769   ('a * 'b option) list -> ('a * 'b) list *)
   764   ('a * 'b option) list -> ('a * 'b) list *)
   770 fun param_types ps = List.mapPartial (fn (_, NONE) => NONE | (x, SOME T) => SOME (x, T)) ps;
   765 fun param_types ps = List.mapPartial (fn (_, NONE) => NONE | (x, SOME T) => SOME (x, T)) ps;
  1006     fun eval syn ((name, xs), axs) =
  1001     fun eval syn ((name, xs), axs) =
  1007       let
  1002       let
  1008         val {params = (ps, qs), elems, ...} = the_locale thy name;
  1003         val {params = (ps, qs), elems, ...} = the_locale thy name;
  1009         val ps' = map (apsnd SOME o #1) ps;
  1004         val ps' = map (apsnd SOME o #1) ps;
  1010         val ren = map #1 ps' ~~
  1005         val ren = map #1 ps' ~~
  1011               map (fn x => (x, valOf (Symtab.lookup (syn, x)))) xs;
  1006               map (fn x => (x, valOf (Symtab.curried_lookup syn x))) xs;
  1012         val (params', elems') =
  1007         val (params', elems') =
  1013           if null ren then ((ps', qs), map #1 elems)
  1008           if null ren then ((ps', qs), map #1 elems)
  1014           else ((map (apfst (rename ren)) ps', map (rename ren) qs),
  1009           else ((map (apfst (rename ren)) ps', map (rename ren) qs),
  1015             map (rename_elem ren o #1) elems);
  1010             map (rename_elem ren o #1) elems);
  1016         val elems'' = map (rename_facts (space_implode "_" xs)) elems';
  1011         val elems'' = map (rename_facts (space_implode "_" xs)) elems';
  1738     val vtinst = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of ts) Vartab.empty;
  1733     val vtinst = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of ts) Vartab.empty;
  1739     val tinst = Vartab.dest vtinst |> map (fn ((x, 0), (_, T)) => (x, T))
  1734     val tinst = Vartab.dest vtinst |> map (fn ((x, 0), (_, T)) => (x, T))
  1740         |> Symtab.make;            
  1735         |> Symtab.make;            
  1741     (* replace parameter names in ids by instantiations *)
  1736     (* replace parameter names in ids by instantiations *)
  1742     val vinst = Symtab.make (parms ~~ vts);
  1737     val vinst = Symtab.make (parms ~~ vts);
  1743     fun vinst_names ps = map (fn p => Symtab.lookup (vinst, p) |> valOf) ps;
  1738     fun vinst_names ps = map (the o Symtab.curried_lookup vinst) ps;
  1744     val inst = Symtab.make (parms ~~ ts);
  1739     val inst = Symtab.make (parms ~~ ts);
  1745     val ids' = map (apsnd vinst_names) ids;
  1740     val ids' = map (apsnd vinst_names) ids;
  1746     val wits = List.concat (map (snd o valOf o get_global_registration thy) ids');
  1741     val wits = List.concat (map (snd o valOf o get_global_registration thy) ids');
  1747   in ((inst, tinst), wits) end;
  1742   in ((inst, tinst), wits) end;
  1748 
  1743 
  2006     |> note_thmss_qualified "" name facts' |> #1
  2001     |> note_thmss_qualified "" name facts' |> #1
  2007     |> declare_locale name
  2002     |> declare_locale name
  2008     |> put_locale name {predicate = predicate, import = import,
  2003     |> put_locale name {predicate = predicate, import = import,
  2009         elems = map (fn e => (e, stamp ())) elems',
  2004         elems = map (fn e => (e, stamp ())) elems',
  2010         params = (params_of elemss' |>
  2005         params = (params_of elemss' |>
  2011           map (fn (x, SOME T) => ((x, T), valOf (Symtab.lookup (syn, x)))), map #1 (params_of body_elemss)),
  2006           map (fn (x, SOME T) => ((x, T), the (Symtab.curried_lookup syn x))), map #1 (params_of body_elemss)),
  2012         regs = []}
  2007         regs = []}
  2013     |> pair (elems', body_ctxt)
  2008     |> pair (elems', body_ctxt)
  2014   end;
  2009   end;
  2015 
  2010 
  2016 in
  2011 in
  2175       let
  2170       let
  2176         val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of
  2171         val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of
  2177                NONE => error ("Instance missing for parameter " ^ quote p)
  2172                NONE => error ("Instance missing for parameter " ^ quote p)
  2178              | SOME (Free (_, T), t) => (t, T);
  2173              | SOME (Free (_, T), t) => (t, T);
  2179         val d = t |> inst_tab_term (inst, tinst) |> Envir.beta_norm;
  2174         val d = t |> inst_tab_term (inst, tinst) |> Envir.beta_norm;
  2180       in (Symtab.update_new ((p, d), inst), tinst) end;
  2175       in (Symtab.curried_update_new (p, d) inst, tinst) end;
  2181     val (inst, tinst) = Library.foldl add_def ((inst, tinst), not_given);
  2176     val (inst, tinst) = Library.foldl add_def ((inst, tinst), not_given);
  2182     (* Note: inst and tinst contain no vars. *)
  2177     (* Note: inst and tinst contain no vars. *)
  2183 
  2178 
  2184     (** compute proof obligations **)
  2179     (** compute proof obligations **)
  2185 
  2180