70 COMP_INCR asm_rl) |
70 COMP_INCR asm_rl) |
71 |> Thm.adjust_maxidx_thm ~1 |
71 |> Thm.adjust_maxidx_thm ~1 |
72 |> restore_tags thm |
72 |> restore_tags thm |
73 end; |
73 end; |
74 |
74 |
|
75 (* FIXME unused *) |
|
76 fun read_instantiate_no_thm ctxt insts fixes = |
|
77 let |
|
78 val (type_insts, term_insts) = |
|
79 List.partition (fn (((x, _) : indexname), _) => String.isPrefix "'" x) insts; |
|
80 |
|
81 val ctxt1 = |
|
82 ctxt |
|
83 |> Context_Position.not_really |
|
84 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; |
|
85 |
|
86 val typs = |
|
87 map snd type_insts |
|
88 |> Syntax.read_typs ctxt1 |
|
89 |> Syntax.check_typs ctxt1; |
|
90 |
|
91 val typ_insts' = map2 (fn (xi, _) => fn T => (xi,T)) type_insts typs; |
|
92 |
|
93 val terms = |
|
94 map snd term_insts |
|
95 |> Syntax.read_terms ctxt1 |
|
96 |> Syntax.check_terms ctxt1; |
|
97 |
|
98 val term_insts' = map2 (fn (xi, _) => fn t => (xi, t)) term_insts terms; |
|
99 |
|
100 in (typ_insts',term_insts') end; |
|
101 |
75 |
102 |
76 datatype rule_inst = |
103 datatype rule_inst = |
77 Named_Insts of ((indexname * string) * (term -> unit)) list |
104 Named_Insts of ((indexname * string) * (term -> unit)) list * (binding * string option * mixfix) list |
78 | Term_Insts of (indexname * term) list; |
105 (*| Unchecked_Of_Insts of (string option list * string option list) * (binding * string option * mixfix) list*) |
|
106 | Term_Insts of (indexname * term) list |
|
107 | Unchecked_Term_Insts of term option list * term option list; |
|
108 |
|
109 fun mk_pair (t, t') = Logic.mk_conjunction (Logic.mk_term t, Logic.mk_term t'); |
|
110 |
|
111 fun dest_pair t = apply2 Logic.dest_term (Logic.dest_conjunction t); |
79 |
112 |
80 fun embed_indexname ((xi, s), f) = |
113 fun embed_indexname ((xi, s), f) = |
81 let |
114 let fun wrap_xi xi t = mk_pair (Var (xi, fastype_of t), t); |
82 fun wrap_xi xi t = |
|
83 Logic.mk_conjunction (Logic.mk_term (Var (xi, fastype_of t)), Logic.mk_term t); |
|
84 in ((xi, s), f o wrap_xi xi) end; |
115 in ((xi, s), f o wrap_xi xi) end; |
85 |
116 |
86 fun unembed_indexname t = |
117 fun unembed_indexname t = dest_pair t |> apfst (Term.dest_Var #> fst); |
87 let |
118 |
88 val (t, t') = apply2 Logic.dest_term (Logic.dest_conjunction t); |
119 fun read_where_insts (insts, fixes) = |
89 val (xi, _) = Term.dest_Var t; |
120 let |
90 in (xi, t') end; |
|
91 |
|
92 fun read_where_insts toks = |
|
93 let |
|
94 val parser = |
|
95 Parse.!!! |
|
96 (Parse.and_list1 (Args.var -- (Args.$$$ "=" |-- Parse_Tools.name_term)) -- Parse.for_fixes) |
|
97 --| Scan.ahead Parse.eof; |
|
98 val (insts, fixes) = the (Scan.read Token.stopper parser toks); |
|
99 |
|
100 val insts' = |
121 val insts' = |
101 if forall (fn (_, v) => Parse_Tools.is_real_val v) insts |
122 if forall (fn (_, v) => Parse_Tools.is_real_val v) insts |
102 then Term_Insts (map (fn (_, t) => unembed_indexname (Parse_Tools.the_real_val t)) insts) |
123 then Term_Insts (map (unembed_indexname o Parse_Tools.the_real_val o snd) insts) |
103 else Named_Insts (map (fn (xi, p) => embed_indexname |
124 else |
104 ((xi, Parse_Tools.the_parse_val p), Parse_Tools.the_parse_fun p)) insts); |
125 Named_Insts (map (fn (xi, p) => embed_indexname |
105 in |
126 ((xi, Parse_Tools.the_parse_val p), Parse_Tools.the_parse_fun p)) insts, fixes); |
106 (insts', fixes) |
127 in insts' end; |
107 end; |
|
108 |
128 |
109 fun of_rule thm (args, concl_args) = |
129 fun of_rule thm (args, concl_args) = |
110 let |
130 let |
111 fun zip_vars _ [] = [] |
131 fun zip_vars _ [] = [] |
112 | zip_vars (_ :: xs) (NONE :: rest) = zip_vars xs rest |
132 | zip_vars (_ :: xs) (NONE :: rest) = zip_vars xs rest |
118 in insts end; |
138 in insts end; |
119 |
139 |
120 val inst = Args.maybe Parse_Tools.name_term; |
140 val inst = Args.maybe Parse_Tools.name_term; |
121 val concl = Args.$$$ "concl" -- Args.colon; |
141 val concl = Args.$$$ "concl" -- Args.colon; |
122 |
142 |
123 fun read_of_insts toks thm = |
143 fun close_unchecked_insts context ((insts,concl_inst), fixes) = |
124 let |
144 let |
125 val parser = |
145 val ctxt = Context.proof_of context; |
126 Parse.!!! |
146 val ctxt1 = ctxt |
127 ((Scan.repeat (Scan.unless concl inst) -- Scan.optional (concl |-- Scan.repeat inst) []) |
147 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; |
128 -- Parse.for_fixes) --| Scan.ahead Parse.eof; |
148 |
129 val ((insts, concl_insts), fixes) = |
149 val insts' = insts @ concl_inst; |
130 the (Scan.read Token.stopper parser toks); |
150 |
131 |
151 val term_insts = |
132 val insts' = |
152 map (the_list o (Option.map Parse_Tools.the_parse_val)) insts' |
133 if forall (fn SOME t => Parse_Tools.is_real_val t | NONE => true) (insts @ concl_insts) |
153 |> burrow (Syntax.read_terms ctxt1 |
134 then |
154 #> Syntax.check_terms ctxt1 |
135 Term_Insts |
155 #> Variable.export_terms ctxt1 ctxt) |
136 (map_filter |
156 |> map (try the_single); |
137 (Option.map (Parse_Tools.the_real_val #> unembed_indexname)) (insts @ concl_insts)) |
157 |
138 else |
158 val _ = |
|
159 (insts', term_insts) |
|
160 |> ListPair.app (fn (SOME p, SOME t) => Parse_Tools.the_parse_fun p t | _ => ()); |
|
161 val (insts'',concl_insts'') = chop (length insts) term_insts; |
|
162 in Unchecked_Term_Insts (insts'', concl_insts'') end; |
|
163 |
|
164 fun read_of_insts checked context ((insts, concl_insts), fixes) = |
|
165 if forall (fn SOME t => Parse_Tools.is_real_val t | NONE => true) (insts @ concl_insts) |
|
166 then |
|
167 if checked |
|
168 then |
|
169 (fn _ => |
|
170 Term_Insts |
|
171 (map (unembed_indexname o Parse_Tools.the_real_val) (map_filter I (insts @ concl_insts)))) |
|
172 else |
|
173 (fn _ => |
|
174 Unchecked_Term_Insts |
|
175 (map (Option.map Parse_Tools.the_real_val) insts, |
|
176 map (Option.map Parse_Tools.the_real_val) concl_insts)) |
|
177 else |
|
178 if checked |
|
179 then |
|
180 (fn thm => |
139 Named_Insts |
181 Named_Insts |
140 (apply2 |
182 (apply2 |
141 (map (Option.map (fn p => (Parse_Tools.the_parse_val p, Parse_Tools.the_parse_fun p)))) |
183 (map (Option.map (fn p => (Parse_Tools.the_parse_val p, Parse_Tools.the_parse_fun p)))) |
142 (insts, concl_insts) |
184 (insts, concl_insts) |
143 |> of_rule thm |> map ((fn (xi, (nm, tok)) => embed_indexname ((xi, nm), tok)))); |
185 |> of_rule thm |> map ((fn (xi, (nm, f)) => embed_indexname ((xi, nm), f))), fixes)) |
144 in |
186 else |
145 (insts', fixes) |
187 let val result = close_unchecked_insts context ((insts, concl_insts), fixes); |
146 end; |
188 in fn _ => result end; |
147 |
189 |
148 fun read_instantiate_closed ctxt ((Named_Insts insts), fixes) thm = |
190 |
|
191 fun read_instantiate_closed ctxt (Named_Insts (insts, fixes)) thm = |
149 let |
192 let |
150 val insts' = map (fn ((v, t), _) => ((v, Position.none), t)) insts; |
193 val insts' = map (fn ((v, t), _) => ((v, Position.none), t)) insts; |
151 |
194 |
152 val (thm_insts, thm') = add_thm_insts thm |
195 val (thm_insts, thm') = add_thm_insts thm |
153 val (thm'', thm_insts') = |
196 val (thm'', thm_insts') = |
168 SOME t => f t |
211 SOME t => f t |
169 | NONE => error "Lost indexname in instantiated theorem"))) insts; |
212 | NONE => error "Lost indexname in instantiated theorem"))) insts; |
170 in |
213 in |
171 (thm'' |> restore_tags thm) |
214 (thm'' |> restore_tags thm) |
172 end |
215 end |
173 | read_instantiate_closed _ ((Term_Insts insts), _) thm = instantiate_xis insts thm; |
216 | read_instantiate_closed ctxt (Unchecked_Term_Insts insts) thm = |
174 |
217 let |
175 val parse_all : Token.T list context_parser = Scan.lift (Scan.many Token.not_eof); |
218 val (xis, ts) = ListPair.unzip (of_rule thm insts); |
|
219 val ctxt' = Variable.declare_maxidx (Thm.maxidx_of thm) ctxt; |
|
220 val (ts', ctxt'') = Variable.import_terms false ts ctxt'; |
|
221 val ts'' = Variable.export_terms ctxt'' ctxt ts'; |
|
222 val insts' = ListPair.zip (xis, ts''); |
|
223 in instantiate_xis insts' thm end |
|
224 | read_instantiate_closed _ (Term_Insts insts) thm = instantiate_xis insts thm; |
176 |
225 |
177 val _ = |
226 val _ = |
178 Theory.setup |
227 Theory.setup |
179 (Attrib.setup @{binding "where"} (parse_all >> |
228 (Attrib.setup @{binding "where"} |
180 (fn toks => Thm.rule_attribute (fn context => |
229 (Scan.lift |
181 read_instantiate_closed (Context.proof_of context) (read_where_insts toks)))) |
230 (Parse.and_list1 (Args.var -- (Args.$$$ "=" |-- Parse_Tools.name_term)) -- Parse.for_fixes) |
|
231 >> (fn args => let val args' = read_where_insts args in Thm.rule_attribute (fn context => |
|
232 read_instantiate_closed (Context.proof_of context) args') end)) |
182 "named instantiation of theorem"); |
233 "named instantiation of theorem"); |
183 |
234 |
184 val _ = |
235 val _ = |
185 Theory.setup |
236 Theory.setup |
186 (Attrib.setup @{binding "of"} (parse_all >> |
237 (Attrib.setup @{binding "of"} |
187 (fn toks => Thm.rule_attribute (fn context => fn thm => |
238 (Scan.lift |
188 read_instantiate_closed (Context.proof_of context) (read_of_insts toks thm) thm))) |
239 (Args.mode "unchecked" -- |
|
240 (Scan.repeat (Scan.unless concl inst) -- |
|
241 Scan.optional (concl |-- Scan.repeat inst) [] -- |
|
242 Parse.for_fixes)) -- Scan.state >> |
|
243 (fn ((unchecked, args), context) => |
|
244 let |
|
245 val read_insts = read_of_insts (not unchecked) context args; |
|
246 in |
|
247 Thm.rule_attribute (fn context => fn thm => |
|
248 if Method_Closure.is_free_thm thm andalso unchecked |
|
249 then Method_Closure.dummy_free_thm |
|
250 else read_instantiate_closed (Context.proof_of context) (read_insts thm) thm) |
|
251 end)) |
189 "positional instantiation of theorem"); |
252 "positional instantiation of theorem"); |
190 |
253 |
191 end; |
254 end; |