2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Tobias Nipkow |
3 Author: Tobias Nipkow |
4 Copyright 1995 TU Munich |
4 Copyright 1995 TU Munich |
5 |
5 |
6 Generic case-splitter, suitable for most logics. |
6 Generic case-splitter, suitable for most logics. |
|
7 Deals with equalities of the form ?P(f args) = ... |
|
8 where "f args" must be a first-order term without duplicate variables. |
7 *) |
9 *) |
8 |
10 |
9 infix 4 addsplits delsplits; |
11 infix 4 addsplits delsplits; |
10 |
12 |
11 signature SPLITTER_DATA = |
13 signature SPLITTER_DATA = |
192 n : number of arguments expected by Const(key,...) |
194 n : number of arguments expected by Const(key,...) |
193 Ts : types of parameters |
195 Ts : types of parameters |
194 t : the term to be scanned |
196 t : the term to be scanned |
195 ******************************************************************************) |
197 ******************************************************************************) |
196 |
198 |
|
199 (* Simplified first-order matching; |
|
200 assumes that all Vars in the pattern are distinct; |
|
201 see Pure/pattern.ML for the full version; |
|
202 *) |
|
203 local |
|
204 exception MATCH |
|
205 in |
|
206 fun typ_match tsig args = (Type.typ_match tsig args) |
|
207 handle Type.TYPE_MATCH => raise MATCH; |
|
208 fun fomatch tsig args = |
|
209 let |
|
210 fun mtch tyinsts = fn |
|
211 (Ts,Var(_,T), t) => typ_match tsig (tyinsts, (T, fastype_of1(Ts,t))) |
|
212 | (_,Free (a,T), Free (b,U)) => |
|
213 if a=b then typ_match tsig (tyinsts,(T,U)) else raise MATCH |
|
214 | (_,Const (a,T), Const (b,U)) => |
|
215 if a=b then typ_match tsig (tyinsts,(T,U)) else raise MATCH |
|
216 | (_,Bound i, Bound j) => if i=j then tyinsts else raise MATCH |
|
217 | (Ts,Abs(_,T,t), Abs(_,U,u)) => |
|
218 mtch (typ_match tsig (tyinsts,(T,U))) (U::Ts,t,u) |
|
219 | (Ts, f$t, g$u) => mtch (mtch tyinsts (Ts,f,g)) (Ts, t, u) |
|
220 | _ => raise MATCH |
|
221 in (mtch Vartab.empty args; true) handle MATCH => false end; |
|
222 end |
|
223 |
197 fun split_posns cmap sg Ts t = |
224 fun split_posns cmap sg Ts t = |
198 let |
225 let |
199 val T' = fastype_of1 (Ts, t); |
226 val T' = fastype_of1 (Ts, t); |
200 fun posns Ts pos apsns (Abs (_, T, t)) = |
227 fun posns Ts pos apsns (Abs (_, T, t)) = |
201 let val U = fastype_of1 (T::Ts,t) |
228 let val U = fastype_of1 (T::Ts,t) |
205 val (h, ts) = strip_comb t |
232 val (h, ts) = strip_comb t |
206 fun iter((i, a), t) = (i+1, (posns Ts (i::pos) apsns t) @ a); |
233 fun iter((i, a), t) = (i+1, (posns Ts (i::pos) apsns t) @ a); |
207 val a = case h of |
234 val a = case h of |
208 Const(c, cT) => |
235 Const(c, cT) => |
209 let fun find [] = [] |
236 let fun find [] = [] |
210 | find ((gcT, thm, T, n)::tups) = |
237 | find ((gcT, pat, thm, T, n)::tups) = |
211 if Sign.typ_instance sg (cT, gcT) |
238 let val t2 = list_comb (h, take (n, ts)) |
212 then |
239 in if Sign.typ_instance sg (cT, gcT) |
213 let val t2 = list_comb (h, take (n, ts)) |
240 andalso fomatch (Sign.tsig_of sg) (Ts,pat,t2) |
214 in mk_split_pack(thm,T,T',n,ts,apsns,pos,type_of1(Ts,t2),t2) |
241 then mk_split_pack(thm,T,T',n,ts,apsns,pos,type_of1(Ts,t2),t2) |
215 end |
242 else find tups |
216 else find tups |
243 end |
217 in find (assocs cmap c) end |
244 in find (assocs cmap c) end |
218 | _ => [] |
245 | _ => [] |
219 in snd(foldl iter ((0, a), ts)) end |
246 in snd(foldl iter ((0, a), ts)) end |
220 in posns Ts [] [] t end; |
247 in posns Ts [] [] t end; |
221 |
248 |
302 | split_tac splits i = |
329 | split_tac splits i = |
303 let val splits = map Data.mk_eq splits; |
330 let val splits = map Data.mk_eq splits; |
304 fun add_thm(cmap,thm) = |
331 fun add_thm(cmap,thm) = |
305 (case concl_of thm of _$(t as _$lhs)$_ => |
332 (case concl_of thm of _$(t as _$lhs)$_ => |
306 (case strip_comb lhs of (Const(a,aT),args) => |
333 (case strip_comb lhs of (Const(a,aT),args) => |
307 let val info = (aT,thm,fastype_of t,length args) |
334 let val info = (aT,lhs,thm,fastype_of t,length args) |
308 in case assoc(cmap,a) of |
335 in case assoc(cmap,a) of |
309 Some infos => overwrite(cmap,(a,info::infos)) |
336 Some infos => overwrite(cmap,(a,info::infos)) |
310 | None => (a,[info])::cmap |
337 | None => (a,[info])::cmap |
311 end |
338 end |
312 | _ => split_format_err()) |
339 | _ => split_format_err()) |