67 P(...) == rhs |
69 P(...) == rhs |
68 |
70 |
69 Ts : types of parameters (i.e. variables bound by meta-quantifiers) |
71 Ts : types of parameters (i.e. variables bound by meta-quantifiers) |
70 t : lefthand side of meta-equality in subgoal |
72 t : lefthand side of meta-equality in subgoal |
71 the split theorem is applied to (see select) |
73 the split theorem is applied to (see select) |
72 pos : "path" leading to body of P(...), coded as a list |
|
73 T : type of body of P(...) |
74 T : type of body of P(...) |
|
75 tt : the term Const(..,..) $ ... |
74 maxi : maximum index of Vars |
76 maxi : maximum index of Vars |
75 |
77 |
76 bvars : type of variables bound by other than meta-quantifiers |
78 lev : abstraction level |
77 *************************************************************************) |
79 *************************************************************************) |
78 |
80 |
79 fun mk_cntxt_splitthm Ts t pos T maxi = |
81 fun mk_cntxt_splitthm Ts t tt T maxi = |
80 let fun down [] t i bvars = Bound (length bvars) |
82 let fun down lev (Abs(v,T2,t)) = Abs(v,T2,down (lev+1) t) |
81 | down (p::ps) (Abs(v,T2,t)) i bvars = Abs(v,T2,down ps t i (T2::bvars)) |
83 | down lev (Bound i) = if i >= lev |
82 | down (p::ps) t i bvars = |
84 then Var(("X",maxi+i-lev),nth_elem(i-lev,Ts)) |
83 let val vars = map Bound (0 upto ((length bvars)-1)) |
85 else Bound i |
84 val (h,ts) = strip_comb t |
86 | down lev t = |
85 fun var (t,i) = list_comb(Var(("X",i),bvars ---> (type_of1(bvars @ Ts,t))),vars); |
87 let val (h,ts) = strip_comb t |
86 val v1 = map var (take(p,ts) ~~ (i upto (i+p-1))) |
88 val h2 = (case h of Bound _ => down lev h | _ => h) |
87 val u::us = drop(p,ts) |
89 in if incr_bv(lev,0,tt)=t |
88 val v2 = map var (us ~~ ((i+p) upto (i+length(ts)-2))) |
90 then |
89 in list_comb(h,v1@[down ps u (i+length ts) bvars]@v2) end; |
91 Bound (lev) |
90 in Abs("",T,down (rev pos) t maxi []) end; |
92 else |
|
93 list_comb(h2,map (down lev) ts) |
|
94 end; |
|
95 in Abs("",T,down 0 t) end; |
91 |
96 |
92 |
97 |
93 (* add all loose bound variables in t to list is *) |
98 (* add all loose bound variables in t to list is *) |
94 fun add_lbnos(is,t) = add_loose_bnos(t,0,is); |
99 fun add_lbnos(is,t) = add_loose_bnos(t,0,is); |
95 |
100 |
115 T : type of the variable bound by the abstraction |
120 T : type of the variable bound by the abstraction |
116 U : type of the abstraction's body |
121 U : type of the abstraction's body |
117 pos : "path" leading to the body of the abstraction |
122 pos : "path" leading to the body of the abstraction |
118 pos : "path" leading to the position where Const(key, ...) $ ... occurs. |
123 pos : "path" leading to the position where Const(key, ...) $ ... occurs. |
119 TB : type of Const(key,...) $ t_1 $ ... $ t_n |
124 TB : type of Const(key,...) $ t_1 $ ... $ t_n |
|
125 t : the term Const(key,...) $ t_1 $ ... $ t_n |
120 |
126 |
121 A split pack is a tuple of the form |
127 A split pack is a tuple of the form |
122 (thm, apsns, pos, TB) |
128 (thm, apsns, pos, TB) |
123 Note : apsns is reversed, so that the outermost quantifier's position |
129 Note : apsns is reversed, so that the outermost quantifier's position |
124 comes first ! If the terms in ts don't contain variables bound |
130 comes first ! If the terms in ts don't contain variables bound |
125 by other than meta-quantifiers, apsns is empty, because no further |
131 by other than meta-quantifiers, apsns is empty, because no further |
126 lifting is required before applying the split-theorem. |
132 lifting is required before applying the split-theorem. |
127 ******************************************************************************) |
133 ******************************************************************************) |
128 |
134 |
129 fun mk_split_pack(thm,T,n,ts,apsns,pos,TB) = |
135 fun mk_split_pack(thm,T,n,ts,apsns,pos,TB,t) = |
130 if n > length ts then [] |
136 if n > length ts then [] |
131 else let val lev = length apsns |
137 else let val lev = length apsns |
132 val lbnos = foldl add_lbnos ([],take(n,ts)) |
138 val lbnos = foldl add_lbnos ([],take(n,ts)) |
133 val flbnos = filter (fn i => i < lev) lbnos |
139 val flbnos = filter (fn i => i < lev) lbnos |
134 in if null flbnos then [(thm,[],pos,TB)] |
140 val tt = incr_bv(~lev,0,t) |
135 else if type_test(T,flbnos,apsns) then [(thm, rev apsns,pos,TB)] else [] |
141 in if null flbnos then [(thm,[],pos,TB,tt)] |
|
142 else if type_test(T,flbnos,apsns) then [(thm, rev apsns,pos,TB,tt)] else [] |
136 end; |
143 end; |
137 |
144 |
138 |
145 |
139 (**************************************************************************** |
146 (**************************************************************************** |
140 Recursively scans term for occurences of Const(key,...) $ ... |
147 Recursively scans term for occurences of Const(key,...) $ ... |
158 let val (h,ts) = strip_comb t |
165 let val (h,ts) = strip_comb t |
159 fun iter((i,a),t) = (i+1, (posns Ts (i::pos) apsns t) @ a); |
166 fun iter((i,a),t) = (i+1, (posns Ts (i::pos) apsns t) @ a); |
160 val a = case h of |
167 val a = case h of |
161 Const(c,_) => |
168 Const(c,_) => |
162 (case assoc(cmap,c) of |
169 (case assoc(cmap,c) of |
163 Some(thm,T,n) => mk_split_pack(thm,T,n,ts,apsns,pos,type_of1(Ts,t)) |
170 Some(thm,T,n) => mk_split_pack(thm,T,n,ts,apsns,pos,type_of1(Ts,t),t) |
164 | None => []) |
171 | None => []) |
165 | _ => [] |
172 | _ => [] |
166 in snd(foldl iter ((0,a),ts)) end |
173 in snd(foldl iter ((0,a),ts)) end |
167 in posns Ts [] [] t end; |
174 in posns Ts [] [] t end; |
168 |
175 |
169 |
176 |
170 fun nth_subgoal i thm = nth_elem(i-1,prems_of thm); |
177 fun nth_subgoal i thm = nth_elem(i-1,prems_of thm); |
171 |
178 |
172 fun shorter((_,ps,pos,_),(_,qs,qos,_)) = |
179 fun shorter((_,ps,pos,_,_),(_,qs,qos,_,_)) = |
173 let val ms = length ps and ns = length qs |
180 let val ms = length ps and ns = length qs |
174 in ms < ns orelse (ms = ns andalso length pos >= length qos) end; |
181 in ms < ns orelse (ms = ns andalso order(length pos,length qos)) end; |
175 |
182 |
176 |
183 |
177 (************************************************************ |
184 (************************************************************ |
178 call split_posns with appropriate parameters |
185 call split_posns with appropriate parameters |
179 *************************************************************) |
186 *************************************************************) |
225 thm : the split theorem |
232 thm : the split theorem |
226 TB : type of body of P(...) |
233 TB : type of body of P(...) |
227 state : current proof state |
234 state : current proof state |
228 **************************************************************) |
235 **************************************************************) |
229 |
236 |
230 fun inst_split Ts t pos thm TB state = |
237 fun inst_split Ts t tt thm TB state = |
231 let val _$((Var(P2,PT2))$_)$_ = concl_of thm |
238 let val _$((Var(P2,PT2))$_)$_ = concl_of thm |
232 val sg = #sign(rep_thm state) |
239 val sg = #sign(rep_thm state) |
233 val tsig = #tsig(Sign.rep_sg sg) |
240 val tsig = #tsig(Sign.rep_sg sg) |
234 val cntxt = mk_cntxt_splitthm Ts t pos TB (#maxidx(rep_thm thm)) |
241 val cntxt = mk_cntxt_splitthm Ts t tt TB (#maxidx(rep_thm thm)) |
235 val cu = cterm_of sg cntxt |
242 val cu = cterm_of sg cntxt |
236 val uT = #T(rep_cterm cu) |
243 val uT = #T(rep_cterm cu) |
237 val cP' = cterm_of sg (Var(P2,uT)) |
244 val cP' = cterm_of sg (Var(P2,uT)) |
238 val ixnTs = Type.typ_match tsig ([],(PT2,uT)); |
245 val ixnTs = Type.typ_match tsig ([],(PT2,uT)); |
239 val ixncTs = map (fn (x,y) => (x,ctyp_of sg y)) ixnTs; |
246 val ixncTs = map (fn (x,y) => (x,ctyp_of sg y)) ixnTs; |
256 fun lift Ts t p state = rtac (inst_lift Ts t p state trlift i) i |
263 fun lift Ts t p state = rtac (inst_lift Ts t p state trlift i) i |
257 fun lift_split state = |
264 fun lift_split state = |
258 let val (Ts,t,splits) = select cmap state i |
265 let val (Ts,t,splits) = select cmap state i |
259 in case splits of |
266 in case splits of |
260 [] => no_tac |
267 [] => no_tac |
261 | (thm,apsns,pos,TB)::_ => |
268 | (thm,apsns,pos,TB,tt)::_ => |
262 (case apsns of |
269 (case apsns of |
263 [] => STATE(fn state => rtac (inst_split Ts t pos thm TB state) i) |
270 [] => STATE(fn state => rtac (inst_split Ts t tt thm TB state) i) |
264 | p::_ => EVERY[STATE(lift Ts t p), |
271 | p::_ => EVERY[STATE(lift Ts t p), |
265 rtac reflexive_thm (i+1), |
272 rtac reflexive_thm (i+1), |
266 STATE lift_split]) |
273 STATE lift_split]) |
267 end |
274 end |
268 in STATE(fn thm => |
275 in STATE(fn thm => |
269 if i <= nprems_of thm then rtac iffD i THEN STATE lift_split |
276 if i <= nprems_of thm then rtac iffD i THEN STATE lift_split |
270 else no_tac) |
277 else no_tac) |
271 end; |
278 end; |
272 |
279 |
273 in split_tac end; |
280 in split_tac end; |
|
281 |
|
282 in |
|
283 |
|
284 fun mk_case_split_tac iffD = mk_case_split_tac_2 iffD (op <=) ; |
|
285 |
|
286 fun mk_case_split_inside_tac iffD = mk_case_split_tac_2 iffD (op >=) ; |
|
287 |
|
288 end; |