src/HOL/Prod.ML
changeset 3568 36ff1ab12021
parent 3429 160f18a686b5
child 3842 b55686a7b22c
equal deleted inserted replaced
3567:e2539e1980b4 3568:36ff1ab12021
    76   | Some x => EVERY[res_inst_tac[("p",x)] PairE i,
    76   | Some x => EVERY[res_inst_tac[("p",x)] PairE i,
    77                     REPEAT(hyp_subst_tac i), prune_params_tac]);
    77                     REPEAT(hyp_subst_tac i), prune_params_tac]);
    78 
    78 
    79 end;
    79 end;
    80 
    80 
       
    81 (* Could be nice, but breaks too many proofs:
       
    82 claset := !claset addbefore split_all_tac;
       
    83 *)
       
    84 
       
    85 (*** lemmas for splitting paired `!!'
       
    86 Does not work with simplifier because it also affects premises in
       
    87 congrence rules, where is can lead to premises of the form
       
    88 !!a b. ... = ?P(a,b)
       
    89 which cannot be solved by reflexivity.
       
    90    
       
    91 val [prem] = goal Prod.thy "(!!x.PROP P x) ==> (!!a b. PROP P(a,b))";
       
    92 br prem 1;
       
    93 val lemma1 = result();
       
    94 
       
    95 local
       
    96     val psig = sign_of Prod.thy;
       
    97     val pT = Sign.read_typ (psig, K None) "?'a*?'b=>prop";
       
    98     val PeqP = reflexive(read_cterm psig ("P", pT));
       
    99     val psplit = zero_var_indexes(read_instantiate [("p","x")]
       
   100                                   surjective_pairing RS eq_reflection)
       
   101 in
       
   102 val adhoc = combination PeqP psplit
       
   103 end;
       
   104 
       
   105 
       
   106 val [prem] = goal Prod.thy "(!!a b. PROP P(a,b)) ==> PROP P x";
       
   107 bw adhoc;
       
   108 br prem 1;
       
   109 val lemma = result();
       
   110 
       
   111 val [prem] = goal Prod.thy "(!!a b. PROP P(a,b)) ==> (!!x. PROP P x)";
       
   112 br lemma 1;
       
   113 br prem 1;
       
   114 val lemma2 = result();
       
   115 
       
   116 bind_thm("split_paired_all", equal_intr lemma1 lemma2);
       
   117 Addsimps [split_paired_all];
       
   118 ***)
       
   119 
    81 goal Prod.thy "(!x. P x) = (!a b. P(a,b))";
   120 goal Prod.thy "(!x. P x) = (!a b. P(a,b))";
    82 by (fast_tac (!claset addbefore split_all_tac) 1);
   121 by (fast_tac (!claset addbefore split_all_tac) 1);
    83 qed "split_paired_All";
   122 qed "split_paired_All";
       
   123 Addsimps [split_paired_All];
       
   124 (* AddIffs is not a good idea because it makes Blast_tac loop *)
       
   125 
       
   126 goal Prod.thy "(? x. P x) = (? a b. P(a,b))";
       
   127 by (fast_tac (!claset addbefore split_all_tac) 1);
       
   128 qed "split_paired_Ex";
       
   129 (* Addsimps [split_paired_Ex]; breaks a number of IOA proofs *)
    84 
   130 
    85 goalw Prod.thy [split_def] "split c (a,b) = c a b";
   131 goalw Prod.thy [split_def] "split c (a,b) = c a b";
    86 by (EVERY1[stac fst_conv, stac snd_conv]);
   132 by (EVERY1[stac fst_conv, stac snd_conv]);
    87 by (rtac refl 1);
   133 by (rtac refl 1);
    88 qed "split";
   134 qed "split";
    89 
   135 
    90 Addsimps [fst_conv, snd_conv, split_paired_All, split];
   136 Addsimps [fst_conv, snd_conv, split];
    91 
   137 
    92 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))";
    93 by (res_inst_tac[("p","s")] PairE 1);
   139 by (res_inst_tac[("p","s")] PairE 1);
    94 by (res_inst_tac[("p","t")] PairE 1);
   140 by (res_inst_tac[("p","t")] PairE 1);
    95 by (Asm_simp_tac 1);
   141 by (Asm_simp_tac 1);
   118 goal Prod.thy "R(split c p) = (! x y. p = (x,y) --> R(c x y))";
   164 goal Prod.thy "R(split c p) = (! x y. p = (x,y) --> R(c x y))";
   119 by (stac surjective_pairing 1);
   165 by (stac surjective_pairing 1);
   120 by (stac split 1);
   166 by (stac split 1);
   121 by (Blast_tac 1);
   167 by (Blast_tac 1);
   122 qed "expand_split";
   168 qed "expand_split";
       
   169 
       
   170 (* could be done after split_tac has been speeded up significantly:
       
   171 simpset := (!simpset setloop split_tac[expand_split]);
       
   172    precompute the constants involved and don't do anything unless
       
   173    the current goal contains one of those constants
       
   174 *)
   123 
   175 
   124 (** split used as a logical connective or set former **)
   176 (** split used as a logical connective or set former **)
   125 
   177 
   126 (*These rules are for use with blast_tac.
   178 (*These rules are for use with blast_tac.
   127   Could instead call simp_tac/asm_full_simp_tac using split as rewrite.*)
   179   Could instead call simp_tac/asm_full_simp_tac using split as rewrite.*)
   250 Addsimps [Sigma_empty1,Sigma_empty2]; 
   302 Addsimps [Sigma_empty1,Sigma_empty2]; 
   251 
   303 
   252 goal Prod.thy "((a,b): Sigma A B) = (a:A & b:B(a))";
   304 goal Prod.thy "((a,b): Sigma A B) = (a:A & b:B(a))";
   253 by (Blast_tac 1);
   305 by (Blast_tac 1);
   254 qed "mem_Sigma_iff";
   306 qed "mem_Sigma_iff";
   255 Addsimps [mem_Sigma_iff]; 
   307 AddIffs [mem_Sigma_iff]; 
   256 
   308 
   257 
   309 
   258 (*Suggested by Pierre Chartier*)
   310 (*Suggested by Pierre Chartier*)
   259 goal Prod.thy
   311 goal Prod.thy
   260      "(UN (a,b):(A Times B). E a Times F b) = (UNION A E) Times (UNION B F)";
   312      "(UN (a,b):(A Times B). E a Times F b) = (UNION A E) Times (UNION B F)";