185 |
185 |
186 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b; |
186 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b; |
187 |
187 |
188 |
188 |
189 |
189 |
|
190 (** substitutions on Frees and Vars -- clone from element.ML **) |
|
191 |
|
192 (* instantiate types *) |
|
193 |
|
194 fun var_instT_type env = |
|
195 if Vartab.is_empty env then I |
|
196 else Term.map_type_tvar (fn (x, S) => the_default (TVar (x, S)) (Vartab.lookup env x)); |
|
197 |
|
198 fun var_instT_term env = |
|
199 if Vartab.is_empty env then I |
|
200 else Term.map_types (var_instT_type env); |
|
201 |
|
202 fun var_inst_term (envT, env) = |
|
203 if Vartab.is_empty env then var_instT_term envT |
|
204 else |
|
205 let |
|
206 val instT = var_instT_type envT; |
|
207 fun inst (Const (x, T)) = Const (x, instT T) |
|
208 | inst (Free (x, T)) = Free(x, instT T) |
|
209 | inst (Var (xi, T)) = |
|
210 (case Vartab.lookup env xi of |
|
211 NONE => Var (xi, instT T) |
|
212 | SOME t => t) |
|
213 | inst (b as Bound _) = b |
|
214 | inst (Abs (x, T, t)) = Abs (x, instT T, inst t) |
|
215 | inst (t $ u) = inst t $ inst u; |
|
216 in Envir.beta_norm o inst end; |
|
217 |
|
218 |
190 (** management of registrations in theories and proof contexts **) |
219 (** management of registrations in theories and proof contexts **) |
191 |
220 |
192 structure Registrations : |
221 structure Registrations : |
193 sig |
222 sig |
194 type T |
223 type T |
195 val empty: T |
224 val empty: T |
196 val join: T * T -> T |
225 val join: T * T -> T |
197 val dest: theory -> T -> |
226 val dest: theory -> T -> |
198 (term list * |
227 (term list * |
199 (((bool * string) * Attrib.src list) * Element.witness list * |
228 (((bool * string) * Attrib.src list) * |
|
229 (Morphism.morphism * ((typ Vartab.table * typ list) * (term Vartab.table * term list))) * |
|
230 Element.witness list * |
200 thm Termtab.table)) list |
231 thm Termtab.table)) list |
201 val lookup: theory -> T * term list -> |
232 val test: theory -> T * term list -> bool |
202 (((bool * string) * Attrib.src list) * Element.witness list * |
233 val lookup: theory -> |
203 thm Termtab.table) option |
234 T * (term list * ((typ Vartab.table * typ list) * (term Vartab.table * term list))) -> |
204 val insert: theory -> term list * ((bool * string) * Attrib.src list) -> T -> |
235 (((bool * string) * Attrib.src list) * |
|
236 Element.witness list * |
|
237 thm Termtab.table) option |
|
238 val insert: theory -> term list -> ((bool * string) * Attrib.src list) -> |
|
239 (Morphism.morphism * ((typ Vartab.table * typ list) * (term Vartab.table * term list))) -> T -> |
205 T * (term list * (((bool * string) * Attrib.src list) * Element.witness list)) list |
240 T * (term list * (((bool * string) * Attrib.src list) * Element.witness list)) list |
206 val add_witness: term list -> Element.witness -> T -> T |
241 val add_witness: term list -> Element.witness -> T -> T |
207 val add_equation: term list -> thm -> T -> T |
242 val add_equation: term list -> thm -> T -> T |
208 end = |
243 end = |
209 struct |
244 struct |
210 (* A registration is indexed by parameter instantiation. Its components are: |
245 (* A registration is indexed by parameter instantiation. Its components are: |
211 - parameters and prefix |
246 - parameters and prefix |
212 (if the Boolean flag is set, only accesses containing the prefix are generated, |
247 (if the Boolean flag is set, only accesses containing the prefix are generated, |
213 otherwise the prefix may be omitted when accessing theorems etc.) |
248 otherwise the prefix may be omitted when accessing theorems etc.) |
|
249 - pair of export and import morphisms, export maps content to its originating |
|
250 context, import is its inverse |
214 - theorems (actually witnesses) instantiating locale assumptions |
251 - theorems (actually witnesses) instantiating locale assumptions |
215 - theorems (equations) interpreting derived concepts and indexed by lhs |
252 - theorems (equations) interpreting derived concepts and indexed by lhs. |
|
253 NB: index is exported while content is internalised. |
216 *) |
254 *) |
217 type T = (((bool * string) * Attrib.src list) * Element.witness list * |
255 type T = (((bool * string) * Attrib.src list) * |
|
256 (Morphism.morphism * ((typ Vartab.table * typ list) * (term Vartab.table * term list))) * |
|
257 Element.witness list * |
218 thm Termtab.table) Termtab.table; |
258 thm Termtab.table) Termtab.table; |
219 |
259 |
220 val empty = Termtab.empty; |
260 val empty = Termtab.empty; |
221 |
261 |
222 (* term list represented as single term, for simultaneous matching *) |
262 (* term list represented as single term, for simultaneous matching *) |
226 let fun ut (Const _) ts = ts |
266 let fun ut (Const _) ts = ts |
227 | ut (s $ t) ts = ut s (t::ts) |
267 | ut (s $ t) ts = ut s (t::ts) |
228 in ut t [] end; |
268 in ut t [] end; |
229 |
269 |
230 (* joining of registrations: |
270 (* joining of registrations: |
231 - prefix and attributes of right theory; |
271 - prefix, attributes and morphisms of right theory; |
232 - witnesses are equal, no attempt to subsumption testing; |
272 - witnesses are equal, no attempt to subsumption testing; |
233 - union of equalities, if conflicting (i.e. two eqns with equal lhs) |
273 - union of equalities, if conflicting (i.e. two eqns with equal lhs) |
234 eqn of right theory takes precedence *) |
274 eqn of right theory takes precedence *) |
235 fun join (r1, r2) = Termtab.join (fn _ => fn ((_, _, e1), (n, w, e2)) => |
275 fun join (r1, r2) = Termtab.join (fn _ => fn ((_, _, _, e1), (n, m, w, e2)) => |
236 (n, w, Termtab.join (fn _ => fn (_, e) => e) (e1, e2))) (r1, r2); |
276 (n, m, w, Termtab.join (fn _ => fn (_, e) => e) (e1, e2))) (r1, r2); |
237 |
277 |
238 fun dest_transfer thy regs = |
278 fun dest_transfer thy regs = |
239 Termtab.dest regs |> map (apsnd (fn (n, ws, es) => |
279 Termtab.dest regs |> map (apsnd (fn (n, m, ws, es) => |
240 (n, map (Element.transfer_witness thy) ws, Termtab.map (transfer thy) es))); |
280 (n, m, map (Element.transfer_witness thy) ws, Termtab.map (transfer thy) es))); |
241 |
281 |
242 fun dest thy regs = dest_transfer thy regs |> map (apfst untermify); |
282 fun dest thy regs = dest_transfer thy regs |> map (apfst untermify); |
243 |
283 |
244 (* registrations that subsume t *) |
284 (* registrations that subsume t *) |
245 fun subsumers thy t regs = |
285 fun subsumers thy t regs = |
246 filter (fn (t', _) => Pattern.matches thy (t', t)) (dest_transfer thy regs); |
286 filter (fn (t', _) => Pattern.matches thy (t', t)) (dest_transfer thy regs); |
247 |
287 |
|
288 (* test if registration that subsumes the query is present *) |
|
289 fun test thy (regs, ts) = |
|
290 not (null (subsumers thy (termify ts) regs)); |
|
291 |
248 (* look up registration, pick one that subsumes the query *) |
292 (* look up registration, pick one that subsumes the query *) |
249 fun lookup thy (regs, ts) = |
293 fun lookup thy (regs, (ts, ((impT, _), (imp, _)))) = |
250 let |
294 let |
251 val t = termify ts; |
295 val t = termify ts; |
252 val subs = subsumers thy t regs; |
296 val subs = subsumers thy t regs; |
253 in |
297 in |
254 (case subs of |
298 (case subs of |
255 [] => NONE |
299 [] => NONE |
256 | ((t', (attn, thms, eqns)) :: _) => |
300 | ((t', ((prfx, atts), (exp', ((impT', domT'), (imp', dom'))), thms, eqns)) :: _) => |
257 let |
301 let |
258 val (tinst, inst) = Pattern.match thy (t', t) (Vartab.empty, Vartab.empty); |
302 val (tinst, inst) = Pattern.match thy (t', t) (Vartab.empty, Vartab.empty); |
259 (* thms contain Frees, not Vars *) |
303 val tinst' = domT' |> map (fn (T as TFree (x, _)) => |
260 val tinst' = tinst |> Vartab.dest (* FIXME Vartab.map (!?) *) |
304 (x, T |> Morphism.typ exp' |> Envir.typ_subst_TVars tinst |
261 |> map (fn ((x, 0), (_, T)) => (x, Logic.legacy_unvarifyT T)) |
305 |> var_instT_type impT)) |> Symtab.make; |
262 |> Symtab.make; |
306 val inst' = dom' |> map (fn (t as Free (x, _)) => |
263 val inst' = inst |> Vartab.dest |
307 (x, t |> Morphism.term exp' |> Envir.subst_vars (tinst, inst) |
264 |> map (fn ((x, 0), (_, t)) => (x, Logic.legacy_unvarify t)) |
308 |> var_inst_term (impT, imp))) |> Symtab.make; |
265 |> Symtab.make; |
309 val inst'_morph = Element.inst_morphism thy (tinst', inst'); |
266 val inst_morph = Element.inst_morphism thy (tinst', inst'); |
310 in SOME ((prfx, map (Args.morph_values inst'_morph) atts), |
267 in SOME (attn, map (Element.morph_witness inst_morph) thms, |
311 map (Element.morph_witness inst'_morph) thms, |
268 Termtab.map (Morphism.thm inst_morph) eqns) |
312 Termtab.map (Morphism.thm inst'_morph) eqns) |
269 end) |
313 end) |
270 end; |
314 end; |
271 |
315 |
272 (* add registration if not subsumed by ones already present, |
316 (* add registration if not subsumed by ones already present, |
273 additionally returns registrations that are strictly subsumed *) |
317 additionally returns registrations that are strictly subsumed *) |
274 fun insert thy (ts, attn) regs = |
318 fun insert thy ts attn m regs = |
275 let |
319 let |
276 val t = termify ts; |
320 val t = termify ts; |
277 val subs = subsumers thy t regs ; |
321 val subs = subsumers thy t regs ; |
278 in (case subs of |
322 in (case subs of |
279 [] => let |
323 [] => let |
280 val sups = |
324 val sups = |
281 filter (fn (t', _) => Pattern.matches thy (t, t')) (dest_transfer thy regs); |
325 filter (fn (t', _) => Pattern.matches thy (t, t')) (dest_transfer thy regs); |
282 val sups' = map (apfst untermify) sups |> map (fn (ts, (n, w, d)) => (ts, (n, w))) |
326 val sups' = map (apfst untermify) sups |> map (fn (ts, (n, _, w, _)) => (ts, (n, w))) |
283 in (Termtab.update (t, (attn, [], Termtab.empty)) regs, sups') end |
327 in (Termtab.update (t, (attn, m, [], Termtab.empty)) regs, sups') end |
284 | _ => (regs, [])) |
328 | _ => (regs, [])) |
285 end; |
329 end; |
286 |
330 |
287 fun gen_add f ts thm regs = |
331 fun gen_add f ts thm regs = |
288 let |
332 let |
292 end; |
336 end; |
293 |
337 |
294 (* add witness theorem to registration, |
338 (* add witness theorem to registration, |
295 only if instantiation is exact, otherwise exception Option raised *) |
339 only if instantiation is exact, otherwise exception Option raised *) |
296 fun add_witness ts thm regs = |
340 fun add_witness ts thm regs = |
297 gen_add (fn thm => fn (x, thms, eqns) => (x, thm::thms, eqns)) ts thm regs; |
341 gen_add (fn thm => fn (x, m, thms, eqns) => (x, m, thm::thms, eqns)) ts thm regs; |
298 |
342 |
299 (* add equation to registration, replaces previous equation with same lhs; |
343 (* add equation to registration, replaces previous equation with same lhs; |
300 only if instantiation is exact, otherwise exception Option raised; |
344 only if instantiation is exact, otherwise exception Option raised; |
301 exception TERM raised if not a meta equality *) |
345 exception TERM raised if not a meta equality *) |
302 fun add_equation ts thm regs = |
346 fun add_equation ts thm regs = |
303 gen_add (fn thm => fn (x, thms, eqns) => |
347 gen_add (fn thm => fn (x, m, thms, eqns) => |
304 (x, thms, Termtab.update (thm |> prop_of |> Logic.dest_equals |> fst, thm) eqns)) |
348 (x, m, thms, Termtab.update (thm |> prop_of |> Logic.dest_equals |> fst, thm) eqns)) |
305 ts thm regs; |
349 ts thm regs; |
306 end; |
350 end; |
307 |
351 |
308 |
352 |
309 (** theory data : locales **) |
353 (** theory data : locales **) |
403 |
442 |
404 fun get_global_registrations thy = get_registrations (Context.Theory thy); |
443 fun get_global_registrations thy = get_registrations (Context.Theory thy); |
405 fun get_local_registrations ctxt = get_registrations (Context.Proof ctxt); |
444 fun get_local_registrations ctxt = get_registrations (Context.Proof ctxt); |
406 |
445 |
407 |
446 |
408 fun get_registration ctxt (name, ps) = |
447 fun get_registration ctxt import (name, ps) = |
409 case Symtab.lookup (RegistrationsData.get ctxt) name of |
448 case Symtab.lookup (RegistrationsData.get ctxt) name of |
410 NONE => NONE |
449 NONE => NONE |
411 | SOME reg => Registrations.lookup (Context.theory_of ctxt) (reg, ps); |
450 | SOME reg => Registrations.lookup (Context.theory_of ctxt) (reg, (ps, import)); |
412 |
451 |
413 fun get_global_registration thy = get_registration (Context.Theory thy); |
452 fun get_global_registration thy = get_registration (Context.Theory thy); |
414 fun get_local_registration ctxt = get_registration (Context.Proof ctxt); |
453 fun get_local_registration ctxt = get_registration (Context.Proof ctxt); |
415 |
454 |
416 val test_global_registration = is_some oo get_global_registration; |
455 |
417 val test_local_registration = is_some oo get_local_registration; |
456 fun test_registration ctxt (name, ps) = |
|
457 case Symtab.lookup (RegistrationsData.get ctxt) name of |
|
458 NONE => false |
|
459 | SOME reg => Registrations.test (Context.theory_of ctxt) (reg, ps); |
|
460 |
|
461 fun test_global_registration thy = test_registration (Context.Theory thy); |
|
462 fun test_local_registration ctxt = test_registration (Context.Proof ctxt); |
|
463 |
418 |
464 |
419 (* add registration to theory or context, ignored if subsumed *) |
465 (* add registration to theory or context, ignored if subsumed *) |
420 |
466 |
421 fun put_registration (name, ps) attn ctxt = |
467 fun put_registration (name, ps) attn morphs ctxt = |
422 RegistrationsData.map (fn regs => |
468 RegistrationsData.map (fn regs => |
423 let |
469 let |
424 val thy = Context.theory_of ctxt; |
470 val thy = Context.theory_of ctxt; |
425 val reg = the_default Registrations.empty (Symtab.lookup regs name); |
471 val reg = the_default Registrations.empty (Symtab.lookup regs name); |
426 val (reg', sups) = Registrations.insert thy (ps, attn) reg; |
472 val (reg', sups) = Registrations.insert thy ps attn morphs reg; |
427 val _ = if not (null sups) then warning |
473 val _ = if not (null sups) then warning |
428 ("Subsumed interpretation(s) of locale " ^ |
474 ("Subsumed interpretation(s) of locale " ^ |
429 quote (extern thy name) ^ |
475 quote (extern thy name) ^ |
430 "\nwith the following prefix(es):" ^ |
476 "\nwith the following prefix(es):" ^ |
431 commas_quote (map (fn (_, (((_, s), _), _)) => s) sups)) |
477 commas_quote (map (fn (_, (((_, s), _), _)) => s) sups)) |
432 else (); |
478 else (); |
433 in Symtab.update (name, reg') regs end) ctxt; |
479 in Symtab.update (name, reg') regs end) ctxt; |
434 |
480 |
435 fun put_global_registration id attn = Context.theory_map (put_registration id attn); |
481 fun put_global_registration id attn morphs = |
436 fun put_local_registration id attn = Context.proof_map (put_registration id attn); |
482 Context.theory_map (put_registration id attn morphs); |
|
483 fun put_local_registration id attn morphs = |
|
484 Context.proof_map (put_registration id attn morphs); |
437 |
485 |
438 |
486 |
439 fun put_registration_in_locale name id = |
487 fun put_registration_in_locale name id = |
440 change_locale name (fn (axiom, imports, elems, params, lparams, decls, regs, intros) => |
488 change_locale name (fn (axiom, imports, elems, params, lparams, decls, regs, intros) => |
441 (axiom, imports, elems, params, lparams, decls, regs @ [(id, [])], intros)); |
489 (axiom, imports, elems, params, lparams, decls, regs @ [(id, [])], intros)); |
491 fun prt_core ts eqns = |
539 fun prt_core ts eqns = |
492 [prt_inst ts, Pretty.fbrk, prt_eqns (Termtab.dest eqns |> map snd)]; |
540 [prt_inst ts, Pretty.fbrk, prt_eqns (Termtab.dest eqns |> map snd)]; |
493 fun prt_witns [] = Pretty.str "no witnesses." |
541 fun prt_witns [] = Pretty.str "no witnesses." |
494 | prt_witns witns = Pretty.block (Pretty.str "witnesses:" :: Pretty.brk 1 :: |
542 | prt_witns witns = Pretty.block (Pretty.str "witnesses:" :: Pretty.brk 1 :: |
495 Pretty.breaks (map (Element.pretty_witness ctxt) witns)) |
543 Pretty.breaks (map (Element.pretty_witness ctxt) witns)) |
496 fun prt_reg (ts, (((_, ""), []), witns, eqns)) = |
544 fun prt_reg (ts, (((_, ""), []), _, witns, eqns)) = |
497 if show_wits |
545 if show_wits |
498 then Pretty.block (prt_core ts eqns @ [Pretty.fbrk, prt_witns witns]) |
546 then Pretty.block (prt_core ts eqns @ [Pretty.fbrk, prt_witns witns]) |
499 else Pretty.block (prt_core ts eqns) |
547 else Pretty.block (prt_core ts eqns) |
500 | prt_reg (ts, (attn, witns, eqns)) = |
548 | prt_reg (ts, (attn, _, witns, eqns)) = |
501 if show_wits |
549 if show_wits |
502 then Pretty.block ((prt_attn attn @ [Pretty.str ":", Pretty.brk 1] @ |
550 then Pretty.block ((prt_attn attn @ [Pretty.str ":", Pretty.brk 1] @ |
503 prt_core ts eqns @ [Pretty.fbrk, prt_witns witns])) |
551 prt_core ts eqns @ [Pretty.fbrk, prt_witns witns])) |
504 else Pretty.block ((prt_attn attn @ |
552 else Pretty.block ((prt_attn attn @ |
505 [Pretty.str ":", Pretty.brk 1] @ prt_core ts eqns)); |
553 [Pretty.str ":", Pretty.brk 1] @ prt_core ts eqns)); |
1568 val vinst = Symtab.make (parms ~~ vts); |
1617 val vinst = Symtab.make (parms ~~ vts); |
1569 fun vinst_names ps = map (the o Symtab.lookup vinst) ps; |
1618 fun vinst_names ps = map (the o Symtab.lookup vinst) ps; |
1570 val inst = Symtab.make (parms ~~ ts); |
1619 val inst = Symtab.make (parms ~~ ts); |
1571 val inst_ids = map (apfst (apsnd vinst_names)) ids; |
1620 val inst_ids = map (apfst (apsnd vinst_names)) ids; |
1572 val assumed_ids' = map_filter (fn (id, (_, Assumed _)) => SOME id | _ => NONE) inst_ids; |
1621 val assumed_ids' = map_filter (fn (id, (_, Assumed _)) => SOME id | _ => NONE) inst_ids; |
1573 val wits = maps (#2 o the o get_global_registration thy) assumed_ids'; |
1622 val wits = maps (#2 o the o get_global_registration thy import) assumed_ids'; |
1574 |
1623 |
1575 val ids' = map fst inst_ids; |
1624 val ids' = map fst inst_ids; |
1576 val eqns = |
1625 val eqns = |
1577 fold_map (join_eqns (get_global_registration thy) I (ProofContext.init thy)) |
1626 fold_map (join_eqns (get_global_registration thy import) I (ProofContext.init thy)) |
1578 ids' Termtab.empty |> snd |> Termtab.dest |> map snd; |
1627 ids' Termtab.empty |> snd |> Termtab.dest |> map snd; |
1579 |
1628 in ((tinst, inst), wits, eqns) end; |
1580 val tinst' = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of vts) Vartab.empty |
1629 |
1581 |> Vartab.dest |> map (fn ((x, 0), (_, T)) => (x, T)) |> Symtab.make; |
1630 |
1582 in ((tinst', vinst), (tinst, inst), wits, eqns) end; |
1631 (* standardise export morphism *) |
|
1632 |
|
1633 (* clone from Element.generalize_facts *) |
|
1634 fun standardize thy export facts = |
|
1635 let |
|
1636 val exp_fact = Drule.zero_var_indexes_list o map Thm.strip_shyps o Morphism.fact export; |
|
1637 val exp_term = TermSubst.zero_var_indexes o Morphism.term export; |
|
1638 (* FIXME sync with exp_fact *) |
|
1639 val exp_typ = Logic.type_map exp_term; |
|
1640 val morphism = |
|
1641 Morphism.morphism {name = I, var = I, typ = exp_typ, term = exp_term, fact = exp_fact}; |
|
1642 in Element.facts_map (Element.morph_ctxt morphism) facts end; |
|
1643 |
|
1644 |
|
1645 (* suppress application of name morphism: workaroud for class package *) (* FIXME *) |
|
1646 |
|
1647 fun morph_ctxt' phi = Element.map_ctxt |
|
1648 {name = I, |
|
1649 var = Morphism.var phi, |
|
1650 typ = Morphism.typ phi, |
|
1651 term = Morphism.term phi, |
|
1652 fact = Morphism.fact phi, |
|
1653 attrib = Args.morph_values phi}; |
|
1654 |
|
1655 |
|
1656 (* compute morphism and apply to args *) |
|
1657 |
|
1658 fun interpret_args thy prfx insts prems eqns atts2 exp attrib args = |
|
1659 let |
|
1660 val inst = Morphism.name_morphism (NameSpace.qualified prfx) $> |
|
1661 Element.inst_morphism thy insts $> Element.satisfy_morphism prems $> |
|
1662 Morphism.term_morphism (MetaSimplifier.rewrite_term thy eqns []) $> |
|
1663 Morphism.thm_morphism (MetaSimplifier.rewrite_rule eqns) |
|
1664 in |
|
1665 args |> Element.facts_map (morph_ctxt' inst) |> |
|
1666 map (fn (attn, bs) => (attn, |
|
1667 bs |> map (fn (ths, atts) => (ths, (atts @ atts2))))) |> |
|
1668 standardize thy exp |> Attrib.map_facts attrib |
|
1669 end; |
1583 |
1670 |
1584 |
1671 |
1585 (* store instantiations of args for all registered interpretations |
1672 (* store instantiations of args for all registered interpretations |
1586 of the theory *) |
1673 of the theory *) |
1587 |
1674 |
1590 val parms = the_locale thy target |> #params |> map fst; |
1677 val parms = the_locale thy target |> #params |> map fst; |
1591 val ids = flatten (ProofContext.init thy, intern_expr thy) |
1678 val ids = flatten (ProofContext.init thy, intern_expr thy) |
1592 (([], Symtab.empty), Expr (Locale target)) |> fst |> fst; |
1679 (([], Symtab.empty), Expr (Locale target)) |> fst |> fst; |
1593 |
1680 |
1594 val regs = get_global_registrations thy target; |
1681 val regs = get_global_registrations thy target; |
1595 |
|
1596 (* add args to thy for all registrations *) |
1682 (* add args to thy for all registrations *) |
1597 |
1683 |
1598 fun activate (vts, (((fully_qualified, prfx), atts2), _, _)) thy = |
1684 fun activate (vts, (((fully_qualified, prfx), atts2), (exp, imp), _, _)) thy = |
1599 let |
1685 let |
1600 val (vinsts, insts, prems, eqns) = collect_global_witnesses thy parms ids vts; |
1686 val (insts, prems, eqns) = collect_global_witnesses thy imp parms ids vts; |
1601 val attrib = Attrib.attribute_i thy; |
1687 val attrib = Attrib.attribute_i thy; |
1602 val inst_atts = Args.morph_values |
1688 val args' = interpret_args thy prfx insts prems eqns atts2 exp attrib args; |
1603 (Morphism.name_morphism (NameSpace.qualified prfx) $> |
|
1604 Element.inst_morphism' thy vinsts insts $> |
|
1605 Element.satisfy_morphism prems $> |
|
1606 Morphism.term_morphism (MetaSimplifier.rewrite_term thy eqns []) $> |
|
1607 Morphism.thm_morphism (MetaSimplifier.rewrite_rule eqns #> Drule.standard)); |
|
1608 val inst_thm = |
|
1609 Element.inst_thm thy insts #> Element.satisfy_thm prems #> |
|
1610 MetaSimplifier.rewrite_rule eqns #> |
|
1611 Drule.standard; |
|
1612 val args' = args |> map (fn ((name, atts), bs) => |
|
1613 ((name, map (attrib o inst_atts) atts), |
|
1614 bs |> map (fn (ths, more_atts) => |
|
1615 (map inst_thm ths, map attrib (map inst_atts more_atts @ atts2))))); |
|
1616 in global_note_prefix_i kind (fully_qualified, prfx) args' thy |> snd end; |
1689 in global_note_prefix_i kind (fully_qualified, prfx) args' thy |> snd end; |
1617 in fold activate regs thy end; |
1690 in fold activate regs thy end; |
1618 |
1691 |
1619 |
1692 |
1620 (* locale results *) |
1693 (* locale results *) |
1983 |
2055 |
1984 structure Idtab = |
2056 structure Idtab = |
1985 TableFun(type key = string * term list |
2057 TableFun(type key = string * term list |
1986 val ord = prod_ord string_ord (list_ord Term.fast_term_ord)); |
2058 val ord = prod_ord string_ord (list_ord Term.fast_term_ord)); |
1987 |
2059 |
1988 fun gen_activate_facts_elemss mk_ctxt get_reg note note_interp attrib std put_reg add_wit add_eqn |
2060 fun gen_activate_facts_elemss mk_ctxt get_reg note note_interp attrib put_reg add_wit add_eqn |
1989 attn all_elemss new_elemss propss eq_attns thmss thy_ctxt = |
2061 attn all_elemss new_elemss propss eq_attns (exp, imp) thmss thy_ctxt = |
1990 let |
2062 let |
1991 val ctxt = mk_ctxt thy_ctxt; |
2063 val ctxt = mk_ctxt thy_ctxt; |
1992 val (propss, eq_props) = chop (length new_elemss) propss; |
2064 val (propss, eq_props) = chop (length new_elemss) propss; |
1993 val (thmss, eq_thms) = chop (length new_elemss) thmss; |
2065 val (thmss, eq_thms) = chop (length new_elemss) thmss; |
1994 |
2066 |
1995 fun activate_elem eqns disch ((fully_qualified, prfx), atts) (Notes (kind, facts)) thy_ctxt = |
2067 fun activate_elem prems eqns exp ((fully_qualified, prfx), atts) (Notes (kind, facts)) thy_ctxt = |
1996 let |
2068 let |
1997 val ctxt = mk_ctxt thy_ctxt; |
2069 val ctxt = mk_ctxt thy_ctxt; |
1998 val fact_morphism = |
2070 val facts' = interpret_args (ProofContext.theory_of ctxt) prfx |
1999 Morphism.name_morphism (NameSpace.qualified prfx) |
2071 (Symtab.empty, Symtab.empty) prems eqns atts |
2000 $> Morphism.term_morphism (MetaSimplifier.rewrite_term |
2072 exp (attrib thy_ctxt) facts; |
2001 (ProofContext.theory_of ctxt) eqns []) |
|
2002 $> Morphism.thm_morphism (disch #> MetaSimplifier.rewrite_rule eqns); |
|
2003 val facts' = facts |
|
2004 (* discharge hyps in attributes *) |
|
2005 |> Attrib.map_facts |
|
2006 (attrib thy_ctxt o Args.morph_values fact_morphism) |
|
2007 (* append interpretation attributes *) |
|
2008 |> map (apfst (apsnd (fn a => a @ map (attrib thy_ctxt) atts))) |
|
2009 (* discharge hyps *) |
|
2010 |> map (apsnd (map (apfst (map disch)))) |
|
2011 (* unfold eqns *) |
|
2012 |> map (apsnd (map (apfst (map (MetaSimplifier.rewrite_rule eqns))))) |
|
2013 in snd (note_interp kind (fully_qualified, prfx) facts' thy_ctxt) end |
2073 in snd (note_interp kind (fully_qualified, prfx) facts' thy_ctxt) end |
2014 | activate_elem _ _ _ _ thy_ctxt = thy_ctxt; |
2074 | activate_elem _ _ _ _ _ thy_ctxt = thy_ctxt; |
2015 |
2075 |
2016 fun activate_elems eqns disch ((id, _), elems) thy_ctxt = |
2076 fun activate_elems prems eqns exp ((id, _), elems) thy_ctxt = |
2017 let |
2077 let |
2018 val (prfx_atts, _, _) = case get_reg thy_ctxt id |
2078 val (prfx_atts, _, _) = case get_reg thy_ctxt imp id |
2019 of SOME x => x |
2079 of SOME x => x |
2020 | NONE => sys_error ("Unknown registration of " ^ quote (fst id) |
2080 | NONE => sys_error ("Unknown registration of " ^ quote (fst id) |
2021 ^ " while activating facts."); |
2081 ^ " while activating facts."); |
2022 in fold (activate_elem (the (Idtab.lookup eqns id)) disch prfx_atts) elems thy_ctxt end; |
2082 in fold (activate_elem prems (the (Idtab.lookup eqns id)) exp prfx_atts) elems thy_ctxt end; |
2023 |
2083 |
2024 val thy_ctxt' = thy_ctxt |
2084 val thy_ctxt' = thy_ctxt |
2025 (* add registrations *) |
2085 (* add registrations *) |
2026 |> fold (fn ((id, _), _) => put_reg id attn) new_elemss |
2086 |> fold (fn ((id, _), _) => put_reg id attn (exp, imp)) new_elemss |
2027 (* add witnesses of Assumed elements (only those generate proof obligations) *) |
2087 (* add witnesses of Assumed elements (only those generate proof obligations) *) |
2028 |> fold (fn (id, thms) => fold (add_wit id) thms) (map fst propss ~~ thmss) |
2088 |> fold (fn (id, thms) => fold (add_wit id) thms) (map fst propss ~~ thmss) |
2029 (* add equations *) |
2089 (* add equations *) |
2030 |> fold (fn (id, thms) => fold (add_eqn id) thms) (map fst eq_props ~~ |
2090 |> fold (fn (id, thms) => fold (add_eqn id) thms) (map fst eq_props ~~ |
2031 (map o map) (Drule.abs_def o LocalDefs.meta_rewrite_rule ctxt o |
2091 (map o map) (Drule.abs_def o LocalDefs.meta_rewrite_rule ctxt o |
2032 Element.conclude_witness) eq_thms); |
2092 Element.conclude_witness) eq_thms); |
2033 |
2093 |
2034 val prems = flat (map_filter |
2094 val prems = flat (map_filter |
2035 (fn ((id, Assumed _), _) => Option.map #2 (get_reg thy_ctxt' id) |
2095 (fn ((id, Assumed _), _) => Option.map #2 (get_reg thy_ctxt' imp id) |
2036 | ((_, Derived _), _) => NONE) all_elemss); |
2096 | ((_, Derived _), _) => NONE) all_elemss); |
2037 val satisfy = Element.satisfy_morphism prems; |
|
2038 val thy_ctxt'' = thy_ctxt' |
2097 val thy_ctxt'' = thy_ctxt' |
2039 (* add witnesses of Derived elements *) |
2098 (* add witnesses of Derived elements *) |
2040 |> fold (fn (id, thms) => fold (add_wit id o Element.morph_witness satisfy) thms) |
2099 |> fold (fn (id, thms) => fold (add_wit id o Element.morph_witness (Element.satisfy_morphism prems)) thms) |
2041 (map_filter (fn ((_, Assumed _), _) => NONE |
2100 (map_filter (fn ((_, Assumed _), _) => NONE |
2042 | ((id, Derived thms), _) => SOME (id, thms)) new_elemss) |
2101 | ((id, Derived thms), _) => SOME (id, thms)) new_elemss) |
2043 |
2102 |
2044 (* Accumulate equations *) |
2103 (* Accumulate equations *) |
2045 val all_eqns = |
2104 val all_eqns = |
2046 fold_map (join_eqns (get_reg thy_ctxt'') (fst o fst) ctxt) all_elemss Termtab.empty |
2105 fold_map (join_eqns (get_reg thy_ctxt'' imp) (fst o fst) ctxt) all_elemss Termtab.empty |
2047 |> fst |
2106 |> fst |
2048 |> map (apsnd (map snd o Termtab.dest)) |
2107 |> map (apsnd (map snd o Termtab.dest)) |
2049 |> (fn xs => fold Idtab.update xs Idtab.empty) |
2108 |> (fn xs => fold Idtab.update xs Idtab.empty) |
2050 (* Idtab.make wouldn't work here: can have conflicting duplicates, |
2109 (* Idtab.make wouldn't work here: can have conflicting duplicates, |
2051 because instantiation may equate ids and equations are accumulated! *) |
2110 because instantiation may equate ids and equations are accumulated! *) |
2052 |
|
2053 val disch' = std o Morphism.thm satisfy; (* FIXME *) |
|
2054 in |
2111 in |
2055 thy_ctxt'' |
2112 thy_ctxt'' |
2056 (* add equations *) |
2113 (* add equations *) |
2057 |> fold (fn (attns, thms) => |
2114 |> fold (fn (attns, thms) => |
2058 fold (fn (attn, thm) => note "lemma" |
2115 fold (fn (attn, thm) => note "lemma" |
2059 [(apsnd (map (attrib thy_ctxt'')) attn, |
2116 [(apsnd (map (attrib thy_ctxt'')) attn, |
2060 [([Element.conclude_witness thm], [])])] #> snd) |
2117 [([Element.conclude_witness thm], [])])] #> snd) |
2061 (attns ~~ thms)) (unflat eq_thms eq_attns ~~ eq_thms) |
2118 (attns ~~ thms)) (unflat eq_thms eq_attns ~~ eq_thms) |
2062 (* add facts *) |
2119 (* add facts *) |
2063 |> fold (activate_elems all_eqns disch') new_elemss |
2120 |> fold (activate_elems prems all_eqns exp) new_elemss |
2064 end; |
2121 end; |
2065 |
2122 |
2066 fun global_activate_facts_elemss x = gen_activate_facts_elemss |
2123 fun global_activate_facts_elemss x = gen_activate_facts_elemss |
2067 ProofContext.init |
2124 ProofContext.init |
2068 (fn thy => fn (name, ps) => |
2125 get_global_registration |
2069 get_global_registration thy (name, map Logic.varify ps)) |
|
2070 PureThy.note_thmss_i |
2126 PureThy.note_thmss_i |
2071 global_note_prefix_i |
2127 global_note_prefix_i |
2072 Attrib.attribute_i Drule.standard |
2128 Attrib.attribute_i |
2073 (fn (name, ps) => put_global_registration (name, map Logic.varify ps)) |
2129 put_global_registration add_global_witness add_global_equation |
2074 (fn (n, ps) => add_global_witness (n, map Logic.varify ps) o |
|
2075 Element.map_witness (fn (t, th) => (Logic.legacy_unvarify t, legacy_unvarify th)) |
|
2076 (* FIXME *)) |
|
2077 (fn (n, ps) => add_global_equation (n, map Logic.varify ps)) |
|
2078 x; |
2130 x; |
2079 |
2131 |
2080 fun local_activate_facts_elemss x = gen_activate_facts_elemss |
2132 fun local_activate_facts_elemss x = gen_activate_facts_elemss |
2081 I |
2133 I |
2082 get_local_registration |
2134 get_local_registration |
2083 ProofContext.note_thmss_i |
2135 ProofContext.note_thmss_i |
2084 local_note_prefix_i |
2136 local_note_prefix_i |
2085 (Attrib.attribute_i o ProofContext.theory_of) I |
2137 (Attrib.attribute_i o ProofContext.theory_of) |
2086 put_local_registration |
2138 put_local_registration |
2087 add_local_witness |
2139 add_local_witness |
2088 add_local_equation |
2140 add_local_equation |
2089 x; |
2141 x; |
2090 |
2142 |
2110 |
2162 |
2111 (* parse insts / eqns *) |
2163 (* parse insts / eqns *) |
2112 val given_insts' = map (parse_term ctxt) given_insts; |
2164 val given_insts' = map (parse_term ctxt) given_insts; |
2113 val eqns' = map (parse_prop ctxt) eqns; |
2165 val eqns' = map (parse_prop ctxt) eqns; |
2114 |
2166 |
2115 (* type inference etc. *) |
2167 (* type inference and contexts *) |
2116 val res = Syntax.check_terms ctxt |
2168 val arg = type_parms @ map2 TypeInfer.constrain given_parm_types given_insts' @ eqns'; |
2117 (type_parms @ |
2169 val res = Syntax.check_terms ctxt arg; |
2118 map2 TypeInfer.constrain given_parm_types given_insts' @ |
|
2119 eqns'); |
|
2120 val ctxt' = ctxt |> fold Variable.auto_fixes res; |
2170 val ctxt' = ctxt |> fold Variable.auto_fixes res; |
2121 |
2171 |
2122 (* results *) |
2172 (* instantiation *) |
2123 val (type_parms'', res') = chop (length type_parms) res; |
2173 val (type_parms'', res') = chop (length type_parms) res; |
2124 val (given_insts'', eqns'') = chop (length given_insts) res'; |
2174 val (given_insts'', eqns'') = chop (length given_insts) res'; |
2125 val instT = Symtab.make (type_parm_names ~~ map Logic.dest_type type_parms''); |
2175 val instT = Symtab.make (type_parm_names ~~ map Logic.dest_type type_parms''); |
2126 val inst = Symtab.make (given_parm_names ~~ given_insts''); |
2176 val inst = Symtab.make (given_parm_names ~~ given_insts''); |
2127 val standard = Variable.export_morphism ctxt' ctxt; |
2177 |
2128 in ((instT, inst), eqns'') end; |
2178 (* export from eigencontext *) |
|
2179 val export = Variable.export_morphism ctxt' ctxt; |
|
2180 |
|
2181 (* import, its inverse *) |
|
2182 val domT = fold Term.add_tfrees res [] |> map TFree; |
|
2183 val importT = domT |> map (fn x => (Morphism.typ export x, x)) |
|
2184 |> map_filter (fn (TFree _, _) => NONE (* fixed point of export *) |
|
2185 | (TVar y, x) => SOME (fst y, x) |
|
2186 | _ => error "internal: illegal export in interpretation") |
|
2187 |> Vartab.make; |
|
2188 val dom = fold Term.add_frees res [] |> map Free; |
|
2189 val import = dom |> map (fn x => (Morphism.term export x, x)) |
|
2190 |> map_filter (fn (Free _, _) => NONE (* fixed point of export *) |
|
2191 | (Var y, x) => SOME (fst y, x) |
|
2192 | _ => error "internal: illegal export in interpretation") |
|
2193 |> Vartab.make; |
|
2194 in (((instT, inst), eqns''), (export, ((importT, domT), (import, dom)))) end; |
2129 |
2195 |
2130 val read_instantiations = prep_instantiations Syntax.parse_term Syntax.parse_prop; |
2196 val read_instantiations = prep_instantiations Syntax.parse_term Syntax.parse_prop; |
2131 val check_instantiations = prep_instantiations (K I) (K I); |
2197 val check_instantiations = prep_instantiations (K I) (K I); |
2132 |
2198 |
2133 fun gen_prep_registration mk_ctxt test_reg activate |
2199 fun gen_prep_registration mk_ctxt test_reg activate |
2185 ((n, map (fn p => Free (p, (the o AList.lookup (op =) parms) p)) ps), mode)) |
2251 ((n, map (fn p => Free (p, (the o AList.lookup (op =) parms) p)) ps), mode)) |
2186 ids; |
2252 ids; |
2187 val (_, all_elemss') = chop (length raw_params_elemss) all_elemss |
2253 val (_, all_elemss') = chop (length raw_params_elemss) all_elemss |
2188 (* instantiate ids and elements *) |
2254 (* instantiate ids and elements *) |
2189 val inst_elemss = (ids' ~~ all_elemss') |> map (fn (((n, ps), _), ((_, mode), elems)) => |
2255 val inst_elemss = (ids' ~~ all_elemss') |> map (fn (((n, ps), _), ((_, mode), elems)) => |
2190 ((n, map (Morphism.term inst_morphism) ps), |
2256 ((n, map (Morphism.term (inst_morphism $> fst morphs)) ps), |
2191 map (fn Int e => Element.morph_ctxt inst_morphism e) elems) |
2257 map (fn Int e => Element.morph_ctxt inst_morphism e) elems) |
2192 |> apfst (fn id => (id, map_mode (map (Element.morph_witness inst_morphism)) mode))); |
2258 |> apfst (fn id => (id, map_mode (map (Element.morph_witness inst_morphism)) mode))); |
2193 |
2259 |
2194 (* remove fragments already registered with theory or context *) |
2260 (* remove fragments already registered with theory or context *) |
2195 val new_inst_elemss = filter_out (fn ((id, _), _) => |
2261 val new_inst_elemss = filter_out (fn ((id, _), _) => |
2196 test_reg thy_ctxt id) inst_elemss; |
2262 test_reg thy_ctxt id) inst_elemss; |
2197 (* val new_ids = map #1 new_inst_elemss; *) |
|
2198 |
2263 |
2199 (* equations *) |
2264 (* equations *) |
2200 val eqn_elems = if null eqns then [] |
2265 val eqn_elems = if null eqns then [] |
2201 else [(Library.last_elem inst_elemss |> fst |> fst, eqns)]; |
2266 else [(Library.last_elem inst_elemss |> fst |> fst, eqns)]; |
2202 |
2267 |
2203 val propss = map extract_asms_elems new_inst_elemss @ eqn_elems; |
2268 val propss = map extract_asms_elems new_inst_elemss @ eqn_elems; |
2204 |
2269 |
2205 in (propss, activate attn inst_elemss new_inst_elemss propss eq_attns) end; |
2270 in (propss, activate attn inst_elemss new_inst_elemss propss eq_attns morphs) end; |
2206 |
2271 |
2207 fun gen_prep_global_registration mk_ctxt = gen_prep_registration ProofContext.init |
2272 fun gen_prep_global_registration mk_ctxt = gen_prep_registration ProofContext.init |
2208 (fn thy => fn (name, ps) => test_global_registration thy (name, map Logic.varify ps)) |
2273 test_global_registration |
2209 global_activate_facts_elemss mk_ctxt; |
2274 global_activate_facts_elemss mk_ctxt; |
2210 |
2275 |
2211 fun gen_prep_local_registration mk_ctxt = gen_prep_registration I |
2276 fun gen_prep_local_registration mk_ctxt = gen_prep_registration I |
2212 test_local_registration |
2277 test_local_registration |
2213 local_activate_facts_elemss mk_ctxt; |
2278 local_activate_facts_elemss mk_ctxt; |
2259 fun activate_id (((id, Assumed _), _), thms) thy = |
2324 fun activate_id (((id, Assumed _), _), thms) thy = |
2260 thy |> put_registration_in_locale target id |
2325 thy |> put_registration_in_locale target id |
2261 |> fold (add_witness_in_locale target id) thms |
2326 |> fold (add_witness_in_locale target id) thms |
2262 | activate_id _ thy = thy; |
2327 | activate_id _ thy = thy; |
2263 |
2328 |
2264 fun activate_reg (vts, (((fully_qualified, prfx), atts2), _, _)) thy = |
2329 fun activate_reg (vts, (((fully_qualified, prfx), atts2), (exp, imp), _, _)) thy = |
2265 let |
2330 let |
2266 val (vinsts, insts, wits, _) = collect_global_witnesses thy fixed target_ids vts; |
2331 val (insts, wits, _) = collect_global_witnesses thy imp fixed target_ids vts; |
2267 fun inst_parms ps = map |
2332 fun inst_parms ps = map |
2268 (the o AList.lookup (op =) (map #1 fixed ~~ vts)) ps; |
2333 (the o AList.lookup (op =) (map #1 fixed ~~ vts)) ps; |
2269 val disch = Element.satisfy_thm wits; |
2334 val disch = Element.satisfy_thm wits; |
2270 val new_elemss = filter (fn (((name, ps), _), _) => |
2335 val new_elemss = filter (fn (((name, ps), _), _) => |
2271 not (test_global_registration thy (name, inst_parms ps))) (ids_elemss); |
2336 not (test_global_registration thy (name, inst_parms ps))) (ids_elemss); |
2274 val ps' = inst_parms ps; |
2339 val ps' = inst_parms ps; |
2275 in |
2340 in |
2276 if test_global_registration thy (name, ps') |
2341 if test_global_registration thy (name, ps') |
2277 then thy |
2342 then thy |
2278 else thy |
2343 else thy |
2279 |> put_global_registration (name, ps') ((fully_qualified, prfx), atts2) |
2344 |> put_global_registration (name, ps') ((fully_qualified, prfx), atts2) (exp, imp) |
2280 |> fold (fn witn => fn thy => add_global_witness (name, ps') |
2345 |> fold (fn witn => fn thy => add_global_witness (name, ps') |
2281 (Element.morph_witness (Element.inst_morphism' thy vinsts insts) witn) thy) thms |
2346 (Element.morph_witness (Element.inst_morphism thy insts) witn) thy) thms |
2282 end; |
2347 end; |
2283 |
2348 |
2284 fun activate_derived_id ((_, Assumed _), _) thy = thy |
2349 fun activate_derived_id ((_, Assumed _), _) thy = thy |
2285 | activate_derived_id (((name, ps), Derived ths), _) thy = let |
2350 | activate_derived_id (((name, ps), Derived ths), _) thy = let |
2286 val ps' = inst_parms ps; |
2351 val ps' = inst_parms ps; |
2287 in |
2352 in |
2288 if test_global_registration thy (name, ps') |
2353 if test_global_registration thy (name, ps') |
2289 then thy |
2354 then thy |
2290 else thy |
2355 else thy |
2291 |> put_global_registration (name, ps') ((fully_qualified, prfx), atts2) |
2356 |> put_global_registration (name, ps') ((fully_qualified, prfx), atts2) (exp, imp) |
2292 |> fold (fn witn => fn thy => add_global_witness (name, ps') |
2357 |> fold (fn witn => fn thy => add_global_witness (name, ps') |
2293 (witn |> Element.map_witness (fn (t, th) => (* FIXME *) |
2358 (witn |> Element.map_witness (fn (t, th) => (* FIXME *) |
2294 (Element.inst_term insts t, |
2359 (Element.inst_term insts t, |
2295 disch (Element.inst_thm thy insts (satisfy th))))) thy) ths |
2360 disch (Element.inst_thm thy insts (satisfy th))))) thy) ths |
2296 end; |
2361 end; |