30 (implicit locale expressions generated by multiple registrations) |
30 (implicit locale expressions generated by multiple registrations) |
31 *) |
31 *) |
32 |
32 |
33 signature LOCALE = |
33 signature LOCALE = |
34 sig |
34 sig |
35 type context (*= Proof.context*) |
|
36 datatype ('typ, 'term, 'fact) elem = |
|
37 Fixes of (string * 'typ option * mixfix option) list | |
|
38 Constrains of (string * 'typ) list | |
|
39 Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list | |
|
40 Defines of ((string * Attrib.src list) * ('term * 'term list)) list | |
|
41 Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list |
|
42 type element (*= (string, string, thmref) elem*) |
|
43 type element_i (*= (typ, term, thm list) elem*) |
|
44 datatype expr = |
35 datatype expr = |
45 Locale of string | |
36 Locale of string | |
46 Rename of expr * (string * mixfix option) option list | |
37 Rename of expr * (string * mixfix option) option list | |
47 Merge of expr list |
38 Merge of expr list |
48 val empty: expr |
39 val empty: expr |
49 datatype 'a elem_expr = Elem of 'a | Expr of expr |
40 datatype 'a element = Elem of 'a | Expr of expr |
50 |
41 |
51 (* Abstract interface to locales *) |
42 (* Abstract interface to locales *) |
52 type locale |
43 type locale |
53 val intern: theory -> xstring -> string |
44 val intern: theory -> xstring -> string |
54 val extern: theory -> string -> xstring |
45 val extern: theory -> string -> xstring |
55 val the_locale: theory -> string -> locale |
46 val the_locale: theory -> string -> locale |
56 val intern_attrib_elem: theory -> |
|
57 ('typ, 'term, 'fact) elem -> ('typ, 'term, 'fact) elem |
|
58 val intern_attrib_elem_expr: theory -> |
|
59 ('typ, 'term, 'fact) elem elem_expr -> ('typ, 'term, 'fact) elem elem_expr |
|
60 |
47 |
61 (* Processing of locale statements *) |
48 (* Processing of locale statements *) |
62 val read_context_statement: xstring option -> element elem_expr list -> |
49 val read_context_statement: xstring option -> Element.context element list -> |
63 (string * (string list * string list)) list list -> context -> |
50 (string * (string list * string list)) list list -> ProofContext.context -> |
64 string option * (cterm list * cterm list) * context * context * |
51 string option * (cterm list * cterm list) * ProofContext.context * ProofContext.context * |
65 (term * (term list * term list)) list list |
52 (term * (term list * term list)) list list |
66 val cert_context_statement: string option -> element_i elem_expr list -> |
53 val cert_context_statement: string option -> Element.context_i element list -> |
67 (term * (term list * term list)) list list -> context -> |
54 (term * (term list * term list)) list list -> ProofContext.context -> |
68 string option * (cterm list * cterm list) * context * context * |
55 string option * (cterm list * cterm list) * ProofContext.context * ProofContext.context * |
69 (term * (term list * term list)) list list |
56 (term * (term list * term list)) list list |
70 |
57 |
71 (* Diagnostic functions *) |
58 (* Diagnostic functions *) |
72 val print_locales: theory -> unit |
59 val print_locales: theory -> unit |
73 val print_locale: theory -> bool -> expr -> element list -> unit |
60 val print_locale: theory -> bool -> expr -> Element.context list -> unit |
74 val print_global_registrations: bool -> string -> theory -> unit |
61 val print_global_registrations: bool -> string -> theory -> unit |
75 val print_local_registrations': bool -> string -> context -> unit |
62 val print_local_registrations': bool -> string -> ProofContext.context -> unit |
76 val print_local_registrations: bool -> string -> context -> unit |
63 val print_local_registrations: bool -> string -> ProofContext.context -> unit |
|
64 |
|
65 val add_locale_context: bool -> bstring -> expr -> Element.context list -> theory |
|
66 -> (Element.context_i list * ProofContext.context) * theory |
|
67 val add_locale_context_i: bool -> bstring -> expr -> Element.context_i list -> theory |
|
68 -> (Element.context_i list * ProofContext.context) * theory |
|
69 val add_locale: bool -> bstring -> expr -> Element.context list -> theory -> theory |
|
70 val add_locale_i: bool -> bstring -> expr -> Element.context_i list -> theory -> theory |
77 |
71 |
78 (* Storing results *) |
72 (* Storing results *) |
79 val add_locale_context: bool -> bstring -> expr -> element list -> theory |
|
80 -> (element_i list * ProofContext.context) * theory |
|
81 val add_locale_context_i: bool -> bstring -> expr -> element_i list -> theory |
|
82 -> (element_i list * ProofContext.context) * theory |
|
83 val add_locale: bool -> bstring -> expr -> element list -> theory -> theory |
|
84 val add_locale_i: bool -> bstring -> expr -> element_i list -> theory -> theory |
|
85 val smart_note_thmss: string -> string option -> |
73 val smart_note_thmss: string -> string option -> |
86 ((bstring * theory attribute list) * (thm list * theory attribute list) list) list -> |
74 ((bstring * theory attribute list) * (thm list * theory attribute list) list) list -> |
87 theory -> theory * (bstring * thm list) list |
75 theory -> theory * (bstring * thm list) list |
88 val note_thmss: string -> xstring -> |
76 val note_thmss: string -> xstring -> |
89 ((bstring * Attrib.src list) * (thmref * Attrib.src list) list) list -> |
77 ((bstring * Attrib.src list) * (thmref * Attrib.src list) list) list -> |
90 theory -> (theory * ProofContext.context) * (bstring * thm list) list |
78 theory -> (theory * ProofContext.context) * (bstring * thm list) list |
91 val note_thmss_i: string -> string -> |
79 val note_thmss_i: string -> string -> |
92 ((bstring * Attrib.src list) * (thm list * Attrib.src list) list) list -> |
80 ((bstring * Attrib.src list) * (thm list * Attrib.src list) list) list -> |
93 theory -> (theory * ProofContext.context) * (bstring * thm list) list |
81 theory -> (theory * ProofContext.context) * (bstring * thm list) list |
|
82 |
94 val theorem: string -> Method.text option -> (thm list list -> theory -> theory) -> |
83 val theorem: string -> Method.text option -> (thm list list -> theory -> theory) -> |
95 string * Attrib.src list -> element elem_expr list -> |
84 string * Attrib.src list -> Element.context element list -> |
96 ((string * Attrib.src list) * (string * (string list * string list)) list) list -> |
85 ((string * Attrib.src list) * (string * (string list * string list)) list) list -> |
97 theory -> Proof.state |
86 theory -> Proof.state |
98 val theorem_i: string -> Method.text option -> (thm list list -> theory -> theory) -> |
87 val theorem_i: string -> Method.text option -> (thm list list -> theory -> theory) -> |
99 string * theory attribute list -> element_i elem_expr list -> |
88 string * theory attribute list -> Element.context_i element list -> |
100 ((string * theory attribute list) * (term * (term list * term list)) list) list -> |
89 ((string * theory attribute list) * (term * (term list * term list)) list) list -> |
101 theory -> Proof.state |
90 theory -> Proof.state |
102 val theorem_in_locale: string -> Method.text option -> |
91 val theorem_in_locale: string -> Method.text option -> |
103 (thm list list -> thm list list -> theory -> theory) -> |
92 (thm list list -> thm list list -> theory -> theory) -> |
104 xstring -> string * Attrib.src list -> element elem_expr list -> |
93 xstring -> string * Attrib.src list -> Element.context element list -> |
105 ((string * Attrib.src list) * (string * (string list * string list)) list) list -> |
94 ((string * Attrib.src list) * (string * (string list * string list)) list) list -> |
106 theory -> Proof.state |
95 theory -> Proof.state |
107 val theorem_in_locale_i: string -> Method.text option -> |
96 val theorem_in_locale_i: string -> Method.text option -> |
108 (thm list list -> thm list list -> theory -> theory) -> |
97 (thm list list -> thm list list -> theory -> theory) -> |
109 string -> string * Attrib.src list -> element_i elem_expr list -> |
98 string -> string * Attrib.src list -> Element.context_i element list -> |
110 ((string * Attrib.src list) * (term * (term list * term list)) list) list -> |
99 ((string * Attrib.src list) * (term * (term list * term list)) list) list -> |
111 theory -> Proof.state |
100 theory -> Proof.state |
112 val smart_theorem: string -> xstring option -> |
101 val smart_theorem: string -> xstring option -> |
113 string * Attrib.src list -> element elem_expr list -> |
102 string * Attrib.src list -> Element.context element list -> |
114 ((string * Attrib.src list) * (string * (string list * string list)) list) list -> |
103 ((string * Attrib.src list) * (string * (string list * string list)) list) list -> |
115 theory -> Proof.state |
104 theory -> Proof.state |
116 val interpretation: string * Attrib.src list -> expr -> string option list -> |
105 val interpretation: string * Attrib.src list -> expr -> string option list -> |
117 theory -> Proof.state |
106 theory -> Proof.state |
118 val interpretation_in_locale: xstring * expr -> theory -> Proof.state |
107 val interpretation_in_locale: xstring * expr -> theory -> Proof.state |
124 struct |
113 struct |
125 |
114 |
126 |
115 |
127 (** locale elements and expressions **) |
116 (** locale elements and expressions **) |
128 |
117 |
129 type context = ProofContext.context; |
118 datatype ctxt = datatype Element.ctxt; |
130 |
|
131 datatype ('typ, 'term, 'fact) elem = |
|
132 Fixes of (string * 'typ option * mixfix option) list | |
|
133 Constrains of (string * 'typ) list | |
|
134 Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list | |
|
135 Defines of ((string * Attrib.src list) * ('term * 'term list)) list | |
|
136 Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list; |
|
137 |
|
138 type element = (string, string, thmref) elem; |
|
139 type element_i = (typ, term, thm list) elem; |
|
140 |
119 |
141 datatype expr = |
120 datatype expr = |
142 Locale of string | |
121 Locale of string | |
143 Rename of expr * (string * mixfix option) option list | |
122 Rename of expr * (string * mixfix option) option list | |
144 Merge of expr list; |
123 Merge of expr list; |
145 |
124 |
146 val empty = Merge []; |
125 val empty = Merge []; |
147 |
126 |
148 datatype 'a elem_expr = |
127 datatype 'a element = |
149 Elem of 'a | Expr of expr; |
128 Elem of 'a | Expr of expr; |
|
129 |
|
130 fun map_elem f (Elem e) = Elem (f e) |
|
131 | map_elem _ (Expr e) = Expr e; |
150 |
132 |
151 type witness = term * thm; (*hypothesis as fact*) |
133 type witness = term * thm; (*hypothesis as fact*) |
152 type locale = |
134 type locale = |
153 {predicate: cterm list * witness list, |
135 {predicate: cterm list * witness list, |
154 (* CB: For locales with "(open)" this entry is ([], []). |
136 (* CB: For locales with "(open)" this entry is ([], []). |
173 (* CB: an internal (Int) locale element was either imported or included, |
155 (* CB: an internal (Int) locale element was either imported or included, |
174 an external (Ext) element appears directly in the locale text. *) |
156 an external (Ext) element appears directly in the locale text. *) |
175 |
157 |
176 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b; |
158 datatype ('a, 'b) int_ext = Int of 'a | Ext of 'b; |
177 |
159 |
178 |
|
179 |
|
180 (** term and type instantiation, using symbol tables **) |
|
181 (** functions for term instantiation beta-reduce the result |
|
182 unless the instantiation table is empty (inst_tab_term) |
|
183 or the instantiation has no effect (inst_tab_thm) **) |
|
184 |
|
185 (* instantiate TFrees *) |
|
186 |
|
187 fun tinst_tab_type tinst T = if Symtab.is_empty tinst |
|
188 then T |
|
189 else Term.map_type_tfree |
|
190 (fn (v as (x, _)) => getOpt (Symtab.lookup tinst x, (TFree v))) T; |
|
191 |
|
192 fun tinst_tab_term tinst t = if Symtab.is_empty tinst |
|
193 then t |
|
194 else Term.map_term_types (tinst_tab_type tinst) t; |
|
195 |
|
196 fun tinst_tab_thm thy tinst thm = if Symtab.is_empty tinst |
|
197 then thm |
|
198 else let |
|
199 val cert = Thm.cterm_of thy; |
|
200 val certT = Thm.ctyp_of thy; |
|
201 val {hyps, prop, ...} = Thm.rep_thm thm; |
|
202 val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps); |
|
203 val tinst' = Symtab.dest tinst |> |
|
204 List.filter (fn (a, _) => a mem_string tfrees); |
|
205 in |
|
206 if null tinst' then thm |
|
207 else thm |> Drule.implies_intr_list (map cert hyps) |
|
208 |> Drule.tvars_intr_list (map #1 tinst') |
|
209 |> (fn (th, al) => th |> Thm.instantiate |
|
210 ((map (fn (a, T) => (certT (TVar ((the o AList.lookup (op =) al) a)), certT T)) tinst'), |
|
211 [])) |
|
212 |> (fn th => Drule.implies_elim_list th |
|
213 (map (Thm.assume o cert o tinst_tab_term tinst) hyps)) |
|
214 end; |
|
215 |
|
216 (* instantiate TFrees and Frees *) |
|
217 |
|
218 fun inst_tab_term (inst, tinst) = if Symtab.is_empty inst |
|
219 then tinst_tab_term tinst |
|
220 else (* instantiate terms and types simultaneously *) |
|
221 let |
|
222 fun instf (Const (x, T)) = Const (x, tinst_tab_type tinst T) |
|
223 | instf (Free (x, T)) = (case Symtab.lookup inst x of |
|
224 NONE => Free (x, tinst_tab_type tinst T) |
|
225 | SOME t => t) |
|
226 | instf (Var (xi, T)) = Var (xi, tinst_tab_type tinst T) |
|
227 | instf (b as Bound _) = b |
|
228 | instf (Abs (x, T, t)) = Abs (x, tinst_tab_type tinst T, instf t) |
|
229 | instf (s $ t) = instf s $ instf t |
|
230 in Envir.beta_norm o instf end; |
|
231 |
|
232 fun inst_tab_thm thy (inst, tinst) thm = if Symtab.is_empty inst |
|
233 then tinst_tab_thm thy tinst thm |
|
234 else let |
|
235 val cert = Thm.cterm_of thy; |
|
236 val certT = Thm.ctyp_of thy; |
|
237 val {hyps, prop, ...} = Thm.rep_thm thm; |
|
238 (* type instantiations *) |
|
239 val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps); |
|
240 val tinst' = Symtab.dest tinst |> |
|
241 List.filter (fn (a, _) => a mem_string tfrees); |
|
242 (* term instantiations; |
|
243 note: lhss are type instantiated, because |
|
244 type insts will be done first*) |
|
245 val frees = foldr Term.add_term_frees [] (prop :: hyps); |
|
246 val inst' = Symtab.dest inst |> |
|
247 List.mapPartial (fn (a, t) => |
|
248 get_first (fn (Free (x, T)) => |
|
249 if a = x then SOME (Free (x, tinst_tab_type tinst T), t) |
|
250 else NONE) frees); |
|
251 in |
|
252 if null tinst' andalso null inst' then tinst_tab_thm thy tinst thm |
|
253 else thm |> Drule.implies_intr_list (map cert hyps) |
|
254 |> Drule.tvars_intr_list (map #1 tinst') |
|
255 |> (fn (th, al) => th |> Thm.instantiate |
|
256 ((map (fn (a, T) => (certT (TVar ((the o AList.lookup (op =) al) a)), certT T)) tinst'), |
|
257 [])) |
|
258 |> Drule.forall_intr_list (map (cert o #1) inst') |
|
259 |> Drule.forall_elim_list (map (cert o #2) inst') |
|
260 |> Drule.fconv_rule (Thm.beta_conversion true) |
|
261 |> (fn th => Drule.implies_elim_list th |
|
262 (map (Thm.assume o cert o inst_tab_term (inst, tinst)) hyps)) |
|
263 end; |
|
264 |
|
265 |
|
266 fun inst_tab_att thy (inst as (_, tinst)) = |
|
267 Args.map_values I (tinst_tab_type tinst) |
|
268 (inst_tab_term inst) (inst_tab_thm thy inst); |
|
269 |
|
270 fun inst_tab_atts thy inst = map (inst_tab_att thy inst); |
|
271 |
160 |
272 |
161 |
273 (** management of registrations in theories and proof contexts **) |
162 (** management of registrations in theories and proof contexts **) |
274 |
163 |
275 structure Registrations : |
164 structure Registrations : |
513 val {predicate, import, elems, params, regs} = the_locale thy name; |
403 val {predicate, import, elems, params, regs} = the_locale thy name; |
514 fun add (id', thms) = |
404 fun add (id', thms) = |
515 if id = id' then (id', thm :: thms) else (id', thms); |
405 if id = id' then (id', thm :: thms) else (id', thms); |
516 in |
406 in |
517 put_locale name {predicate = predicate, import = import, |
407 put_locale name {predicate = predicate, import = import, |
518 elems = elems, params = params, regs = map add regs} thy |
408 elems = elems, params = params, regs = map add regs} thy |
519 end; |
409 end; |
520 |
|
521 (* import hierarchy |
|
522 implementation could be more efficient, eg. by maintaining a database |
|
523 of dependencies *) |
|
524 |
|
525 fun imports thy (upper, lower) = |
|
526 let |
|
527 fun imps (Locale name) low = (name = low) orelse |
|
528 (case get_locale thy name of |
|
529 NONE => false |
|
530 | SOME {import, ...} => imps import low) |
|
531 | imps (Rename (expr, _)) low = imps expr low |
|
532 | imps (Merge es) low = exists (fn e => imps e low) es; |
|
533 in |
|
534 imps (Locale (intern thy upper)) (intern thy lower) |
|
535 end; |
|
536 |
410 |
537 |
411 |
538 (* printing of registrations *) |
412 (* printing of registrations *) |
539 |
413 |
540 fun gen_print_registrations get_regs mk_ctxt msg show_wits loc thy_ctxt = |
414 fun gen_print_registrations get_regs mk_ctxt msg show_wits loc thy_ctxt = |
600 if forall (equal "" o #1) ids then msg |
474 if forall (equal "" o #1) ids then msg |
601 else msg ^ "\n" ^ Pretty.string_of (Pretty.block |
475 else msg ^ "\n" ^ Pretty.string_of (Pretty.block |
602 (Pretty.str "The error(s) above occurred in locale:" :: Pretty.brk 1 :: prt_ids)); |
476 (Pretty.str "The error(s) above occurred in locale:" :: Pretty.brk 1 :: prt_ids)); |
603 in raise ProofContext.CONTEXT (err_msg, ctxt) end; |
477 in raise ProofContext.CONTEXT (err_msg, ctxt) end; |
604 |
478 |
605 (* Version for identifiers with axioms *) |
|
606 |
|
607 fun err_in_locale' ctxt msg ids' = err_in_locale ctxt msg (map fst ids'); |
479 fun err_in_locale' ctxt msg ids' = err_in_locale ctxt msg (map fst ids'); |
608 |
480 |
609 |
481 |
610 (** primitives **) |
482 |
611 |
483 (** witnesses -- protected facts **) |
612 (* map elements *) |
|
613 |
|
614 fun map_elem {name, var, typ, term, fact, attrib} = |
|
615 fn Fixes fixes => Fixes (fixes |> map (fn (x, T, mx) => |
|
616 let val (x', mx') = var (x, mx) in (x', Option.map typ T, mx') end)) |
|
617 | Constrains csts => Constrains (csts |> map (fn (x, T) => |
|
618 let val (x', _) = var (x, SOME Syntax.NoSyn) in (x', typ T) end)) |
|
619 | Assumes asms => Assumes (asms |> map (fn ((a, atts), propps) => |
|
620 ((name a, map attrib atts), propps |> map (fn (t, (ps, qs)) => |
|
621 (term t, (map term ps, map term qs)))))) |
|
622 | Defines defs => Defines (defs |> map (fn ((a, atts), (t, ps)) => |
|
623 ((name a, map attrib atts), (term t, map term ps)))) |
|
624 | Notes facts => Notes (facts |> map (fn ((a, atts), bs) => |
|
625 ((name a, map attrib atts), bs |> map (fn (ths, btts) => (fact ths, map attrib btts))))); |
|
626 |
|
627 fun map_values typ term thm = map_elem |
|
628 {name = I, var = I, typ = typ, term = term, fact = map thm, |
|
629 attrib = Args.map_values I typ term thm}; |
|
630 |
|
631 |
|
632 (* map attributes *) |
|
633 |
|
634 fun map_attrib_elem f = map_elem {name = I, var = I, typ = I, term = I, fact = I, attrib = f}; |
|
635 |
|
636 fun intern_attrib_elem thy = map_attrib_elem (Attrib.intern_src thy); |
|
637 |
|
638 fun intern_attrib_elem_expr thy (Elem elem) = Elem (intern_attrib_elem thy elem) |
|
639 | intern_attrib_elem_expr _ (Expr expr) = Expr expr; |
|
640 |
|
641 |
|
642 (* renaming *) |
|
643 |
|
644 (* ren maps names to (new) names and syntax; represented as association list *) |
|
645 |
|
646 fun rename_var ren (x, mx) = |
|
647 case AList.lookup (op =) ren x of |
|
648 NONE => (x, mx) |
|
649 | SOME (x', NONE) => |
|
650 (x', if mx = NONE then mx else SOME Syntax.NoSyn) (*drop syntax*) |
|
651 | SOME (x', SOME mx') => |
|
652 if mx = NONE then raise ERROR_MESSAGE |
|
653 ("Attempt to change syntax of structure parameter " ^ quote x) |
|
654 else (x', SOME mx'); (*change syntax*) |
|
655 |
|
656 fun rename ren x = |
|
657 case AList.lookup (op =) ren x of |
|
658 NONE => x |
|
659 | SOME (x', _) => x'; (*ignore syntax*) |
|
660 |
|
661 fun rename_term ren (Free (x, T)) = Free (rename ren x, T) |
|
662 | rename_term ren (t $ u) = rename_term ren t $ rename_term ren u |
|
663 | rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t) |
|
664 | rename_term _ a = a; |
|
665 |
|
666 fun rename_thm ren th = |
|
667 let |
|
668 val {thy, hyps, prop, maxidx, ...} = Thm.rep_thm th; |
|
669 val cert = Thm.cterm_of thy; |
|
670 val (xs, Ts) = Library.split_list (fold Term.add_frees (prop :: hyps) []); |
|
671 val xs' = map (rename ren) xs; |
|
672 fun cert_frees names = map (cert o Free) (names ~~ Ts); |
|
673 fun cert_vars names = map (cert o Var o apfst (rpair (maxidx + 1))) (names ~~ Ts); |
|
674 in |
|
675 if xs = xs' then th |
|
676 else |
|
677 th |
|
678 |> Drule.implies_intr_list (map cert hyps) |
|
679 |> Drule.forall_intr_list (cert_frees xs) |
|
680 |> Drule.forall_elim_list (cert_vars xs) |
|
681 |> Thm.instantiate ([], cert_vars xs ~~ cert_frees xs') |
|
682 |> (fn th' => Drule.implies_elim_list th' (map (Thm.assume o cert o rename_term ren) hyps)) |
|
683 end; |
|
684 |
|
685 fun rename_elem ren = |
|
686 map_values I (rename_term ren) (rename_thm ren) o |
|
687 map_elem {name = I, typ = I, term = I, fact = I, attrib = I, var = rename_var ren}; |
|
688 |
|
689 fun rename_facts prfx = |
|
690 map_elem {var = I, typ = I, term = I, fact = I, attrib = I, name = NameSpace.qualified prfx}; |
|
691 |
|
692 |
|
693 (* type instantiation *) |
|
694 |
|
695 fun inst_type [] T = T |
|
696 | inst_type env T = Term.map_type_tfree (fn v => AList.lookup (op =) env v |> the_default (TFree v)) T; |
|
697 |
|
698 fun inst_term [] t = t |
|
699 | inst_term env t = Term.map_term_types (inst_type env) t; |
|
700 |
|
701 fun inst_thm _ [] th = th |
|
702 | inst_thm ctxt env th = |
|
703 let |
|
704 val thy = ProofContext.theory_of ctxt; |
|
705 val cert = Thm.cterm_of thy; |
|
706 val certT = Thm.ctyp_of thy; |
|
707 val {hyps, prop, maxidx, ...} = Thm.rep_thm th; |
|
708 val tfrees = foldr Term.add_term_tfree_names [] (prop :: hyps); |
|
709 val env' = List.filter (fn ((a, _), _) => a mem_string tfrees) env; |
|
710 in |
|
711 if null env' then th |
|
712 else |
|
713 th |
|
714 |> Drule.implies_intr_list (map cert hyps) |
|
715 |> Drule.tvars_intr_list (map (#1 o #1) env') |
|
716 |> (fn (th', al) => th' |> |
|
717 Thm.instantiate ((map (fn ((a, _), T) => |
|
718 (certT (TVar ((the o AList.lookup (op =) al) a)), certT T)) env'), [])) |
|
719 |> (fn th'' => Drule.implies_elim_list th'' |
|
720 (map (Thm.assume o cert o inst_term env') hyps)) |
|
721 end; |
|
722 |
|
723 fun inst_elem ctxt env = |
|
724 map_values (inst_type env) (inst_term env) (inst_thm ctxt env); |
|
725 |
|
726 |
|
727 (* term and type instantiation, variant using symbol tables *) |
|
728 |
|
729 (* instantiate TFrees *) |
|
730 |
|
731 fun tinst_tab_elem thy tinst = |
|
732 map_values (tinst_tab_type tinst) (tinst_tab_term tinst) (tinst_tab_thm thy tinst); |
|
733 |
|
734 (* instantiate TFrees and Frees *) |
|
735 |
|
736 fun inst_tab_elem thy (inst as (_, tinst)) = |
|
737 map_values (tinst_tab_type tinst) (inst_tab_term inst) (inst_tab_thm thy inst); |
|
738 |
|
739 fun inst_tab_elems thy inst ((n, ps), elems) = |
|
740 ((n, map (inst_tab_term inst) ps), map (inst_tab_elem thy inst) elems); |
|
741 |
|
742 |
|
743 (* protected thms *) |
|
744 |
484 |
745 fun assume_protected thy t = |
485 fun assume_protected thy t = |
746 (t, Goal.protect (Thm.assume (Thm.cterm_of thy t))); |
486 (t, Goal.protect (Thm.assume (Thm.cterm_of thy t))); |
747 |
487 |
748 fun prove_protected thy t tac = |
488 fun prove_protected thy t tac = |
842 SOME (q, ids) => err_in_locale ctxt ("Multiple declaration of parameter " ^ quote q) |
577 SOME (q, ids) => err_in_locale ctxt ("Multiple declaration of parameter " ^ quote q) |
843 (map (apsnd (map fst)) ids) |
578 (map (apsnd (map fst)) ids) |
844 | NONE => map (apfst (apfst (apsnd #1))) elemss) |
579 | NONE => map (apfst (apfst (apsnd #1))) elemss) |
845 end; |
580 end; |
846 |
581 |
847 fun unify_parms ctxt (fixed_parms : (string * typ) list) |
582 fun unify_parms ctxt fixed_parms raw_parmss = |
848 (raw_parmss : (string * typ option) list list) = |
|
849 let |
583 let |
850 val thy = ProofContext.theory_of ctxt; |
584 val thy = ProofContext.theory_of ctxt; |
851 val maxidx = length raw_parmss; |
585 val maxidx = length raw_parmss; |
852 val idx_parmss = (0 upto maxidx - 1) ~~ raw_parmss; |
586 val idx_parmss = (0 upto maxidx - 1) ~~ raw_parmss; |
853 |
587 |
854 fun varify i = Term.map_type_tfree (fn (a, S) => TVar ((a, i), S)); |
588 fun varify i = Term.map_type_tfree (fn (a, S) => TVar ((a, i), S)); |
855 fun varify_parms (i, ps) = map (apsnd (varify i)) (param_types ps); |
589 fun varify_parms (i, ps) = map (apsnd (varify i)) (param_types ps); |
856 val parms = fixed_parms @ List.concat (map varify_parms idx_parmss); |
590 val parms = fixed_parms @ List.concat (map varify_parms idx_parmss); |
857 |
591 |
858 fun unify T ((env, maxidx), U) = |
592 fun unify T U envir = Sign.typ_unify thy (U, T) envir |
859 Sign.typ_unify thy (U, T) (env, maxidx) |
|
860 handle Type.TUNIFY => |
593 handle Type.TUNIFY => |
861 let val prt = Sign.string_of_typ thy |
594 let val prt = Sign.string_of_typ thy in |
862 in raise TYPE ("unify_parms: failed to unify types " ^ |
595 raise TYPE ("unify_parms: failed to unify types " ^ |
863 prt U ^ " and " ^ prt T, [U, T], []) |
596 prt U ^ " and " ^ prt T, [U, T], []) |
864 end |
597 end; |
865 fun unify_list (envir, T :: Us) = Library.foldl (unify T) (envir, Us) |
598 fun unify_list (T :: Us) = fold (unify T) Us |
866 | unify_list (envir, []) = envir; |
599 | unify_list [] = I; |
867 val (unifier, _) = Library.foldl unify_list |
600 val (unifier, _) = fold unify_list (map #2 (Symtab.dest (Symtab.make_multi parms))) |
868 ((Vartab.empty, maxidx), map #2 (Symtab.dest (Symtab.make_multi parms))); |
601 (Vartab.empty, maxidx); |
869 |
602 |
870 val parms' = map (apsnd (Envir.norm_type unifier)) (gen_distinct (eq_fst (op =)) parms); |
603 val parms' = map (apsnd (Envir.norm_type unifier)) (gen_distinct (eq_fst (op =)) parms); |
871 val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (map #2 parms')); |
604 val unifier' = Vartab.extend (unifier, frozen_tvars ctxt (map #2 parms')); |
872 |
605 |
873 fun inst_parms (i, ps) = |
606 fun inst_parms (i, ps) = |
874 foldr Term.add_typ_tfrees [] (List.mapPartial snd ps) |
607 foldr Term.add_typ_tfrees [] (List.mapPartial snd ps) |
875 |> List.mapPartial (fn (a, S) => |
608 |> List.mapPartial (fn (a, S) => |
876 let val T = Envir.norm_type unifier' (TVar ((a, i), S)) |
609 let val T = Envir.norm_type unifier' (TVar ((a, i), S)) |
877 in if T = TFree (a, S) then NONE else SOME ((a, S), T) end) |
610 in if T = TFree (a, S) then NONE else SOME (a, T) end) |
878 in map inst_parms idx_parmss end : ((string * sort) * typ) list list; |
611 |> Symtab.make; |
|
612 in map inst_parms idx_parmss end; |
879 |
613 |
880 in |
614 in |
881 |
615 |
882 fun unify_elemss _ _ [] = [] |
616 fun unify_elemss _ _ [] = [] |
883 | unify_elemss _ [] [elems] = [elems] |
617 | unify_elemss _ [] [elems] = [elems] |
884 | unify_elemss ctxt fixed_parms elemss = |
618 | unify_elemss ctxt fixed_parms elemss = |
885 let |
619 let |
|
620 val thy = ProofContext.theory_of ctxt; |
886 val envs = unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss); |
621 val envs = unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss); |
887 fun inst ((((name, ps), mode), elems), env) = |
622 fun inst ((((name, ps), mode), elems), env) = |
888 (((name, map (apsnd (Option.map (inst_type env))) ps), |
623 (((name, map (apsnd (Option.map (Element.instT_type env))) ps), |
889 map_mode (map (fn (t, th) => (inst_term env t, inst_thm ctxt env th))) mode), |
624 map_mode (map (fn (t, th) => |
890 map (inst_elem ctxt env) elems); |
625 (Element.instT_term env t, Element.instT_thm thy env th))) mode), |
|
626 map (Element.instT_ctxt thy env) elems); |
891 in map inst (elemss ~~ envs) end; |
627 in map inst (elemss ~~ envs) end; |
892 |
628 |
893 (* like unify_elemss, but does not touch mode, additional |
629 (* like unify_elemss, but does not touch mode, additional |
894 parameter c_parms for enforcing further constraints (eg. syntax) *) |
630 parameter c_parms for enforcing further constraints (eg. syntax) *) |
895 |
631 |
896 fun unify_elemss' _ _ [] [] = [] |
632 fun unify_elemss' _ _ [] [] = [] |
897 | unify_elemss' _ [] [elems] [] = [elems] |
633 | unify_elemss' _ [] [elems] [] = [elems] |
898 | unify_elemss' ctxt fixed_parms elemss c_parms = |
634 | unify_elemss' ctxt fixed_parms elemss c_parms = |
899 let |
635 let |
900 val envs = unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss @ map single c_parms); |
636 val thy = ProofContext.theory_of ctxt; |
|
637 val envs = |
|
638 unify_parms ctxt fixed_parms (map (snd o fst o fst) elemss @ map single c_parms); |
901 fun inst ((((name, ps), (ps', mode)), elems), env) = |
639 fun inst ((((name, ps), (ps', mode)), elems), env) = |
902 (((name, map (apsnd (Option.map (inst_type env))) ps), |
640 (((name, map (apsnd (Option.map (Element.instT_type env))) ps), (ps', mode)), |
903 (ps', mode)), |
641 map (Element.instT_ctxt thy env) elems); |
904 map (inst_elem ctxt env) elems); |
|
905 in map inst (elemss ~~ (Library.take (length elemss, envs))) end; |
642 in map inst (elemss ~~ (Library.take (length elemss, envs))) end; |
906 |
643 |
907 |
644 |
908 (* flatten_expr: |
645 (* flatten_expr: |
909 Extend list of identifiers by those new in locale expression expr. |
646 Extend list of identifiers by those new in locale expression expr. |
927 *) |
664 *) |
928 |
665 |
929 fun flatten_expr ctxt ((prev_idents, prev_syntax), expr) = |
666 fun flatten_expr ctxt ((prev_idents, prev_syntax), expr) = |
930 let |
667 let |
931 val thy = ProofContext.theory_of ctxt; |
668 val thy = ProofContext.theory_of ctxt; |
932 (* thy used for retrieval of locale info, |
|
933 ctxt for error messages, parameter unification and instantiation |
|
934 of axioms *) |
|
935 |
669 |
936 fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys |
670 fun renaming (SOME x :: xs) (y :: ys) = (y, x) :: renaming xs ys |
937 | renaming (NONE :: xs) (y :: ys) = renaming xs ys |
671 | renaming (NONE :: xs) (y :: ys) = renaming xs ys |
938 | renaming [] _ = [] |
672 | renaming [] _ = [] |
939 | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^ |
673 | renaming xs [] = raise ERROR_MESSAGE ("Too many arguments in renaming: " ^ |
940 commas (map (fn NONE => "_" | SOME x => quote (fst x)) xs)); |
674 commas (map (fn NONE => "_" | SOME x => quote (fst x)) xs)); |
941 |
675 |
942 fun rename_parms top ren ((name, ps), (parms, mode)) = |
676 fun rename_parms top ren ((name, ps), (parms, mode)) = |
943 let val ps' = map (rename ren) ps in |
677 let val ps' = map (Element.rename ren) ps in |
944 (case duplicates ps' of |
678 (case duplicates ps' of |
945 [] => ((name, ps'), |
679 [] => ((name, ps'), |
946 if top then (map (rename ren) parms, |
680 if top then (map (Element.rename ren) parms, |
947 map_mode (map (fn (t, th) => |
681 map_mode (map (fn (t, th) => |
948 (rename_term ren t, rename_thm ren th))) mode) |
682 (Element.rename_term ren t, Element.rename_thm ren th))) mode) |
949 else (parms, mode)) |
683 else (parms, mode)) |
950 | dups => err_in_locale ctxt ("Duplicate parameters: " ^ commas_quote dups) [(name, ps')]) |
684 | dups => err_in_locale ctxt ("Duplicate parameters: " ^ commas_quote dups) [(name, ps')]) |
951 end; |
685 end; |
952 |
686 |
953 (* add registrations of (name, ps), recursively; |
687 (* add registrations of (name, ps), recursively; |
961 (* dummy syntax, since required by rename *) |
695 (* dummy syntax, since required by rename *) |
962 val ps'' = map (fn ((p, _), (_, T)) => (p, T)) (ps ~~ ps'); |
696 val ps'' = map (fn ((p, _), (_, T)) => (p, T)) (ps ~~ ps'); |
963 val [env] = unify_parms ctxt ps [map (apsnd SOME) ps'']; |
697 val [env] = unify_parms ctxt ps [map (apsnd SOME) ps'']; |
964 (* propagate parameter types, to keep them consistent *) |
698 (* propagate parameter types, to keep them consistent *) |
965 val regs' = map (fn ((name, ps), ths) => |
699 val regs' = map (fn ((name, ps), ths) => |
966 ((name, map (rename ren) ps), ths)) regs; |
700 ((name, map (Element.rename ren) ps), ths)) regs; |
967 val new_regs = gen_rems (eq_fst (op =)) (regs', ids); |
701 val new_regs = gen_rems (eq_fst (op =)) (regs', ids); |
968 val new_ids = map fst new_regs; |
702 val new_ids = map fst new_regs; |
969 val new_idTs = map (apsnd (map (fn p => (p, (the o AList.lookup (op =) ps) p)))) new_ids; |
703 val new_idTs = map (apsnd (map (fn p => (p, (the o AList.lookup (op =) ps) p)))) new_ids; |
970 |
704 |
971 val new_ths = new_regs |> map (fn (_, ths') => ths' |> map (fn (t, th) => |
705 val new_ths = new_regs |> map (fn (_, ths') => ths' |> map (fn (t, th) => |
972 (t |> inst_term env |> rename_term ren, |
706 (t |> Element.instT_term env |> Element.rename_term ren, |
973 th |> inst_thm ctxt env |> rename_thm ren |> satisfy_protected ths))); |
707 th |> Element.instT_thm thy env |> Element.rename_thm ren |> satisfy_protected ths))); |
974 val new_ids' = map (fn (id, ths) => |
708 val new_ids' = map (fn (id, ths) => |
975 (id, ([], Derived ths))) (new_ids ~~ new_ths); |
709 (id, ([], Derived ths))) (new_ids ~~ new_ths); |
976 in |
710 in |
977 fold add_regs new_idTs (ths @ List.concat new_ths, ids @ new_ids') |
711 fold add_regs new_idTs (ths @ List.concat new_ths, ids @ new_ids') |
978 end; |
712 end; |
1047 val ps' = map (apsnd SOME o #1) ps; |
780 val ps' = map (apsnd SOME o #1) ps; |
1048 val ren = map #1 ps' ~~ |
781 val ren = map #1 ps' ~~ |
1049 map (fn x => (x, valOf (Symtab.lookup syn x))) xs; |
782 map (fn x => (x, valOf (Symtab.lookup syn x))) xs; |
1050 val (params', elems') = |
783 val (params', elems') = |
1051 if null ren then ((ps', qs), map #1 elems) |
784 if null ren then ((ps', qs), map #1 elems) |
1052 else ((map (apfst (rename ren)) ps', map (rename ren) qs), |
785 else ((map (apfst (Element.rename ren)) ps', map (Element.rename ren) qs), |
1053 map (rename_elem ren o #1) elems); |
786 map (Element.rename_ctxt ren o #1) elems); |
1054 val elems'' = map (rename_facts (space_implode "_" xs)) elems'; |
787 val elems'' = elems' |> map (Element.map_ctxt |
|
788 {var = I, typ = I, term = I, fact = I, attrib = I, |
|
789 name = NameSpace.qualified (space_implode "_" xs)}); |
1055 in (((name, params'), axs), elems'') end; |
790 in (((name, params'), axs), elems'') end; |
1056 |
791 |
1057 (* type constraint for renamed parameter with syntax *) |
792 (* type constraint for renamed parameter with syntax *) |
1058 fun type_syntax NONE = NONE |
793 fun type_syntax NONE = NONE |
1059 | type_syntax (SOME mx) = let |
794 | type_syntax (SOME mx) = let |
1252 The implementation of activate_facts relies on identifier names being |
973 The implementation of activate_facts relies on identifier names being |
1253 empty strings for external elements. |
974 empty strings for external elements. |
1254 *) |
975 *) |
1255 |
976 |
1256 fun flatten (ctxt, _) ((ids, syn), Elem (Fixes fixes)) = let |
977 fun flatten (ctxt, _) ((ids, syn), Elem (Fixes fixes)) = let |
1257 val ids' = ids @ [(("", map #1 fixes), ([], Assumed []))] |
978 val ids' = ids @ [(("", map #1 fixes), ([], Assumed []))] |
1258 in |
979 in |
1259 ((ids', |
980 ((ids', |
1260 merge_syntax ctxt ids' |
981 merge_syntax ctxt ids' |
1261 (syn, Symtab.make (map (fn fx => (#1 fx, #3 fx)) fixes)) |
982 (syn, Symtab.make (map (fn fx => (#1 fx, #3 fx)) fixes)) |
1262 handle Symtab.DUPS xs => err_in_locale ctxt |
983 handle Symtab.DUPS xs => err_in_locale ctxt |
1263 ("Conflicting syntax for parameters: " ^ commas_quote xs) |
984 ("Conflicting syntax for parameters: " ^ commas_quote xs) |
1264 (map #1 ids')), |
985 (map #1 ids')), |
1265 [((("", map (rpair NONE o #1) fixes), Assumed []), Ext (Fixes fixes))]) |
986 [((("", map (rpair NONE o #1) fixes), Assumed []), Ext (Fixes fixes))]) |
1266 end |
987 end |
1267 | flatten _ ((ids, syn), Elem elem) = |
988 | flatten _ ((ids, syn), Elem elem) = |
1268 ((ids @ [(("", []), ([], Assumed []))], syn), [((("", []), Assumed []), Ext elem)]) |
989 ((ids @ [(("", []), ([], Assumed []))], syn), [((("", []), Assumed []), Ext elem)]) |
1269 | flatten (ctxt, prep_expr) ((ids, syn), Expr expr) = |
990 | flatten (ctxt, prep_expr) ((ids, syn), Expr expr) = |
1270 apsnd (map (apsnd Int)) (flatten_expr ctxt ((ids, syn), prep_expr expr)); |
991 apsnd (map (apsnd Int)) (flatten_expr ctxt ((ids, syn), prep_expr expr)); |
1648 val cert_context_statement = gen_statement (K I) gen_context_i; |
1360 val cert_context_statement = gen_statement (K I) gen_context_i; |
1649 |
1361 |
1650 end; |
1362 end; |
1651 |
1363 |
1652 |
1364 |
1653 (** define locales **) |
|
1654 |
|
1655 (* print locale *) |
1365 (* print locale *) |
1656 |
1366 |
1657 fun print_locale thy show_facts import body = |
1367 fun print_locale thy show_facts import body = |
1658 let |
1368 let |
1659 val thy_ctxt = ProofContext.init thy; |
1369 val (((_, import_elemss), (ctxt, elemss, _)), _) = |
1660 val (((_, import_elemss), (ctxt, elemss, _)), _) = read_context import body thy_ctxt; |
1370 read_context import body (ProofContext.init thy); |
|
1371 val prt_elem = Element.pretty_ctxt ctxt; |
1661 val all_elems = List.concat (map #2 (import_elemss @ elemss)); |
1372 val all_elems = List.concat (map #2 (import_elemss @ elemss)); |
1662 |
|
1663 val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt; |
|
1664 val prt_term = Pretty.quote o ProofContext.pretty_term ctxt; |
|
1665 val prt_thm = Pretty.quote o ProofContext.pretty_thm ctxt; |
|
1666 val prt_atts = Args.pretty_attribs ctxt; |
|
1667 |
|
1668 fun prt_syn syn = |
|
1669 let val s = (case syn of NONE => "(structure)" | SOME mx => Syntax.string_of_mixfix mx) |
|
1670 in if s = "" then [] else [Pretty.brk 2, Pretty.str s] end; |
|
1671 fun prt_fix (x, SOME T, syn) = Pretty.block (Pretty.str (x ^ " ::") :: Pretty.brk 1 :: |
|
1672 prt_typ T :: Pretty.brk 1 :: prt_syn syn) |
|
1673 | prt_fix (x, NONE, syn) = Pretty.block (Pretty.str x :: Pretty.brk 1 :: prt_syn syn); |
|
1674 fun prt_cst (x, T) = Pretty.block [Pretty.str (x ^ " ::"), prt_typ T]; |
|
1675 |
|
1676 fun prt_name name = Pretty.str (ProofContext.extern_thm ctxt name); |
|
1677 fun prt_name_atts (name, atts) = |
|
1678 if name = "" andalso null atts then [] |
|
1679 else [Pretty.block (Pretty.breaks (prt_name name :: prt_atts atts @ [Pretty.str ":"]))]; |
|
1680 |
|
1681 fun prt_asm (a, ts) = |
|
1682 Pretty.block (Pretty.breaks (prt_name_atts a @ map (prt_term o fst) ts)); |
|
1683 fun prt_def (a, (t, _)) = |
|
1684 Pretty.block (Pretty.breaks (prt_name_atts a @ [prt_term t])); |
|
1685 |
|
1686 fun prt_fact (ths, []) = map prt_thm ths |
|
1687 | prt_fact (ths, atts) = |
|
1688 Pretty.enclose "(" ")" (Pretty.breaks (map prt_thm ths)) :: prt_atts atts; |
|
1689 fun prt_note (a, ths) = |
|
1690 Pretty.block (Pretty.breaks (List.concat (prt_name_atts a :: map prt_fact ths))); |
|
1691 |
|
1692 fun items _ [] = [] |
|
1693 | items prfx (x :: xs) = Pretty.block [Pretty.str prfx, Pretty.brk 1, x] :: items " and" xs; |
|
1694 fun prt_elem (Fixes fixes) = items "fixes" (map prt_fix fixes) |
|
1695 | prt_elem (Constrains csts) = items "constrains" (map prt_cst csts) |
|
1696 | prt_elem (Assumes asms) = items "assumes" (map prt_asm asms) |
|
1697 | prt_elem (Defines defs) = items "defines" (map prt_def defs) |
|
1698 | prt_elem (Notes facts) = items "notes" (map prt_note facts); |
|
1699 in |
1373 in |
1700 Pretty.big_list "context elements:" (all_elems |
1374 Pretty.big_list "locale elements:" (all_elems |
1701 |> (if show_facts then I else filter (fn Notes _ => false | _ => true)) |
1375 |> (if show_facts then I else filter (fn Notes _ => false | _ => true)) |
1702 |> map (Pretty.chunks o prt_elem)) |
1376 |> map (Pretty.chunks o prt_elem)) |
1703 |> Pretty.writeln |
1377 |> Pretty.writeln |
1704 end; |
1378 end; |
1705 |
1379 |
1766 val ts = map Logic.unvarify vts; |
1440 val ts = map Logic.unvarify vts; |
1767 val (parms, parmTs) = split_list parms; |
1441 val (parms, parmTs) = split_list parms; |
1768 val parmvTs = map Type.varifyT parmTs; |
1442 val parmvTs = map Type.varifyT parmTs; |
1769 val vtinst = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of ts) Vartab.empty; |
1443 val vtinst = fold (Sign.typ_match thy) (parmvTs ~~ map Term.fastype_of ts) Vartab.empty; |
1770 val tinst = Vartab.dest vtinst |> map (fn ((x, 0), (_, T)) => (x, T)) |
1444 val tinst = Vartab.dest vtinst |> map (fn ((x, 0), (_, T)) => (x, T)) |
1771 |> Symtab.make; |
1445 |> Symtab.make; |
1772 (* replace parameter names in ids by instantiations *) |
1446 (* replace parameter names in ids by instantiations *) |
1773 val vinst = Symtab.make (parms ~~ vts); |
1447 val vinst = Symtab.make (parms ~~ vts); |
1774 fun vinst_names ps = map (the o Symtab.lookup vinst) ps; |
1448 fun vinst_names ps = map (the o Symtab.lookup vinst) ps; |
1775 val inst = Symtab.make (parms ~~ ts); |
1449 val inst = Symtab.make (parms ~~ ts); |
1776 val ids' = map (apsnd vinst_names) ids; |
1450 val ids' = map (apsnd vinst_names) ids; |
1777 val wits = List.concat (map (snd o valOf o get_global_registration thy) ids'); |
1451 val wits = List.concat (map (snd o valOf o get_global_registration thy) ids'); |
1778 in ((inst, tinst), wits) end; |
1452 in ((tinst, inst), wits) end; |
1779 |
1453 |
1780 |
1454 |
1781 (* store instantiations of args for all registered interpretations |
1455 (* store instantiations of args for all registered interpretations |
1782 of the theory *) |
1456 of the theory *) |
1783 |
1457 |
1792 |
1466 |
1793 (* add args to thy for all registrations *) |
1467 (* add args to thy for all registrations *) |
1794 |
1468 |
1795 fun activate (thy, (vts, ((prfx, atts2), _))) = |
1469 fun activate (thy, (vts, ((prfx, atts2), _))) = |
1796 let |
1470 let |
1797 val ((inst, tinst), prems) = collect_global_witnesses thy parms ids vts; |
1471 val (insts, prems) = collect_global_witnesses thy parms ids vts; |
1798 val args' = map (fn ((n, atts), [(ths, [])]) => |
1472 val inst_atts = |
|
1473 Args.map_values I (Element.instT_type (#1 insts)) |
|
1474 (Element.inst_term insts) (Element.inst_thm thy insts); |
|
1475 val args' = args |> map (fn ((n, atts), [(ths, [])]) => |
1799 ((NameSpace.qualified prfx n, |
1476 ((NameSpace.qualified prfx n, |
1800 map (Attrib.global_attribute_i thy) |
1477 map (Attrib.global_attribute_i thy) (map inst_atts atts @ atts2)), |
1801 (inst_tab_atts thy (inst, tinst) atts @ atts2)), |
|
1802 [(map (Drule.standard o satisfy_protected prems o |
1478 [(map (Drule.standard o satisfy_protected prems o |
1803 inst_tab_thm thy (inst, tinst)) ths, [])])) |
1479 Element.inst_thm thy insts) ths, [])])); |
1804 args; |
|
1805 in global_note_accesses_i (Drule.kind kind) prfx args' thy |> fst end; |
1480 in global_note_accesses_i (Drule.kind kind) prfx args' thy |> fst end; |
1806 in Library.foldl activate (thy, regs) end; |
1481 in Library.foldl activate (thy, regs) end; |
1807 |
1482 |
1808 |
1483 |
1809 fun smart_note_thmss kind NONE = PureThy.note_thmss_i (Drule.kind kind) |
1484 fun smart_note_thmss kind NONE = PureThy.note_thmss_i (Drule.kind kind) |
2019 val (pred_thy, (elemss', predicate as (predicate_statement, predicate_axioms))) = |
1697 val (pred_thy, (elemss', predicate as (predicate_statement, predicate_axioms))) = |
2020 if do_pred then thy |> define_preds bname text elemss |
1698 if do_pred then thy |> define_preds bname text elemss |
2021 else (thy, (elemss, ([], []))); |
1699 else (thy, (elemss, ([], []))); |
2022 val pred_ctxt = ProofContext.init pred_thy; |
1700 val pred_ctxt = ProofContext.init pred_thy; |
2023 |
1701 |
2024 fun axiomify axioms elemss = |
1702 fun axiomify axioms elemss = |
2025 (axioms, elemss) |> foldl_map (fn (axs, (id, elems)) => let |
1703 (axioms, elemss) |> foldl_map (fn (axs, (id, elems)) => let |
2026 val ts = List.concat (List.mapPartial (fn (Assumes asms) => |
1704 val ts = List.concat (List.mapPartial (fn (Assumes asms) => |
2027 SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems); |
1705 SOME (List.concat (map (map #1 o #2) asms)) | _ => NONE) elems); |
2028 val (axs1, axs2) = splitAt (length ts, axs); |
1706 val (axs1, axs2) = splitAt (length ts, axs); |
2029 in (axs2, ((id, Assumed axs1), elems)) end) |
1707 in (axs2, ((id, Assumed axs1), elems)) end) |
2269 val inst = Symtab.make (given_ps ~~ map rename vs); |
1954 val inst = Symtab.make (given_ps ~~ map rename vs); |
2270 |
1955 |
2271 (* defined params without user input *) |
1956 (* defined params without user input *) |
2272 val not_given = List.mapPartial (fn (x, (NONE, T)) => SOME (x, T) |
1957 val not_given = List.mapPartial (fn (x, (NONE, T)) => SOME (x, T) |
2273 | (_, (SOME _, _)) => NONE) (ps ~~ (insts ~~ pTs)); |
1958 | (_, (SOME _, _)) => NONE) (ps ~~ (insts ~~ pTs)); |
2274 fun add_def ((inst, tinst), (p, pT)) = |
1959 fun add_def (p, pT) inst = |
2275 let |
1960 let |
2276 val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of |
1961 val (t, T) = case find_first (fn (Free (a, _), _) => a = p) defs of |
2277 NONE => error ("Instance missing for parameter " ^ quote p) |
1962 NONE => error ("Instance missing for parameter " ^ quote p) |
2278 | SOME (Free (_, T), t) => (t, T); |
1963 | SOME (Free (_, T), t) => (t, T); |
2279 val d = inst_tab_term (inst, tinst) t; |
1964 val d = Element.inst_term (tinst, inst) t; |
2280 in (Symtab.update_new (p, d) inst, tinst) end; |
1965 in Symtab.update_new (p, d) inst end; |
2281 val (inst, tinst) = Library.foldl add_def ((inst, tinst), not_given); |
1966 val inst = fold add_def not_given inst; |
2282 (* Note: inst and tinst contain no vars. *) |
1967 val insts = (tinst, inst); |
|
1968 (* Note: insts contain no vars. *) |
2283 |
1969 |
2284 (** compute proof obligations **) |
1970 (** compute proof obligations **) |
2285 |
1971 |
2286 (* restore "small" ids *) |
1972 (* restore "small" ids *) |
2287 val ids' = map (fn ((n, ps), (_, mode)) => |
1973 val ids' = map (fn ((n, ps), (_, mode)) => |
2288 ((n, map (fn p => Free (p, (the o AList.lookup (op =) parms) p)) ps), mode)) ids; |
1974 ((n, map (fn p => Free (p, (the o AList.lookup (op =) parms) p)) ps), mode)) ids; |
2289 (* instantiate ids and elements *) |
1975 (* instantiate ids and elements *) |
2290 val inst_elemss = map |
1976 val inst_elemss = (ids' ~~ all_elemss) |> map (fn (((n, ps), _), ((_, mode), elems)) => |
2291 (fn ((id, _), ((_, mode), elems)) => |
1977 ((n, map (Element.inst_term insts) ps), |
2292 inst_tab_elems thy (inst, tinst) (id, map (fn Int e => e) elems) |
1978 map (fn Int e => Element.inst_ctxt thy insts e) elems) |
2293 |> apfst (fn id => (id, map_mode (map (fn (t, th) => |
1979 |> apfst (fn id => (id, map_mode (map (fn (t, th) => |
2294 (inst_tab_term (inst, tinst) t, inst_tab_thm thy (inst, tinst) th))) mode))) |
1980 (Element.inst_term insts t, Element.inst_thm thy insts th))) mode))); |
2295 (ids' ~~ all_elemss); |
|
2296 |
1981 |
2297 (* remove fragments already registered with theory or context *) |
1982 (* remove fragments already registered with theory or context *) |
2298 val new_inst_elemss = List.filter (fn ((id, _), _) => |
1983 val new_inst_elemss = List.filter (fn ((id, _), _) => |
2299 not (test_reg thy_ctxt id)) inst_elemss; |
1984 not (test_reg thy_ctxt id)) inst_elemss; |
2300 val new_ids = map #1 new_inst_elemss; |
1985 val new_ids = map #1 new_inst_elemss; |
2361 thy |> put_registration_in_locale target id |
2046 thy |> put_registration_in_locale target id |
2362 |> fold (add_witness_in_locale target id) thms |
2047 |> fold (add_witness_in_locale target id) thms |
2363 | activate_id _ thy = thy; |
2048 | activate_id _ thy = thy; |
2364 |
2049 |
2365 fun activate_reg (vts, ((prfx, atts2), _)) thy = let |
2050 fun activate_reg (vts, ((prfx, atts2), _)) thy = let |
2366 val ((inst, tinst), wits) = |
2051 val (insts, wits) = collect_global_witnesses thy fixed t_ids vts; |
2367 collect_global_witnesses thy fixed t_ids vts; |
2052 fun inst_parms ps = map |
2368 fun inst_parms ps = map |
|
2369 (the o AList.lookup (op =) (map #1 fixed ~~ vts)) ps; |
2053 (the o AList.lookup (op =) (map #1 fixed ~~ vts)) ps; |
2370 val disch = satisfy_protected wits; |
2054 val disch = satisfy_protected wits; |
2371 val new_elemss = List.filter (fn (((name, ps), _), _) => |
2055 val new_elemss = List.filter (fn (((name, ps), _), _) => |
2372 not (test_global_registration thy (name, inst_parms ps))) (ids_elemss); |
2056 not (test_global_registration thy (name, inst_parms ps))) (ids_elemss); |
2373 fun activate_assumed_id (((_, Derived _), _), _) thy = thy |
2057 fun activate_assumed_id (((_, Derived _), _), _) thy = thy |
2390 if test_global_registration thy (name, ps') |
2073 if test_global_registration thy (name, ps') |
2391 then thy |
2074 then thy |
2392 else thy |
2075 else thy |
2393 |> put_global_registration (name, ps') (prfx, atts2) |
2076 |> put_global_registration (name, ps') (prfx, atts2) |
2394 |> fold (fn (t, th) => fn thy => add_global_witness (name, ps') |
2077 |> fold (fn (t, th) => fn thy => add_global_witness (name, ps') |
2395 (inst_tab_term (inst, tinst) t, |
2078 (Element.inst_term insts t, |
2396 disch (inst_tab_thm thy (inst, tinst) (satisfy th))) thy) ths |
2079 disch (Element.inst_thm thy insts (satisfy th))) thy) ths |
2397 end; |
2080 end; |
2398 |
2081 |
2399 fun activate_elem (Notes facts) thy = |
2082 fun activate_elem (Notes facts) thy = |
2400 let |
2083 let |
2401 val facts' = facts |
2084 val facts' = facts |
2402 |> Attrib.map_facts (Attrib.global_attribute_i thy o |
2085 |> Attrib.map_facts (Attrib.global_attribute_i thy o |
2403 Args.map_values I (tinst_tab_type tinst) |
2086 Args.map_values I (Element.instT_type (#1 insts)) |
2404 (inst_tab_term (inst, tinst)) |
2087 (Element.inst_term insts) |
2405 (disch o inst_tab_thm thy (inst, tinst) o satisfy)) |
2088 (disch o Element.inst_thm thy insts o satisfy)) |
2406 |> map (apfst (apsnd (fn a => a @ map (Attrib.global_attribute thy) atts2))) |
2089 |> map (apfst (apsnd (fn a => a @ map (Attrib.global_attribute thy) atts2))) |
2407 |> map (apsnd (map (apfst (map (disch o inst_tab_thm thy (inst, tinst) o satisfy))))) |
2090 |> map (apsnd (map (apfst (map (disch o Element.inst_thm thy insts o satisfy))))) |
2408 |> map (apfst (apfst (NameSpace.qualified prfx))) |
2091 |> map (apfst (apfst (NameSpace.qualified prfx))) |
2409 in |
2092 in |
2410 fst (global_note_accesses_i (Drule.kind "") prfx facts' thy) |
2093 fst (global_note_accesses_i (Drule.kind "") prfx facts' thy) |
2411 end |
2094 end |
2412 | activate_elem _ thy = thy; |
2095 | activate_elem _ thy = thy; |