51 |
51 |
52 val [prem] = goal Prod.thy "[| !!x y. p = (x,y) ==> Q |] ==> Q"; |
52 val [prem] = goal Prod.thy "[| !!x y. p = (x,y) ==> Q |] ==> Q"; |
53 by (rtac (PairE_lemma RS exE) 1); |
53 by (rtac (PairE_lemma RS exE) 1); |
54 by (REPEAT (eresolve_tac [prem,exE] 1)); |
54 by (REPEAT (eresolve_tac [prem,exE] 1)); |
55 qed "PairE"; |
55 qed "PairE"; |
|
56 |
|
57 fun pair_tac s = res_inst_tac [("p",s)] PairE THEN' hyp_subst_tac; |
56 |
58 |
57 (* replace parameters of product type by individual component parameters *) |
59 (* replace parameters of product type by individual component parameters *) |
58 local |
60 local |
59 fun is_pair (_,Type("*",_)) = true |
61 fun is_pair (_,Type("*",_)) = true |
60 | is_pair _ = false; |
62 | is_pair _ = false; |
131 goalw Prod.thy [split_def] "split c (a,b) = c a b"; |
133 goalw Prod.thy [split_def] "split c (a,b) = c a b"; |
132 by (EVERY1[stac fst_conv, stac snd_conv]); |
134 by (EVERY1[stac fst_conv, stac snd_conv]); |
133 by (rtac refl 1); |
135 by (rtac refl 1); |
134 qed "split"; |
136 qed "split"; |
135 |
137 |
|
138 val split_select = prove_goalw Prod.thy [split_def] |
|
139 "(®(x,y). P x y) = (®xy. P (fst xy) (snd xy))" (K [rtac refl 1]); |
|
140 |
136 Addsimps [fst_conv, snd_conv, split]; |
141 Addsimps [fst_conv, snd_conv, split]; |
137 |
142 |
138 goal Prod.thy "(s=t) = (fst(s)=fst(t) & snd(s)=snd(t))"; |
143 goal Prod.thy "(s=t) = (fst(s)=fst(t) & snd(s)=snd(t))"; |
139 by (res_inst_tac[("p","s")] PairE 1); |
144 by (res_inst_tac[("p","s")] PairE 1); |
140 by (res_inst_tac[("p","t")] PairE 1); |
145 by (res_inst_tac[("p","t")] PairE 1); |
155 goal Prod.thy "p = split (%x y.(x,y)) p"; |
160 goal Prod.thy "p = split (%x y.(x,y)) p"; |
156 by (res_inst_tac [("p","p")] PairE 1); |
161 by (res_inst_tac [("p","p")] PairE 1); |
157 by (Asm_simp_tac 1); |
162 by (Asm_simp_tac 1); |
158 qed "surjective_pairing2"; |
163 qed "surjective_pairing2"; |
159 |
164 |
|
165 val surj_pair = prove_goal Prod.thy "? x y. z = (x, y)" (K [ |
|
166 rtac exI 1, rtac exI 1, rtac surjective_pairing 1]); |
|
167 Addsimps [surj_pair]; |
|
168 |
160 qed_goal "split_eta" Prod.thy "(%(x,y). f(x,y)) = f" |
169 qed_goal "split_eta" Prod.thy "(%(x,y). f(x,y)) = f" |
161 (fn _ => [rtac ext 1, split_all_tac 1, rtac split 1]); |
170 (fn _ => [rtac ext 1, split_all_tac 1, rtac split 1]); |
|
171 |
|
172 val split_beta = prove_goal Prod.thy "(%(x,y). P x y) z = P (fst z) (snd z)" |
|
173 (fn _ => [stac surjective_pairing 1, stac split 1, rtac refl 1]); |
162 |
174 |
163 (*For use with split_tac and the simplifier*) |
175 (*For use with split_tac and the simplifier*) |
164 goal Prod.thy "R(split c p) = (! x y. p = (x,y) --> R(c x y))"; |
176 goal Prod.thy "R(split c p) = (! x y. p = (x,y) --> R(c x y))"; |
165 by (stac surjective_pairing 1); |
177 by (stac surjective_pairing 1); |
166 by (stac split 1); |
178 by (stac split 1); |
189 |
201 |
190 val prems = goalw Prod.thy [split_def] |
202 val prems = goalw Prod.thy [split_def] |
191 "[| split c p; !!x y. [| p = (x,y); c x y |] ==> Q |] ==> Q"; |
203 "[| split c p; !!x y. [| p = (x,y); c x y |] ==> Q |] ==> Q"; |
192 by (REPEAT (resolve_tac (prems@[surjective_pairing]) 1)); |
204 by (REPEAT (resolve_tac (prems@[surjective_pairing]) 1)); |
193 qed "splitE"; |
205 qed "splitE"; |
|
206 |
|
207 val splitE2 = prove_goal Prod.thy |
|
208 "[|Q (split P z); !!x y. [|z = (x, y); Q (P x y)|] ==> R|] ==> R" (fn prems => [ |
|
209 REPEAT (resolve_tac (prems@[surjective_pairing]) 1), |
|
210 rtac (split_beta RS subst) 1, |
|
211 rtac (hd prems) 1]); |
194 |
212 |
195 goal Prod.thy "!!R a b. split R (a,b) ==> R a b"; |
213 goal Prod.thy "!!R a b. split R (a,b) ==> R a b"; |
196 by (etac (split RS iffD1) 1); |
214 by (etac (split RS iffD1) 1); |
197 qed "splitD"; |
215 qed "splitD"; |
198 |
216 |
304 goal Prod.thy "((a,b): Sigma A B) = (a:A & b:B(a))"; |
322 goal Prod.thy "((a,b): Sigma A B) = (a:A & b:B(a))"; |
305 by (Blast_tac 1); |
323 by (Blast_tac 1); |
306 qed "mem_Sigma_iff"; |
324 qed "mem_Sigma_iff"; |
307 AddIffs [mem_Sigma_iff]; |
325 AddIffs [mem_Sigma_iff]; |
308 |
326 |
|
327 val Collect_Prod = prove_goal Prod.thy |
|
328 "{(a,b). P a & Q b} = Collect P Times Collect Q" (K [Blast_tac 1]); |
|
329 Addsimps [Collect_Prod]; |
309 |
330 |
310 (*Suggested by Pierre Chartier*) |
331 (*Suggested by Pierre Chartier*) |
311 goal Prod.thy |
332 goal Prod.thy |
312 "(UN (a,b):(A Times B). E a Times F b) = (UNION A E) Times (UNION B F)"; |
333 "(UN (a,b):(A Times B). E a Times F b) = (UNION A E) Times (UNION B F)"; |
313 by (Blast_tac 1); |
334 by (Blast_tac 1); |