src/Pure/Isar/locale.ML
changeset 19278 4d762b77d319
parent 19276 ac90764bb654
child 19282 89949d8652c3
equal deleted inserted replaced
19277:f7602e74d948 19278:4d762b77d319
   146        from the locale predicate to the normalised assumptions of the locale
   146        from the locale predicate to the normalised assumptions of the locale
   147        (cf. [1], normalisation of locale expressions.)
   147        (cf. [1], normalisation of locale expressions.)
   148     *)
   148     *)
   149   import: expr,                                                     (*dynamic import*)
   149   import: expr,                                                     (*dynamic import*)
   150   elems: (Element.context_i * stamp) list,                          (*static content*)
   150   elems: (Element.context_i * stamp) list,                          (*static content*)
   151   params: ((string * typ) * mixfix) list * string list,             (*all/local params*)
   151   params: ((string * typ) * mixfix) list,                           (*all params*)
       
   152   lparams: string list,                                             (*local parmas*)
   152   abbrevs: ((bool * (bstring * term * mixfix) list) * stamp) list,  (*abbreviations*)
   153   abbrevs: ((bool * (bstring * term * mixfix) list) * stamp) list,  (*abbreviations*)
   153   regs: ((string * string list) * (term * thm) list) list}
   154   regs: ((string * string list) * (term * thm) list) list}
   154     (* Registrations: indentifiers and witness theorems of locales interpreted
   155     (* Registrations: indentifiers and witness theorems of locales interpreted
   155        in the locale.
   156        in the locale.
   156     *)
   157     *)
   264 
   265 
   265   val empty = (NameSpace.empty, Symtab.empty, Symtab.empty);
   266   val empty = (NameSpace.empty, Symtab.empty, Symtab.empty);
   266   val copy = I;
   267   val copy = I;
   267   val extend = I;
   268   val extend = I;
   268 
   269 
   269   fun join_locs _ ({predicate, import, elems, params, abbrevs, regs}: locale,
   270   fun join_locs _ ({predicate, import, elems, params, lparams, abbrevs, regs}: locale,
   270       {elems = elems', abbrevs = abbrevs', regs = regs', ...}: locale) =
   271       {elems = elems', abbrevs = abbrevs', regs = regs', ...}: locale) =
   271      {predicate = predicate,
   272      {predicate = predicate,
   272       import = import,
   273       import = import,
   273       elems = gen_merge_lists (eq_snd (op =)) elems elems',
   274       elems = gen_merge_lists (eq_snd (op =)) elems elems',
   274       params = params,
   275       params = params,
       
   276       lparams = lparams,
   275       abbrevs = Library.merge (eq_snd (op =)) (abbrevs, abbrevs'),
   277       abbrevs = Library.merge (eq_snd (op =)) (abbrevs, abbrevs'),
   276       regs = merge_alists regs regs'};
   278       regs = merge_alists regs regs'};
   277   fun merge _ ((space1, locs1, regs1), (space2, locs2, regs2)) =
   279   fun merge _ ((space1, locs1, regs1), (space2, locs2, regs2)) =
   278     (NameSpace.merge (space1, space2), Symtab.join join_locs (locs1, locs2),
   280     (NameSpace.merge (space1, space2), Symtab.join join_locs (locs1, locs2),
   279      Symtab.join (K Registrations.join) (regs1, regs2));
   281      Symtab.join (K Registrations.join) (regs1, regs2));
   323     SOME loc => loc
   325     SOME loc => loc
   324   | NONE => error ("Unknown locale " ^ quote name));
   326   | NONE => error ("Unknown locale " ^ quote name));
   325 
   327 
   326 fun change_locale name f thy =
   328 fun change_locale name f thy =
   327   let
   329   let
   328     val {predicate, import, elems , params, abbrevs, regs} = the_locale thy name;
   330     val {predicate, import, elems, params, lparams, abbrevs, regs} = the_locale thy name;
   329     val (predicate', import', elems', params', abbrevs', regs') =
   331     val (predicate', import', elems', params', lparams', abbrevs', regs') =
   330       f (predicate, import, elems, params, abbrevs, regs);
   332       f (predicate, import, elems, params, lparams, abbrevs, regs);
   331   in
   333   in
   332     put_locale name {predicate = predicate', import = import', elems = elems',
   334     put_locale name {predicate = predicate', import = import', elems = elems',
   333       params = params', abbrevs = abbrevs', regs = regs'} thy
   335       params = params', lparams = lparams', abbrevs = abbrevs', regs = regs'} thy
   334   end;
   336   end;
   335 
   337 
   336 
   338 
   337 (* access registrations *)
   339 (* access registrations *)
   338 
   340 
   393        GlobalLocalesData.map (fn (space, locs, regs) => (space, locs, f regs))) I;
   395        GlobalLocalesData.map (fn (space, locs, regs) => (space, locs, f regs))) I;
   394 val put_local_registration =
   396 val put_local_registration =
   395      gen_put_registration LocalLocalesData.map ProofContext.theory_of;
   397      gen_put_registration LocalLocalesData.map ProofContext.theory_of;
   396 
   398 
   397 fun put_registration_in_locale name id =
   399 fun put_registration_in_locale name id =
   398   change_locale name (fn (predicate, import, elems, params, abbrevs, regs) =>
   400   change_locale name (fn (predicate, import, elems, params, lparams, abbrevs, regs) =>
   399     (predicate, import, elems, params, abbrevs, regs @ [(id, [])]));
   401     (predicate, import, elems, params, lparams, abbrevs, regs @ [(id, [])]));
   400 
   402 
   401 
   403 
   402 (* add witness theorem to registration in theory or context,
   404 (* add witness theorem to registration in theory or context,
   403    ignored if registration not present *)
   405    ignored if registration not present *)
   404 
   406 
   409   GlobalLocalesData.map (fn (space, locs, regs) => (space, locs, add_witness id thm regs));
   411   GlobalLocalesData.map (fn (space, locs, regs) => (space, locs, add_witness id thm regs));
   410 
   412 
   411 val add_local_witness = LocalLocalesData.map oo add_witness;
   413 val add_local_witness = LocalLocalesData.map oo add_witness;
   412 
   414 
   413 fun add_witness_in_locale name id thm =
   415 fun add_witness_in_locale name id thm =
   414   change_locale name (fn (predicate, import, elems, params, abbrevs, regs) =>
   416   change_locale name (fn (predicate, import, elems, params, lparams, abbrevs, regs) =>
   415     let
   417     let
   416       fun add (id', thms) =
   418       fun add (id', thms) =
   417         if id = id' then (id', thm :: thms) else (id', thms);
   419         if id = id' then (id', thm :: thms) else (id', thms);
   418     in (predicate, import, elems, params, abbrevs, map add regs) end);
   420     in (predicate, import, elems, params, lparams, abbrevs, map add regs) end);
   419 
   421 
   420 
   422 
   421 (* printing of registrations *)
   423 (* printing of registrations *)
   422 
   424 
   423 fun gen_print_registrations get_regs mk_ctxt msg show_wits loc thy_ctxt =
   425 fun gen_print_registrations get_regs mk_ctxt msg show_wits loc thy_ctxt =
   694        adjust hyps of witness theorems *)
   696        adjust hyps of witness theorems *)
   695 
   697 
   696     fun add_regs (name, ps) (ths, ids) =
   698     fun add_regs (name, ps) (ths, ids) =
   697         let
   699         let
   698           val {params, regs, ...} = the_locale thy name;
   700           val {params, regs, ...} = the_locale thy name;
   699           val ps' = map #1 (#1 params);
   701           val ps' = map #1 params;
   700           val ren = map #1 ps' ~~ map (fn (x, _) => (x, NONE)) ps;
   702           val ren = map #1 ps' ~~ map (fn (x, _) => (x, NONE)) ps;
   701             (* dummy syntax, since required by rename *)
   703             (* dummy syntax, since required by rename *)
   702           val ps'' = map (fn ((p, _), (_, T)) => (p, T)) (ps ~~ ps');
   704           val ps'' = map (fn ((p, _), (_, T)) => (p, T)) (ps ~~ ps');
   703           val [env] = unify_parms ctxt ps [map (apsnd SOME) ps''];
   705           val [env] = unify_parms ctxt ps [map (apsnd SOME) ps''];
   704             (* propagate parameter types, to keep them consistent *)
   706             (* propagate parameter types, to keep them consistent *)
   740        identify at top level (top = true);
   742        identify at top level (top = true);
   741        parms is accumulated list of parameters *)
   743        parms is accumulated list of parameters *)
   742           let
   744           let
   743             val {predicate = (_, axioms), import, params, ...} =
   745             val {predicate = (_, axioms), import, params, ...} =
   744               the_locale thy name;
   746               the_locale thy name;
   745             val ps = map (#1 o #1) (#1 params);
   747             val ps = map (#1 o #1) params;
   746             val (ids', parms', _) = identify false import;
   748             val (ids', parms', _) = identify false import;
   747                 (* acyclic import dependencies *)
   749                 (* acyclic import dependencies *)
   748             val ids'' = ids' @ [((name, ps), ([], Assumed []))];
   750             val ids'' = ids' @ [((name, ps), ([], Assumed []))];
   749             val (_, ids''') = add_regs (name, map #1 (#1 params)) ([], ids'');
   751             val (_, ids''') = add_regs (name, map #1 params) ([], ids'');
   750 
   752 
   751             val ids_ax = if top then fst
   753             val ids_ax = if top then fst
   752                  (fold_map (axiomify ps) ids''' axioms)
   754                  (fold_map (axiomify ps) ids''' axioms)
   753               else ids''';
   755               else ids''';
   754             val syn = Symtab.make (map (apfst fst) (#1 params));
   756             val syn = Symtab.make (map (apfst fst) params);
   755             in (ids_ax, merge_lists parms' ps, syn) end
   757             in (ids_ax, merge_lists parms' ps, syn) end
   756       | identify top (Rename (e, xs)) =
   758       | identify top (Rename (e, xs)) =
   757           let
   759           let
   758             val (ids', parms', syn') = identify top e;
   760             val (ids', parms', syn') = identify top e;
   759             val ren = renaming xs parms'
   761             val ren = renaming xs parms'
   780        the corresponding elements (with renamed parameters),
   782        the corresponding elements (with renamed parameters),
   781        also takes care of parameter syntax *)
   783        also takes care of parameter syntax *)
   782 
   784 
   783     fun eval syn ((name, xs), axs) =
   785     fun eval syn ((name, xs), axs) =
   784       let
   786       let
   785         val {params = (ps, qs), elems, ...} = the_locale thy name;
   787         val {params = ps, lparams = qs, elems, ...} = the_locale thy name;
   786         val ps' = map (apsnd SOME o #1) ps;
   788         val ps' = map (apsnd SOME o #1) ps;
   787         fun lookup_syn x = (case Symtab.lookup syn x of SOME Structure => NONE | opt => opt);
   789         fun lookup_syn x = (case Symtab.lookup syn x of SOME Structure => NONE | opt => opt);
   788         val ren = map #1 ps' ~~ map (fn x => (x, lookup_syn x)) xs;
   790         val ren = map #1 ps' ~~ map (fn x => (x, lookup_syn x)) xs;
   789         val (params', elems') =
   791         val (params', elems') =
   790           if null ren then ((ps', qs), map #1 elems)
   792           if null ren then ((ps', qs), map #1 elems)
  1273   end;
  1275   end;
  1274 
  1276 
  1275 in
  1277 in
  1276 
  1278 
  1277 fun parameters_of thy name =
  1279 fun parameters_of thy name =
  1278   the_locale thy name |> #params |> fst;
  1280   the_locale thy name |> #params;
  1279 
  1281 
  1280 fun parameters_of_expr thy expr =
  1282 fun parameters_of_expr thy expr =
  1281   let
  1283   let
  1282     val ctxt = ProofContext.init thy;
  1284     val ctxt = ProofContext.init thy;
  1283     val ((_, syn), raw_elemss) = flatten (ctxt, intern_expr thy)
  1285     val ((_, syn), raw_elemss) = flatten (ctxt, intern_expr thy)
  1341     val locale = Option.map (prep_locale thy) raw_locale;
  1343     val locale = Option.map (prep_locale thy) raw_locale;
  1342     val (locale_stmt, fixed_params, import) =
  1344     val (locale_stmt, fixed_params, import) =
  1343       (case locale of
  1345       (case locale of
  1344         NONE => ([], [], empty)
  1346         NONE => ([], [], empty)
  1345       | SOME name =>
  1347       | SOME name =>
  1346           let val {predicate = (stmt, _), params = (ps, _), ...} = the_locale thy name
  1348           let val {predicate = (stmt, _), params = ps, ...} = the_locale thy name
  1347           in (stmt, map fst ps, Locale name) end);
  1349           in (stmt, map fst ps, Locale name) end);
  1348     val ((((locale_ctxt, _), (elems_ctxt, _, _)), _), (elems_stmt, concl')) =
  1350     val ((((locale_ctxt, _), (elems_ctxt, _, _)), _), (elems_stmt, concl')) =
  1349       prep_ctxt false fixed_params import elems concl ctxt;
  1351       prep_ctxt false fixed_params import elems concl ctxt;
  1350   in (locale, (locale_stmt, locale_ctxt), (elems_stmt, elems_ctxt), concl') end;
  1352   in (locale, (locale_stmt, locale_ctxt), (elems_stmt, elems_ctxt), concl') end;
  1351 
  1353 
  1422 (* store instantiations of args for all registered interpretations
  1424 (* store instantiations of args for all registered interpretations
  1423    of the theory *)
  1425    of the theory *)
  1424 
  1426 
  1425 fun note_thmss_registrations kind target args thy =
  1427 fun note_thmss_registrations kind target args thy =
  1426   let
  1428   let
  1427     val parms = the_locale thy target |> #params |> fst |> map fst;
  1429     val parms = the_locale thy target |> #params |> map fst;
  1428     val ids = flatten (ProofContext.init thy, intern_expr thy)
  1430     val ids = flatten (ProofContext.init thy, intern_expr thy)
  1429       (([], Symtab.empty), Expr (Locale target)) |> fst |> fst
  1431       (([], Symtab.empty), Expr (Locale target)) |> fst |> fst
  1430       |> List.mapPartial (fn (id, (_, Assumed _)) => SOME id | _ => NONE)
  1432       |> List.mapPartial (fn (id, (_, Assumed _)) => SOME id | _ => NONE)
  1431 
  1433 
  1432     val regs = get_global_registrations thy target;
  1434     val regs = get_global_registrations thy target;
  1450 (* abbreviations *)
  1452 (* abbreviations *)
  1451 
  1453 
  1452 fun add_abbrevs loc revert decls =
  1454 fun add_abbrevs loc revert decls =
  1453   snd #> ProofContext.add_abbrevs_i revert decls #>
  1455   snd #> ProofContext.add_abbrevs_i revert decls #>
  1454   ProofContext.map_theory (change_locale loc
  1456   ProofContext.map_theory (change_locale loc
  1455     (fn (predicate, import, elems, params, abbrevs, regs) =>
  1457     (fn (predicate, import, elems, params, lparams, abbrevs, regs) =>
  1456       (predicate, import, elems, params, ((revert, decls), stamp ()) :: abbrevs, regs)));
  1458       (predicate, import, elems, params, lparams, ((revert, decls), stamp ()) :: abbrevs, regs)));
  1457 
  1459 
  1458 fun init_abbrevs loc ctxt =
  1460 fun init_abbrevs loc ctxt =
  1459   fold_rev (uncurry ProofContext.add_abbrevs_i o fst)
  1461   fold_rev (uncurry ProofContext.add_abbrevs_i o fst)
  1460     (#abbrevs (the_locale (ProofContext.theory_of ctxt) loc)) ctxt;
  1462     (#abbrevs (the_locale (ProofContext.theory_of ctxt) loc)) ctxt;
  1461 
  1463 
  1480   let
  1482   let
  1481     val (ctxt', ([(_, [Notes args'])], facts)) =
  1483     val (ctxt', ([(_, [Notes args'])], facts)) =
  1482       activate_facts prep_facts (ctxt, [((("", []), Assumed []), [Ext (Notes args)])]);
  1484       activate_facts prep_facts (ctxt, [((("", []), Assumed []), [Ext (Notes args)])]);
  1483     val (facts', thy') =
  1485     val (facts', thy') =
  1484       thy
  1486       thy
  1485       |> change_locale loc (fn (predicate, import, elems, params, abbrevs, regs) =>
  1487       |> change_locale loc (fn (predicate, import, elems, params, lparams, abbrevs, regs) =>
  1486         (predicate, import, elems @ [(Notes args', stamp ())], params, abbrevs, regs))
  1488         (predicate, import, elems @ [(Notes args', stamp ())], params, lparams, abbrevs, regs))
  1487       |> note_thmss_registrations kind loc args'
  1489       |> note_thmss_registrations kind loc args'
  1488       |> global_results (map (#1 o #1) args' ~~ map #2 facts) (view, ctxt);
  1490       |> global_results (map (#1 o #1) args' ~~ map #2 facts) (view, ctxt);
  1489   in ((facts, facts'), (ProofContext.transfer thy' ctxt', thy')) end;
  1491   in ((facts, facts'), (ProofContext.transfer thy' ctxt', thy')) end;
  1490 
  1492 
  1491 fun gen_note prep_locale prep_facts kind raw_loc args thy =
  1493 fun gen_note prep_locale prep_facts kind raw_loc args thy =
  1700       |> declare_locale name
  1702       |> declare_locale name
  1701       |> put_locale name
  1703       |> put_locale name
  1702        {predicate = predicate,
  1704        {predicate = predicate,
  1703         import = import,
  1705         import = import,
  1704         elems = map (fn e => (e, stamp ())) elems',
  1706         elems = map (fn e => (e, stamp ())) elems',
  1705         params = (params_of elemss' |> map (fn (x, SOME T) => ((x, T), the (Symtab.lookup syn x))),
  1707         params = params_of elemss' |> map (fn (x, SOME T) => ((x, T), the (Symtab.lookup syn x))),
  1706           map #1 (params_of body_elemss)),
  1708         lparams = map #1 (params_of body_elemss),
  1707         abbrevs = [],
  1709         abbrevs = [],
  1708         regs = []};
  1710         regs = []};
  1709   in (ProofContext.transfer thy' body_ctxt, thy') end;
  1711   in (ProofContext.transfer thy' body_ctxt, thy') end;
  1710 
  1712 
  1711 in
  1713 in
  2006   (* target already in internal form *)
  2008   (* target already in internal form *)
  2007   let
  2009   let
  2008     val ctxt = ProofContext.init thy;
  2010     val ctxt = ProofContext.init thy;
  2009     val ((raw_target_ids, target_syn), _) = flatten (ctxt, I)
  2011     val ((raw_target_ids, target_syn), _) = flatten (ctxt, I)
  2010         (([], Symtab.empty), Expr (Locale target));
  2012         (([], Symtab.empty), Expr (Locale target));
  2011     val fixed = the_locale thy target |> #params |> #1 |> map #1;
  2013     val fixed = the_locale thy target |> #params |> map #1;
  2012     val ((all_ids, syn), raw_elemss) = flatten (ctxt, intern_expr thy)
  2014     val ((all_ids, syn), raw_elemss) = flatten (ctxt, intern_expr thy)
  2013         ((raw_target_ids, target_syn), Expr expr);
  2015         ((raw_target_ids, target_syn), Expr expr);
  2014     val (target_ids, ids) = chop (length raw_target_ids) all_ids;
  2016     val (target_ids, ids) = chop (length raw_target_ids) all_ids;
  2015     val ((parms, elemss, _), _) = read_elemss false ctxt fixed raw_elemss [];
  2017     val ((parms, elemss, _), _) = read_elemss false ctxt fixed raw_elemss [];
  2016 
  2018