34 by (blast_tac (claset() addSEs [Pair_inject]) 1); |
34 by (blast_tac (claset() addSEs [Pair_inject]) 1); |
35 qed "Pair_eq"; |
35 qed "Pair_eq"; |
36 AddIffs [Pair_eq]; |
36 AddIffs [Pair_eq]; |
37 |
37 |
38 goalw Prod.thy [fst_def] "fst((a,b)) = a"; |
38 goalw Prod.thy [fst_def] "fst((a,b)) = a"; |
39 by (blast_tac (claset() addIs [select_equality]) 1); |
39 by (Blast_tac 1); |
40 qed "fst_conv"; |
40 qed "fst_conv"; |
41 |
|
42 goalw Prod.thy [snd_def] "snd((a,b)) = b"; |
41 goalw Prod.thy [snd_def] "snd((a,b)) = b"; |
43 by (blast_tac (claset() addIs [select_equality]) 1); |
42 by (Blast_tac 1); |
44 qed "snd_conv"; |
43 qed "snd_conv"; |
|
44 Addsimps [fst_conv, snd_conv]; |
45 |
45 |
46 goalw Prod.thy [Pair_def] "? x y. p = (x,y)"; |
46 goalw Prod.thy [Pair_def] "? x y. p = (x,y)"; |
47 by (rtac (rewrite_rule [Prod_def] Rep_Prod RS CollectE) 1); |
47 by (rtac (rewrite_rule [Prod_def] Rep_Prod RS CollectE) 1); |
48 by (EVERY1[etac exE, etac exE, rtac exI, rtac exI, |
48 by (EVERY1[etac exE, etac exE, rtac exI, rtac exI, |
49 rtac (Rep_Prod_inverse RS sym RS trans), etac arg_cong]); |
49 rtac (Rep_Prod_inverse RS sym RS trans), etac arg_cong]); |
126 (* AddIffs is not a good idea because it makes Blast_tac loop *) |
126 (* AddIffs is not a good idea because it makes Blast_tac loop *) |
127 |
127 |
128 goal Prod.thy "(? x. P x) = (? a b. P(a,b))"; |
128 goal Prod.thy "(? x. P x) = (? a b. P(a,b))"; |
129 by (fast_tac (claset() addbefore split_all_tac) 1); |
129 by (fast_tac (claset() addbefore split_all_tac) 1); |
130 qed "split_paired_Ex"; |
130 qed "split_paired_Ex"; |
131 (* Addsimps [split_paired_Ex]; breaks a number of IOA proofs *) |
131 Addsimps [split_paired_Ex]; |
132 |
132 |
133 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"; |
134 by (EVERY1[stac fst_conv, stac snd_conv]); |
134 by (Simp_tac 1); |
135 by (rtac refl 1); |
|
136 qed "split"; |
135 qed "split"; |
137 |
136 Addsimps [split]; |
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 |
|
141 Addsimps [fst_conv, snd_conv, split]; |
|
142 |
137 |
143 goal Prod.thy "(s=t) = (fst(s)=fst(t) & snd(s)=snd(t))"; |
138 goal Prod.thy "(s=t) = (fst(s)=fst(t) & snd(s)=snd(t))"; |
144 by (res_inst_tac[("p","s")] PairE 1); |
139 by (res_inst_tac[("p","s")] PairE 1); |
145 by (res_inst_tac[("p","t")] PairE 1); |
140 by (res_inst_tac[("p","t")] PairE 1); |
146 by (Asm_simp_tac 1); |
141 by (Asm_simp_tac 1); |
165 val surj_pair = prove_goal Prod.thy "? x y. z = (x, y)" (K [ |
160 val surj_pair = prove_goal Prod.thy "? x y. z = (x, y)" (K [ |
166 rtac exI 1, rtac exI 1, rtac surjective_pairing 1]); |
161 rtac exI 1, rtac exI 1, rtac surjective_pairing 1]); |
167 Addsimps [surj_pair]; |
162 Addsimps [surj_pair]; |
168 |
163 |
169 qed_goal "split_eta" Prod.thy "(%(x,y). f(x,y)) = f" |
164 qed_goal "split_eta" Prod.thy "(%(x,y). f(x,y)) = f" |
170 (fn _ => [rtac ext 1, split_all_tac 1, rtac split 1]); |
165 (K [rtac ext 1, split_all_tac 1, rtac split 1]); |
171 |
166 |
172 val split_beta = prove_goal Prod.thy "(%(x,y). P x y) z = P (fst z) (snd z)" |
167 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]); |
168 (K [stac surjective_pairing 1, stac split 1, rtac refl 1]); |
174 |
169 |
175 (*For use with split_tac and the simplifier*) |
170 (*For use with split_tac and the simplifier*) |
176 goal Prod.thy "R (split c p) = (! x y. p = (x,y) --> R (c x y))"; |
171 goal Prod.thy "R (split c p) = (! x y. p = (x,y) --> R (c x y))"; |
177 by (stac surjective_pairing 1); |
172 by (stac surjective_pairing 1); |
178 by (stac split 1); |
173 by (stac split 1); |
233 by (REPEAT (resolve_tac (prems@[surjective_pairing]) 1)); |
228 by (REPEAT (resolve_tac (prems@[surjective_pairing]) 1)); |
234 qed "mem_splitE"; |
229 qed "mem_splitE"; |
235 |
230 |
236 AddSIs [splitI, splitI2, mem_splitI, mem_splitI2]; |
231 AddSIs [splitI, splitI2, mem_splitI, mem_splitI2]; |
237 AddSEs [splitE, mem_splitE]; |
232 AddSEs [splitE, mem_splitE]; |
|
233 |
|
234 (* allows simplifications of nested splits in case of independent predicates *) |
|
235 goal Prod.thy "(%(a,b). P & Q a b) = (%ab. P & split Q ab)"; |
|
236 by (rtac ext 1); |
|
237 by (Blast_tac 1); |
|
238 qed "split_part"; |
|
239 Addsimps [split_part]; |
|
240 |
|
241 goal Prod.thy "(@(x',y'). x = x' & y = y') = (x,y)"; |
|
242 by (Blast_tac 1); |
|
243 qed "Eps_split_eq"; |
|
244 Addsimps [Eps_split_eq]; |
|
245 (* |
|
246 the following would be slightly more general, |
|
247 but cannot be used as rewrite rule: |
|
248 ### Cannot add premise as rewrite rule because it contains (type) unknowns: |
|
249 ### ?y = .x |
|
250 goal Prod.thy "!!P. [| P y; !!x. P x ==> x = y |] ==> (@(x',y). x = x' & P y) = (x,y)"; |
|
251 by (rtac select_equality 1); |
|
252 by ( Simp_tac 1); |
|
253 by (split_all_tac 1); |
|
254 by (Asm_full_simp_tac 1); |
|
255 qed "Eps_split_eq"; |
|
256 *) |
238 |
257 |
239 (*** prod_fun -- action of the product functor upon functions ***) |
258 (*** prod_fun -- action of the product functor upon functions ***) |
240 |
259 |
241 goalw Prod.thy [prod_fun_def] "prod_fun f g (a,b) = (f(a),g(b))"; |
260 goalw Prod.thy [prod_fun_def] "prod_fun f g (a,b) = (f(a),g(b))"; |
242 by (rtac split 1); |
261 by (rtac split 1); |
330 goal Prod.thy "((a,b): Sigma A B) = (a:A & b:B(a))"; |
349 goal Prod.thy "((a,b): Sigma A B) = (a:A & b:B(a))"; |
331 by (Blast_tac 1); |
350 by (Blast_tac 1); |
332 qed "mem_Sigma_iff"; |
351 qed "mem_Sigma_iff"; |
333 AddIffs [mem_Sigma_iff]; |
352 AddIffs [mem_Sigma_iff]; |
334 |
353 |
335 val Collect_Prod = prove_goal Prod.thy |
354 val Collect_split = prove_goal Prod.thy |
336 "{(a,b). P a & Q b} = Collect P Times Collect Q" (K [Blast_tac 1]); |
355 "{(a,b). P a & Q b} = Collect P Times Collect Q" (K [Blast_tac 1]); |
337 Addsimps [Collect_Prod]; |
356 Addsimps [Collect_split]; |
338 |
357 |
339 (*Suggested by Pierre Chartier*) |
358 (*Suggested by Pierre Chartier*) |
340 goal Prod.thy |
359 goal Prod.thy |
341 "(UN (a,b):(A Times B). E a Times F b) = (UNION A E) Times (UNION B F)"; |
360 "(UN (a,b):(A Times B). E a Times F b) = (UNION A E) Times (UNION B F)"; |
342 by (Blast_tac 1); |
361 by (Blast_tac 1); |