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.*) |