src/HOL/Product_Type.thy
changeset 14208 144f45277d5a
parent 14190 609c072edf90
child 14337 e13731554e50
equal deleted inserted replaced
14207:f20fbb141673 14208:144f45277d5a
   152 lemma ProdI: "Pair_Rep a b : Prod"
   152 lemma ProdI: "Pair_Rep a b : Prod"
   153   by (unfold Prod_def) blast
   153   by (unfold Prod_def) blast
   154 
   154 
   155 lemma Pair_Rep_inject: "Pair_Rep a b = Pair_Rep a' b' ==> a = a' & b = b'"
   155 lemma Pair_Rep_inject: "Pair_Rep a b = Pair_Rep a' b' ==> a = a' & b = b'"
   156   apply (unfold Pair_Rep_def)
   156   apply (unfold Pair_Rep_def)
   157   apply (drule fun_cong [THEN fun_cong])
   157   apply (drule fun_cong [THEN fun_cong], blast)
   158   apply blast
       
   159   done
   158   done
   160 
   159 
   161 lemma inj_on_Abs_Prod: "inj_on Abs_Prod Prod"
   160 lemma inj_on_Abs_Prod: "inj_on Abs_Prod Prod"
   162   apply (rule inj_on_inverseI)
   161   apply (rule inj_on_inverseI)
   163   apply (erule Abs_Prod_inverse)
   162   apply (erule Abs_Prod_inverse)
   300 lemmas splitD = split_conv [THEN iffD1, standard]
   299 lemmas splitD = split_conv [THEN iffD1, standard]
   301 
   300 
   302 lemma split_Pair_apply: "split (%x y. f (x, y)) = f"
   301 lemma split_Pair_apply: "split (%x y. f (x, y)) = f"
   303   -- {* Subsumes the old @{text split_Pair} when @{term f} is the identity function. *}
   302   -- {* Subsumes the old @{text split_Pair} when @{term f} is the identity function. *}
   304   apply (rule ext)
   303   apply (rule ext)
   305   apply (tactic {* pair_tac "x" 1 *})
   304   apply (tactic {* pair_tac "x" 1 *}, simp)
   306   apply simp
       
   307   done
   305   done
   308 
   306 
   309 lemma split_paired_The: "(THE x. P x) = (THE (a, b). P (a, b))"
   307 lemma split_paired_The: "(THE x. P x) = (THE (a, b). P (a, b))"
   310   -- {* Can't be added to simpset: loops! *}
   308   -- {* Can't be added to simpset: loops! *}
   311   by (simp add: split_Pair_apply)
   309   by (simp add: split_Pair_apply)
   312 
   310 
   313 lemma The_split: "The (split P) = (THE xy. P (fst xy) (snd xy))"
   311 lemma The_split: "The (split P) = (THE xy. P (fst xy) (snd xy))"
   314   by (simp add: split_def)
   312   by (simp add: split_def)
   315 
   313 
   316 lemma Pair_fst_snd_eq: "!!s t. (s = t) = (fst s = fst t & snd s = snd t)"
   314 lemma Pair_fst_snd_eq: "!!s t. (s = t) = (fst s = fst t & snd s = snd t)"
   317   apply (simp only: split_tupled_all)
   315 by (simp only: split_tupled_all, simp)
   318   apply simp
       
   319   done
       
   320 
   316 
   321 lemma prod_eqI [intro?]: "fst p = fst q ==> snd p = snd q ==> p = q"
   317 lemma prod_eqI [intro?]: "fst p = fst q ==> snd p = snd q ==> p = q"
   322   by (simp add: Pair_fst_snd_eq)
   318   by (simp add: Pair_fst_snd_eq)
   323 
   319 
   324 lemma split_weak_cong: "p = q ==> split c p = split c q"
   320 lemma split_weak_cong: "p = q ==> split c p = split c q"
   394   by (subst surjective_pairing, rule split_conv)
   390   by (subst surjective_pairing, rule split_conv)
   395 
   391 
   396 lemma split_split: "R (split c p) = (ALL x y. p = (x, y) --> R (c x y))"
   392 lemma split_split: "R (split c p) = (ALL x y. p = (x, y) --> R (c x y))"
   397   -- {* For use with @{text split} and the Simplifier. *}
   393   -- {* For use with @{text split} and the Simplifier. *}
   398   apply (subst surjective_pairing)
   394   apply (subst surjective_pairing)
   399   apply (subst split_conv)
   395   apply (subst split_conv, blast)
   400   apply blast
       
   401   done
   396   done
   402 
   397 
   403 text {*
   398 text {*
   404   @{thm [source] split_split} could be declared as @{text "[split]"}
   399   @{thm [source] split_split} could be declared as @{text "[split]"}
   405   done after the Splitter has been speeded up significantly;
   400   done after the Splitter has been speeded up significantly;
   406   precompute the constants involved and don't do anything unless the
   401   precompute the constants involved and don't do anything unless the
   407   current goal contains one of those constants.
   402   current goal contains one of those constants.
   408 *}
   403 *}
   409 
   404 
   410 lemma split_split_asm: "R (split c p) = (~(EX x y. p = (x, y) & (~R (c x y))))"
   405 lemma split_split_asm: "R (split c p) = (~(EX x y. p = (x, y) & (~R (c x y))))"
   411   apply (subst split_split)
   406 by (subst split_split, simp)
   412   apply simp
       
   413   done
       
   414 
   407 
   415 
   408 
   416 text {*
   409 text {*
   417   \medskip @{term split} used as a logical connective or set former.
   410   \medskip @{term split} used as a logical connective or set former.
   418 
   411 
   451 
   444 
   452 lemma mem_splitI: "z: c a b ==> z: split c (a, b)"
   445 lemma mem_splitI: "z: c a b ==> z: split c (a, b)"
   453   by simp
   446   by simp
   454 
   447 
   455 lemma mem_splitI2: "!!p. [| !!a b. p = (a, b) ==> z: c a b |] ==> z: split c p"
   448 lemma mem_splitI2: "!!p. [| !!a b. p = (a, b) ==> z: c a b |] ==> z: split c p"
   456   apply (simp only: split_tupled_all)
   449 by (simp only: split_tupled_all, simp)
   457   apply simp
       
   458   done
       
   459 
   450 
   460 lemma mem_splitE: "[| z: split c p; !!x y. [| p = (x,y); z: c x y |] ==> Q |] ==> Q"
   451 lemma mem_splitE: "[| z: split c p; !!x y. [| p = (x,y); z: c x y |] ==> Q |] ==> Q"
   461 proof -
   452 proof -
   462   case rule_context [unfolded split_def]
   453   case rule_context [unfolded split_def]
   463   show ?thesis by (rule rule_context surjective_pairing)+
   454   show ?thesis by (rule rule_context surjective_pairing)+
   481    to quite time-consuming computations (in particular for nested tuples) *)
   472    to quite time-consuming computations (in particular for nested tuples) *)
   482 claset_ref() := claset() addSbefore (\"split_conv_tac\", split_conv_tac);
   473 claset_ref() := claset() addSbefore (\"split_conv_tac\", split_conv_tac);
   483 "
   474 "
   484 
   475 
   485 lemma split_eta_SetCompr [simp]: "(%u. EX x y. u = (x, y) & P (x, y)) = P"
   476 lemma split_eta_SetCompr [simp]: "(%u. EX x y. u = (x, y) & P (x, y)) = P"
   486   apply (rule ext)
   477 by (rule ext, fast)
   487   apply fast
       
   488   done
       
   489 
   478 
   490 lemma split_eta_SetCompr2 [simp]: "(%u. EX x y. u = (x, y) & P x y) = split P"
   479 lemma split_eta_SetCompr2 [simp]: "(%u. EX x y. u = (x, y) & P x y) = split P"
   491   apply (rule ext)
   480 by (rule ext, fast)
   492   apply fast
       
   493   done
       
   494 
   481 
   495 lemma split_part [simp]: "(%(a,b). P & Q a b) = (%ab. P & split Q ab)"
   482 lemma split_part [simp]: "(%(a,b). P & Q a b) = (%ab. P & split Q ab)"
   496   -- {* Allows simplifications of nested splits in case of independent predicates. *}
   483   -- {* Allows simplifications of nested splits in case of independent predicates. *}
   497   apply (rule ext)
   484   apply (rule ext, blast)
   498   apply blast
       
   499   done
   485   done
   500 
   486 
   501 lemma split_comp_eq [simp]: 
   487 lemma split_comp_eq [simp]: 
   502 "(%u. f (g (fst u)) (snd u)) = (split (%x. f (g x)))"
   488 "(%u. f (g (fst u)) (snd u)) = (split (%x. f (g x)))"
   503 by (rule ext, auto)
   489 by (rule ext, auto)
   509 the following  would be slightly more general,
   495 the following  would be slightly more general,
   510 but cannot be used as rewrite rule:
   496 but cannot be used as rewrite rule:
   511 ### Cannot add premise as rewrite rule because it contains (type) unknowns:
   497 ### Cannot add premise as rewrite rule because it contains (type) unknowns:
   512 ### ?y = .x
   498 ### ?y = .x
   513 Goal "[| P y; !!x. P x ==> x = y |] ==> (@(x',y). x = x' & P y) = (x,y)"
   499 Goal "[| P y; !!x. P x ==> x = y |] ==> (@(x',y). x = x' & P y) = (x,y)"
   514 by (rtac some_equality 1);
   500 by (rtac some_equality 1)
   515 by ( Simp_tac 1);
   501 by ( Simp_tac 1)
   516 by (split_all_tac 1);
   502 by (split_all_tac 1)
   517 by (Asm_full_simp_tac 1);
   503 by (Asm_full_simp_tac 1)
   518 qed "The_split_eq";
   504 qed "The_split_eq";
   519 *)
   505 *)
   520 
   506 
   521 lemma injective_fst_snd: "!!x y. [|fst x = fst y; snd x = snd y|] ==> x = y"
   507 lemma injective_fst_snd: "!!x y. [|fst x = fst y; snd x = snd y|] ==> x = y"
   522   by auto
   508   by auto
   530 lemma prod_fun [simp]: "prod_fun f g (a, b) = (f a, g b)"
   516 lemma prod_fun [simp]: "prod_fun f g (a, b) = (f a, g b)"
   531   by (simp add: prod_fun_def)
   517   by (simp add: prod_fun_def)
   532 
   518 
   533 lemma prod_fun_compose: "prod_fun (f1 o f2) (g1 o g2) = (prod_fun f1 g1 o prod_fun f2 g2)"
   519 lemma prod_fun_compose: "prod_fun (f1 o f2) (g1 o g2) = (prod_fun f1 g1 o prod_fun f2 g2)"
   534   apply (rule ext)
   520   apply (rule ext)
   535   apply (tactic {* pair_tac "x" 1 *})
   521   apply (tactic {* pair_tac "x" 1 *}, simp)
   536   apply simp
       
   537   done
   522   done
   538 
   523 
   539 lemma prod_fun_ident [simp]: "prod_fun (%x. x) (%y. y) = (%z. z)"
   524 lemma prod_fun_ident [simp]: "prod_fun (%x. x) (%y. y) = (%z. z)"
   540   apply (rule ext)
   525   apply (rule ext)
   541   apply (tactic {* pair_tac "z" 1 *})
   526   apply (tactic {* pair_tac "z" 1 *}, simp)
   542   apply simp
       
   543   done
   527   done
   544 
   528 
   545 lemma prod_fun_imageI [intro]: "(a, b) : r ==> (f a, g b) : prod_fun f g ` r"
   529 lemma prod_fun_imageI [intro]: "(a, b) : r ==> (f a, g b) : prod_fun f g ` r"
   546   apply (rule image_eqI)
   530   apply (rule image_eqI)
   547   apply (rule prod_fun [symmetric])
   531   apply (rule prod_fun [symmetric], assumption)
   548   apply assumption
       
   549   done
   532   done
   550 
   533 
   551 lemma prod_fun_imageE [elim!]:
   534 lemma prod_fun_imageE [elim!]:
   552   "[| c: (prod_fun f g)`r;  !!x y. [| c=(f(x),g(y));  (x,y):r |] ==> P
   535   "[| c: (prod_fun f g)`r;  !!x y. [| c=(f(x),g(y));  (x,y):r |] ==> P
   553     |] ==> P"
   536     |] ==> P"
   597   Elimination of @{term "(a, b) : A \<times> B"} -- introduces no
   580   Elimination of @{term "(a, b) : A \<times> B"} -- introduces no
   598   eigenvariables.
   581   eigenvariables.
   599 *}
   582 *}
   600 
   583 
   601 lemma SigmaD1: "(a, b) : Sigma A B ==> a : A"
   584 lemma SigmaD1: "(a, b) : Sigma A B ==> a : A"
   602   apply (erule SigmaE)
   585 by (erule SigmaE, blast)
   603   apply blast
       
   604   done
       
   605 
   586 
   606 lemma SigmaD2: "(a, b) : Sigma A B ==> b : B a"
   587 lemma SigmaD2: "(a, b) : Sigma A B ==> b : B a"
   607   apply (erule SigmaE)
   588 by (erule SigmaE, blast)
   608   apply blast
       
   609   done
       
   610 
   589 
   611 lemma SigmaE2:
   590 lemma SigmaE2:
   612     "[| (a, b) : Sigma A B;
   591     "[| (a, b) : Sigma A B;
   613         [| a:A;  b:B(a) |] ==> P
   592         [| a:A;  b:B(a) |] ==> P
   614      |] ==> P"
   593      |] ==> P"