src/HOL/Prod.ML
changeset 4534 6932c3ae3912
parent 4521 c7f56322a84b
child 4650 91af1ef45d68
equal deleted inserted replaced
4533:05ecfa08fefa 4534:6932c3ae3912
    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);