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 |