131 | Set => (@{const_name "Abs_set"}, @{typ "atom set"}, @{type_name abs_set}) |
132 | Set => (@{const_name "Abs_set"}, @{typ "atom set"}, @{type_name abs_set}) |
132 | Res => (@{const_name "Abs_res"}, @{typ "atom set"}, @{type_name abs_res}) |
133 | Res => (@{const_name "Abs_res"}, @{typ "atom set"}, @{type_name abs_res}) |
133 |
134 |
134 val abs = Const (abs_name, [binder_ty, body_ty] ---> Type (abs_ty, [body_ty])) |
135 val abs = Const (abs_name, [binder_ty, body_ty] ---> Type (abs_ty, [body_ty])) |
135 val abs_lhs = abs $ binder_trm $ body_trm |
136 val abs_lhs = abs $ binder_trm $ body_trm |
136 val abs_rhs = abs $ mk_perm p binder_trm $ Bound 0 |
137 val abs_rhs = abs $ mk_perm p binder_trm $ mk_perm (Bound 0) body_trm |
137 val goal = HOLogic.mk_eq (abs_lhs, abs_rhs) |
138 val abs_rhs' = abs $ mk_perm (Bound 0) binder_trm $ mk_perm (Bound 0) body_trm |
138 |> (fn t => HOLogic.mk_exists ("y", body_ty, t)) |
139 val abs_eq = HOLogic.mk_eq (abs_lhs, abs_rhs) |
|
140 val abs_eq' = HOLogic.mk_eq (abs_lhs, abs_rhs') |
|
141 val eq = HOLogic.mk_eq (mk_perm (Bound 0) binder_trm, mk_perm p binder_trm) |
|
142 |
|
143 val goal = HOLogic.mk_conj (abs_eq, eq) |
|
144 |> (fn t => HOLogic.mk_exists ("q", @{typ "perm"}, t)) |
139 |> HOLogic.mk_Trueprop |
145 |> HOLogic.mk_Trueprop |
|
146 |
|
147 val goal' = HOLogic.mk_conj (abs_eq', eq) |
|
148 |> (fn t => HOLogic.mk_exists ("q", @{typ "perm"}, t)) |
|
149 |> HOLogic.mk_Trueprop |
140 |
150 |
141 val ss = fprops @ bn_finite_thms @ @{thms set.simps set_append union_eqvt} |
151 val ss = fprops @ bn_finite_thms @ @{thms set.simps set_append union_eqvt} |
142 @ @{thms fresh_star_Un fresh_star_Pair fresh_star_list fresh_star_singleton fresh_star_fset |
152 @ @{thms fresh_star_Un fresh_star_Pair fresh_star_list fresh_star_singleton fresh_star_fset |
143 fresh_star_set} @ @{thms finite.intros finite_fset} |
153 fresh_star_set} @ @{thms finite.intros finite_fset} |
144 in |
154 in |
145 [Goal.prove ctxt [] [] goal |
155 if is_recursive_binder bclause |
146 (K (HEADGOAL (resolve_tac @{thms Abs_rename_set Abs_rename_res Abs_rename_lst} |
156 then |
147 THEN_ALL_NEW (simp_tac (HOL_basic_ss addsimps ss) THEN' TRY o simp_tac HOL_ss))))] |
157 (tracing "recursive"; |
|
158 [ Goal.prove ctxt [] [] goal' |
|
159 (K (HEADGOAL (resolve_tac @{thms Abs_rename_set' Abs_rename_res' Abs_rename_lst'} |
|
160 THEN_ALL_NEW (simp_tac (HOL_basic_ss addsimps ss) THEN' TRY o simp_tac HOL_ss)))) |
|
161 |> Nominal_Permeq.eqvt_strict_rule ctxt bn_eqvt [] |
|
162 ]) |
|
163 else |
|
164 (tracing "non-recursive"; |
|
165 [ Goal.prove ctxt [] [] goal |
|
166 (K (HEADGOAL (resolve_tac @{thms Abs_rename_set Abs_rename_res Abs_rename_lst} |
|
167 THEN_ALL_NEW (simp_tac (HOL_basic_ss addsimps ss) THEN' TRY o simp_tac HOL_ss)))) |
|
168 |> Nominal_Permeq.eqvt_strict_rule ctxt permute_bns [] |
|
169 ]) |
148 end |
170 end |
149 *} |
171 *} |
150 |
172 |
151 |
173 ML {* |
152 (* FIXME: use pure cterm functions *) |
174 fun conj_tac tac i = |
153 ML {* |
175 let |
154 fun mk_cperm ctxt p ctrm = |
176 fun select (t, i) = |
155 mk_perm (term_of p) (term_of ctrm) |
177 case t of |
156 |> cterm_of (ProofContext.theory_of ctxt) |
178 @{term "Trueprop"} $ t' => select (t', i) |
157 *} |
179 | @{term "op \<and>"} $ _ $ _ => (rtac @{thm conjI} THEN' RANGE [conj_tac tac, conj_tac tac]) i |
158 |
180 | _ => tac i |
159 |
181 in |
160 ML {* |
182 SUBGOAL select i |
161 fun case_tac ctxt c bn_finite_thms (prems, bclausess) thm = |
183 end |
|
184 *} |
|
185 |
|
186 ML {* |
|
187 fun is_abs_eq thm = |
|
188 let |
|
189 fun is_abs trm = |
|
190 case (head_of trm) of |
|
191 Const (@{const_name "Abs_set"}, _) => true |
|
192 | Const (@{const_name "Abs_lst"}, _) => true |
|
193 | Const (@{const_name "Abs_res"}, _) => true |
|
194 | _ => false |
|
195 in |
|
196 thm |> prop_of |
|
197 |> HOLogic.dest_Trueprop |
|
198 |> HOLogic.dest_eq |
|
199 |> fst |
|
200 |> is_abs |
|
201 end |
|
202 *} |
|
203 |
|
204 lemma setify: |
|
205 shows "xs = ys \<Longrightarrow> set xs = set ys" |
|
206 by simp |
|
207 |
|
208 ML {* |
|
209 fun case_tac ctxt c bn_finite_thms eq_iff_thms bn_eqvt permute_bns perm_bn_alphas |
|
210 (prems, bclausess) qexhaust_thm = |
162 let |
211 let |
163 fun aux_tac prem bclauses = |
212 fun aux_tac prem bclauses = |
164 case (get_all_binders bclauses) of |
213 case (get_all_binders bclauses) of |
165 [] => EVERY' [rtac prem, atac] |
214 [] => EVERY' [rtac prem, atac] |
166 | binders => Subgoal.FOCUS (fn {params, prems, context = ctxt, ...} => |
215 | binders => Subgoal.SUBPROOF (fn {params, prems, concl, context = ctxt, ...} => |
167 let |
216 let |
168 val parms = map (term_of o snd) params |
217 val parms = map (term_of o snd) params |
169 val fthm = fresh_thm ctxt c parms binders bn_finite_thms |
218 val fthm = fresh_thm ctxt c parms binders bn_finite_thms |
170 |
219 |
171 val ss = @{thms fresh_star_Pair union_eqvt fresh_star_Un} |
220 val ss = @{thms fresh_star_Pair union_eqvt fresh_star_Un} |
172 val (([(_, fperm)], fprops), ctxt') = Obtain.result |
221 val (([(_, fperm)], fprops), ctxt') = Obtain.result |
173 (K (EVERY1 [etac exE, |
222 (K (EVERY1 [etac exE, |
174 full_simp_tac (HOL_basic_ss addsimps ss), |
223 full_simp_tac (HOL_basic_ss addsimps ss), |
175 REPEAT o (etac conjE)])) [fthm] ctxt |
224 REPEAT o (etac @{thm conjE})])) [fthm] ctxt |
176 |
225 |
177 val abs_eqs = flat (map (abs_eq_thm ctxt fprops (term_of fperm) parms bn_finite_thms) bclauses) |
226 val abs_eq_thms = flat |
178 |
227 (map (abs_eq_thm ctxt fprops (term_of fperm) parms bn_finite_thms bn_eqvt permute_bns) bclauses) |
179 val _ = tracing ("test") |
228 |
180 (* |
229 val ((_, eqs), ctxt'') = Obtain.result |
181 val _ = tracing ("fprop:\n" ^ cat_lines (map (Syntax.string_of_term ctxt' o prop_of) fprops)) |
230 (K (EVERY1 |
182 *) |
231 [ REPEAT o (etac @{thm exE}), |
183 (* |
232 REPEAT o (etac @{thm conjE}), |
184 val _ = tracing ("abs_eqs:\n" ^ cat_lines (map (Syntax.string_of_term ctxt' o prop_of) abs_eqs)) |
233 REPEAT o (dtac @{thm setify}), |
185 *) |
234 full_simp_tac (HOL_basic_ss addsimps @{thms set_append set.simps})])) abs_eq_thms ctxt' |
|
235 |
|
236 val (abs_eqs, peqs) = split_filter is_abs_eq eqs |
|
237 |
|
238 val fprops' = map (Nominal_Permeq.eqvt_strict_rule ctxt permute_bns []) fprops |
|
239 val fprops'' = map (Nominal_Permeq.eqvt_strict_rule ctxt bn_eqvt []) fprops |
|
240 |
|
241 val _ = tracing ("prem:\n" ^ (Syntax.string_of_term ctxt'' o prop_of) prem) |
|
242 val _ = tracing ("prems:\n" ^ cat_lines (map (Syntax.string_of_term ctxt'' o prop_of) prems)) |
|
243 val _ = tracing ("fprop':\n" ^ cat_lines (map (Syntax.string_of_term ctxt'' o prop_of) fprops')) |
|
244 val _ = tracing ("fprop'':\n" ^ cat_lines (map (Syntax.string_of_term ctxt'' o prop_of) fprops'')) |
|
245 val _ = tracing ("abseq:\n" ^ cat_lines (map (Syntax.string_of_term ctxt'' o prop_of) abs_eqs)) |
|
246 val _ = tracing ("peqs:\n" ^ cat_lines (map (Syntax.string_of_term ctxt'' o prop_of) peqs)) |
|
247 |
|
248 |
|
249 val tac1 = EVERY' |
|
250 [ simp_tac (HOL_basic_ss addsimps peqs), |
|
251 rewrite_goal_tac (@{thms fresh_star_Un[THEN eq_reflection]}), |
|
252 K (print_tac "before solving freshness"), |
|
253 conj_tac (TRY o DETERM o resolve_tac (fprops' @ fprops'')) ] |
|
254 |
|
255 val tac2 = EVERY' |
|
256 [ rtac (@{thm ssubst} OF prems), |
|
257 rewrite_goal_tac (map safe_mk_equiv eq_iff_thms), |
|
258 K (print_tac "before substituting"), |
|
259 rewrite_goal_tac (map safe_mk_equiv abs_eqs), |
|
260 K (print_tac "after substituting"), |
|
261 conj_tac (TRY o DETERM o resolve_tac (@{thms refl} @ perm_bn_alphas)), |
|
262 K (print_tac "end") |
|
263 ] |
|
264 |
|
265 val side_thm = Goal.prove ctxt'' [] [] (term_of concl) |
|
266 (fn _ => (* Skip_Proof.cheat_tac (ProofContext.theory_of ctxt'') *) |
|
267 EVERY |
|
268 [ rtac prem 1, |
|
269 print_tac "after applying prem", |
|
270 RANGE [SOLVED' tac1, SOLVED' tac2] 1, |
|
271 print_tac "final" ] ) |
|
272 |> singleton (ProofContext.export ctxt'' ctxt) |
|
273 |
|
274 val _ = tracing ("side_thm:\n" ^ (Syntax.string_of_term ctxt o prop_of) side_thm) |
186 in |
275 in |
187 (*HEADGOAL (rtac prem THEN' RANGE [K all_tac, simp_tac (HOL_basic_ss addsimps prems)])*) |
276 rtac side_thm 1 |
188 Skip_Proof.cheat_tac (ProofContext.theory_of ctxt') |
|
189 end) ctxt |
277 end) ctxt |
190 in |
278 in |
191 rtac thm THEN' RANGE (map2 aux_tac prems bclausess) |
279 rtac qexhaust_thm THEN' RANGE (map2 aux_tac prems bclausess) |
192 end |
280 end |
193 *} |
281 *} |
194 |
282 |
195 |
283 |
196 ML {* |
284 ML {* |
197 fun prove_strong_exhausts lthy qexhausts qtrms bclausesss bn_finite_thms = |
285 fun prove_strong_exhausts lthy exhausts qtrms bclausesss bn_finite_thms eq_iff_thms bn_eqvt permute_bns |
|
286 perm_bn_alphas = |
198 let |
287 let |
199 val ((_, qexhausts'), lthy') = Variable.import true qexhausts lthy |
288 val ((_, exhausts'), lthy') = Variable.import true exhausts lthy |
200 |
289 |
201 val ([c, a], lthy'') = Variable.variant_fixes ["c", "'a"] lthy' |
290 val ([c, a], lthy'') = Variable.variant_fixes ["c", "'a"] lthy' |
202 val c = Free (c, TFree (a, @{sort fs})) |
291 val c = Free (c, TFree (a, @{sort fs})) |
203 |
292 |
204 val (ecases, main_concls) = qexhausts' (* ecases or of the form (params, prems, concl) *) |
293 val (ecases, main_concls) = exhausts' (* ecases or of the form (params, prems, concl) *) |
205 |> map prop_of |
294 |> map prop_of |
206 |> map Logic.strip_horn |
295 |> map Logic.strip_horn |
207 |> split_list |
296 |> split_list |
208 |>> (map o map) strip_params_prems_concl |
297 |>> (map o map) strip_params_prems_concl |
209 |
298 |