|
1 (* Title: HOL/ex/veriT_Preprocessing.thy |
|
2 Author: Jasmin Christian Blanchette, Inria, LORIA, MPII |
|
3 *) |
|
4 |
|
5 section \<open>Proof Reconstruction for veriT's Preprocessing\<close> |
|
6 |
|
7 theory veriT_Preprocessing |
|
8 imports Main |
|
9 begin |
|
10 |
|
11 declare [[eta_contract = false]] |
|
12 |
|
13 lemma |
|
14 some_All_iffI: "p (SOME x. \<not> p x) = q \<Longrightarrow> (\<forall>x. p x) = q" and |
|
15 some_Ex_iffI: "p (SOME x. p x) = q \<Longrightarrow> (\<exists>x. p x) = q" |
|
16 by (metis (full_types) someI_ex)+ |
|
17 |
|
18 ML \<open> |
|
19 fun mk_prod1 bound_Ts (t, u) = |
|
20 HOLogic.pair_const (fastype_of1 (bound_Ts, t)) (fastype_of1 (bound_Ts, u)) $ t $ u; |
|
21 |
|
22 fun mk_tuple1 bound_Ts = the_default HOLogic.unit o try (foldr1 (mk_prod1 bound_Ts)); |
|
23 |
|
24 fun mk_arg_congN 0 = refl |
|
25 | mk_arg_congN 1 = arg_cong |
|
26 | mk_arg_congN 2 = @{thm arg_cong2} |
|
27 | mk_arg_congN n = arg_cong RS funpow (n - 2) (fn th => @{thm cong} RS th) @{thm cong}; |
|
28 |
|
29 fun mk_let_iffNI ctxt n = |
|
30 let |
|
31 val ((As, [B]), _) = ctxt |
|
32 |> Ctr_Sugar_Util.mk_TFrees n |
|
33 ||>> Ctr_Sugar_Util.mk_TFrees 1; |
|
34 |
|
35 val ((((ts, us), [p]), [q]), _) = ctxt |
|
36 |> Ctr_Sugar_Util.mk_Frees "t" As |
|
37 ||>> Ctr_Sugar_Util.mk_Frees "u" As |
|
38 ||>> Ctr_Sugar_Util.mk_Frees "p" [As ---> B] |
|
39 ||>> Ctr_Sugar_Util.mk_Frees "q" [B]; |
|
40 |
|
41 val tuple_t = HOLogic.mk_tuple ts; |
|
42 val tuple_T = fastype_of tuple_t; |
|
43 |
|
44 val lambda_t = HOLogic.tupled_lambda tuple_t (list_comb (p, ts)); |
|
45 val lambda_T = fastype_of lambda_t; |
|
46 |
|
47 val left_prems = map2 (curry Ctr_Sugar_Util.mk_Trueprop_eq) ts us; |
|
48 val right_prem = Ctr_Sugar_Util.mk_Trueprop_eq (list_comb (p, us), q); |
|
49 val concl = Ctr_Sugar_Util.mk_Trueprop_eq |
|
50 (Const (@{const_name Let}, tuple_T --> lambda_T --> B) $ tuple_t $ lambda_t, q); |
|
51 |
|
52 val goal = Logic.list_implies (left_prems @ [right_prem], concl); |
|
53 val vars = Variable.add_free_names ctxt goal []; |
|
54 in |
|
55 Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, ...} => |
|
56 HEADGOAL (hyp_subst_tac ctxt) THEN |
|
57 Local_Defs.unfold0_tac ctxt @{thms Let_def prod.case} THEN |
|
58 HEADGOAL (resolve_tac ctxt [refl])) |
|
59 end; |
|
60 |
|
61 datatype rule_name = |
|
62 Refl |
|
63 | Taut of thm |
|
64 | Trans of term |
|
65 | Cong |
|
66 | Bind |
|
67 | Sko_Ex |
|
68 | Sko_All |
|
69 | Let of term list; |
|
70 |
|
71 fun str_of_rule_name Refl = "Refl" |
|
72 | str_of_rule_name (Taut th) = "Taut[" ^ @{make_string} th ^ "]" |
|
73 | str_of_rule_name (Trans t) = "Trans[" ^ Syntax.string_of_term @{context} t ^ "]" |
|
74 | str_of_rule_name Cong = "Cong" |
|
75 | str_of_rule_name Bind = "Bind" |
|
76 | str_of_rule_name Sko_Ex = "Sko_Ex" |
|
77 | str_of_rule_name Sko_All = "Sko_All" |
|
78 | str_of_rule_name (Let ts) = |
|
79 "Let[" ^ commas (map (Syntax.string_of_term @{context}) ts) ^ "]"; |
|
80 |
|
81 datatype rule = Rule of rule_name * rule list; |
|
82 |
|
83 fun lambda_count (Abs (_, _, t)) = lambda_count t + 1 |
|
84 | lambda_count ((t as Abs _) $ _) = lambda_count t - 1 |
|
85 | lambda_count ((t as Const (@{const_name case_prod}, _) $ _) $ _) = lambda_count t - 1 |
|
86 | lambda_count (Const (@{const_name case_prod}, _) $ t) = lambda_count t - 1 |
|
87 | lambda_count _ = 0; |
|
88 |
|
89 fun zoom apply = |
|
90 let |
|
91 fun zo 0 bound_Ts (Abs (r, T, t), Abs (s, U, u)) = |
|
92 let val (t', u') = zo 0 (T :: bound_Ts) (t, u) in |
|
93 (lambda (Free (r, T)) t', lambda (Free (s, U)) u') |
|
94 end |
|
95 | zo 0 bound_Ts ((t as Abs (_, T, _)) $ arg, u) = |
|
96 let val (t', u') = zo 1 (T :: bound_Ts) (t, u) in |
|
97 (t' $ arg, u') |
|
98 end |
|
99 | zo 0 bound_Ts ((t as Const (@{const_name case_prod}, _) $ _) $ arg, u) = |
|
100 let val (t', u') = zo 1 bound_Ts (t, u) in |
|
101 (t' $ arg, u') |
|
102 end |
|
103 | zo 0 bound_Ts tu = apply bound_Ts tu |
|
104 | zo n bound_Ts (Const (@{const_name case_prod}, |
|
105 Type (@{type_name fun}, [Type (@{type_name fun}, [A, Type (@{type_name fun}, [B, _])]), |
|
106 Type (@{type_name fun}, [AB, _])])) $ t, u) = |
|
107 let |
|
108 val (t', u') = zo (n + 1) bound_Ts (t, u); |
|
109 val C = range_type (range_type (fastype_of t')); |
|
110 in |
|
111 (Const (@{const_name case_prod}, (A --> B --> C) --> AB --> C) $ t', u') |
|
112 end |
|
113 | zo n bound_Ts (Abs (s, T, t), u) = |
|
114 let val (t', u') = zo (n - 1) (T :: bound_Ts) (t, u) in |
|
115 (Abs (s, T, t'), u') |
|
116 end |
|
117 | zo _ _ (t, u) = raise TERM ("zoom", [t, u]); |
|
118 in |
|
119 zo 0 [] |
|
120 end; |
|
121 |
|
122 fun apply_Trans_left t (lhs, _) = (lhs, t); |
|
123 fun apply_Trans_right t (_, rhs) = (t, rhs); |
|
124 |
|
125 fun apply_Cong ary j (lhs, rhs) = |
|
126 (case apply2 strip_comb (lhs, rhs) of |
|
127 ((c, ts), (d, us)) => |
|
128 if c aconv d andalso length ts = ary andalso length us = ary then (nth ts j, nth us j) |
|
129 else raise TERM ("apply_Cong", [lhs, rhs])); |
|
130 |
|
131 fun apply_Bind (lhs, rhs) = |
|
132 (case (lhs, rhs) of |
|
133 (Const (@{const_name All}, _) $ Abs (_, T, t), Const (@{const_name All}, _) $ Abs (s, U, u)) => |
|
134 (Abs (s, T, t), Abs (s, U, u)) |
|
135 | (Const (@{const_name Ex}, _) $ t, Const (@{const_name Ex}, _) $ u) => (t, u) |
|
136 | _ => raise TERM ("apply_Bind", [lhs, rhs])); |
|
137 |
|
138 fun apply_Sko_Ex (lhs, rhs) = |
|
139 (case lhs of |
|
140 Const (@{const_name Ex}, _) $ (t as Abs (_, T, _)) => |
|
141 (t $ (HOLogic.choice_const T $ t), rhs) |
|
142 | _ => raise TERM ("apply_Sko_Ex", [lhs])); |
|
143 |
|
144 fun apply_Sko_All (lhs, rhs) = |
|
145 (case lhs of |
|
146 Const (@{const_name All}, _) $ (t as Abs (s, T, body)) => |
|
147 (t $ (HOLogic.choice_const T $ Abs (s, T, HOLogic.mk_not body)), rhs) |
|
148 | _ => raise TERM ("apply_Sko_All", [lhs])); |
|
149 |
|
150 fun apply_Let_left ts j (lhs, _) = |
|
151 (case lhs of |
|
152 Const (@{const_name Let}, _) $ t $ _ => |
|
153 let val ts0 = HOLogic.strip_tuple t in |
|
154 (nth ts0 j, nth ts j) |
|
155 end |
|
156 | _ => raise TERM ("apply_Let_left", [lhs])); |
|
157 |
|
158 fun apply_Let_right ts bound_Ts (lhs, rhs) = |
|
159 let val t' = mk_tuple1 bound_Ts ts in |
|
160 (case lhs of |
|
161 Const (@{const_name Let}, _) $ _ $ u => (u $ t', rhs) |
|
162 | _ => raise TERM ("apply_Let_right", [lhs, rhs])) |
|
163 end; |
|
164 |
|
165 fun reconstruct_proof ctxt (lrhs as (_, rhs), Rule (rule_name, prems)) = |
|
166 let |
|
167 val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq lrhs); |
|
168 val ary = length prems; |
|
169 |
|
170 val _ = warning (Syntax.string_of_term @{context} goal); |
|
171 val _ = warning (str_of_rule_name rule_name); |
|
172 |
|
173 val parents = |
|
174 (case (rule_name, prems) of |
|
175 (Refl, []) => [] |
|
176 | (Taut _, []) => [] |
|
177 | (Trans t, [left_prem, right_prem]) => |
|
178 [reconstruct_proof ctxt (zoom (K (apply_Trans_left t)) lrhs, left_prem), |
|
179 reconstruct_proof ctxt (zoom (K (apply_Trans_right t)) (rhs, rhs), right_prem)] |
|
180 | (Cong, _) => |
|
181 map_index (fn (j, prem) => reconstruct_proof ctxt (zoom (K (apply_Cong ary j)) lrhs, prem)) |
|
182 prems |
|
183 | (Bind, [prem]) => [reconstruct_proof ctxt (zoom (K apply_Bind) lrhs, prem)] |
|
184 | (Sko_Ex, [prem]) => [reconstruct_proof ctxt (zoom (K apply_Sko_Ex) lrhs, prem)] |
|
185 | (Sko_All, [prem]) => [reconstruct_proof ctxt (zoom (K apply_Sko_All) lrhs, prem)] |
|
186 | (Let ts, prems) => |
|
187 let val (left_prems, right_prem) = split_last prems in |
|
188 map2 (fn j => fn prem => |
|
189 reconstruct_proof ctxt (zoom (K (apply_Let_left ts j)) lrhs, prem)) |
|
190 (0 upto length left_prems - 1) left_prems @ |
|
191 [reconstruct_proof ctxt (zoom (apply_Let_right ts) lrhs, right_prem)] |
|
192 end |
|
193 | _ => raise Fail ("Invalid rule: " ^ str_of_rule_name rule_name ^ "/" ^ |
|
194 string_of_int (length prems))); |
|
195 |
|
196 val rule_thms = |
|
197 (case rule_name of |
|
198 Refl => [refl] |
|
199 | Taut th => [th] |
|
200 | Trans _ => [trans] |
|
201 | Cong => [mk_arg_congN ary] |
|
202 | Bind => @{thms arg_cong[of _ _ All] arg_cong[of _ _ Ex]} |
|
203 | Sko_Ex => [@{thm some_Ex_iffI}] |
|
204 | Sko_All => [@{thm some_All_iffI}] |
|
205 | Let ts => [mk_let_iffNI ctxt (length ts)]); |
|
206 |
|
207 val num_lams = lambda_count rhs; |
|
208 val conged_parents = map (funpow num_lams (fn th => th RS fun_cong) |
|
209 #> Local_Defs.unfold0 ctxt @{thms prod.case}) parents; |
|
210 in |
|
211 Goal.prove_sorry ctxt [] [] goal (fn {context = ctxt, ...} => |
|
212 Local_Defs.unfold0_tac ctxt @{thms prod.case} THEN |
|
213 HEADGOAL (REPEAT_DETERM_N num_lams o resolve_tac ctxt [ext] THEN' |
|
214 resolve_tac ctxt rule_thms THEN' |
|
215 K (Local_Defs.unfold0_tac ctxt @{thms prod.case}) THEN' |
|
216 EVERY' (map (resolve_tac ctxt o single) conged_parents))) |
|
217 end; |
|
218 \<close> |
|
219 |
|
220 ML \<open> |
|
221 val proof0 = |
|
222 ((@{term "\<exists>x :: nat. p x"}, |
|
223 @{term "p (SOME x :: nat. p x)"}), |
|
224 Rule (Sko_Ex, [Rule (Refl, [])])); |
|
225 |
|
226 reconstruct_proof @{context} proof0; |
|
227 \<close> |
|
228 |
|
229 ML \<open> |
|
230 val proof1 = |
|
231 ((@{term "\<not> (\<forall>x :: nat. \<exists>y :: nat. p x y)"}, |
|
232 @{term "\<not> (\<exists>y :: nat. p (SOME x :: nat. \<not> (\<exists>y :: nat. p x y)) y)"}), |
|
233 Rule (Cong, [Rule (Sko_All, [Rule (Bind, [Rule (Refl, [])])])])); |
|
234 |
|
235 reconstruct_proof @{context} proof1; |
|
236 \<close> |
|
237 |
|
238 ML \<open> |
|
239 val proof2 = |
|
240 ((@{term "\<forall>x :: nat. \<exists>y :: nat. \<exists>z :: nat. p x y z"}, |
|
241 @{term "\<forall>x :: nat. p x (SOME y :: nat. \<exists>z :: nat. p x y z) |
|
242 (SOME z :: nat. p x (SOME y :: nat. \<exists>z :: nat. p x y z) z)"}), |
|
243 Rule (Bind, [Rule (Sko_Ex, [Rule (Sko_Ex, [Rule (Refl, [])])])])); |
|
244 |
|
245 reconstruct_proof @{context} proof2 |
|
246 \<close> |
|
247 |
|
248 ML \<open> |
|
249 val proof3 = |
|
250 ((@{term "\<forall>x :: nat. \<exists>x :: nat. \<exists>x :: nat. p x x x"}, |
|
251 @{term "\<forall>x :: nat. p (SOME x :: nat. p x x x) (SOME x. p x x x) (SOME x. p x x x)"}), |
|
252 Rule (Bind, [Rule (Sko_Ex, [Rule (Sko_Ex, [Rule (Refl, [])])])])); |
|
253 |
|
254 reconstruct_proof @{context} proof3 |
|
255 \<close> |
|
256 |
|
257 ML \<open> |
|
258 val proof4 = |
|
259 ((@{term "\<forall>x :: nat. \<exists>x :: nat. \<exists>x :: nat. p x x x"}, |
|
260 @{term "\<forall>x :: nat. \<exists>x :: nat. p (SOME x :: nat. p x x x) (SOME x. p x x x) (SOME x. p x x x)"}), |
|
261 Rule (Bind, [Rule (Bind, [Rule (Sko_Ex, [Rule (Refl, [])])])])); |
|
262 |
|
263 reconstruct_proof @{context} proof4 |
|
264 \<close> |
|
265 |
|
266 ML \<open> |
|
267 val proof5 = |
|
268 ((@{term "\<forall>x :: nat. q \<and> (\<exists>x :: nat. \<exists>x :: nat. p x x x)"}, |
|
269 @{term "\<forall>x :: nat. q \<and> |
|
270 (\<exists>x :: nat. p (SOME x :: nat. p x x x) (SOME x. p x x x) (SOME x. p x x x))"}), |
|
271 Rule (Bind, [Rule (Cong, [Rule (Refl, []), Rule (Bind, [Rule (Sko_Ex, |
|
272 [Rule (Refl, [])])])])])); |
|
273 |
|
274 reconstruct_proof @{context} proof5 |
|
275 \<close> |
|
276 |
|
277 ML \<open> |
|
278 val proof6 = |
|
279 ((@{term "\<not> (\<forall>x :: nat. q \<and> (\<exists>x :: nat. \<forall>x :: nat. p x x x))"}, |
|
280 @{term "\<not> (\<forall>x :: nat. q \<and> |
|
281 (\<exists>x :: nat. p (SOME x :: nat. \<not> p x x x) (SOME x. \<not> p x x x) (SOME x. \<not> p x x x)))"}), |
|
282 Rule (Cong, [Rule (Bind, [Rule (Cong, [Rule (Refl, []), Rule (Bind, [Rule (Sko_All, |
|
283 [Rule (Refl, [])])])])])])); |
|
284 |
|
285 reconstruct_proof @{context} proof6 |
|
286 \<close> |
|
287 |
|
288 ML \<open> |
|
289 val proof7 = |
|
290 ((@{term "\<not> \<not> (\<exists>x. p x)"}, |
|
291 @{term "\<not> \<not> p (SOME x. p x)"}), |
|
292 Rule (Cong, [Rule (Cong, [Rule (Sko_Ex, [Rule (Refl, [])])])])); |
|
293 |
|
294 reconstruct_proof @{context} proof7 |
|
295 \<close> |
|
296 |
|
297 ML \<open> |
|
298 val proof8 = |
|
299 ((@{term "\<not> \<not> (let x = Suc x in x = 0)"}, |
|
300 @{term "\<not> \<not> Suc x = 0"}), |
|
301 Rule (Cong, [Rule (Cong, [Rule (Let [@{term "Suc x"}], |
|
302 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
303 |
|
304 reconstruct_proof @{context} proof8 |
|
305 \<close> |
|
306 |
|
307 ML \<open> |
|
308 val proof9 = |
|
309 ((@{term "\<not> (let x = Suc x in x = 0)"}, |
|
310 @{term "\<not> Suc x = 0"}), |
|
311 Rule (Cong, [Rule (Let [@{term "Suc x"}], [Rule (Refl, []), Rule (Refl, [])])])); |
|
312 |
|
313 reconstruct_proof @{context} proof9 |
|
314 \<close> |
|
315 |
|
316 ML \<open> |
|
317 val proof10 = |
|
318 ((@{term "\<exists>x :: nat. p (x + 0)"}, |
|
319 @{term "\<exists>x :: nat. p x"}), |
|
320 Rule (Bind, [Rule (Cong, [Rule (Taut @{thm add_0_right}, [])])])); |
|
321 |
|
322 reconstruct_proof @{context} proof10; |
|
323 \<close> |
|
324 |
|
325 ML \<open> |
|
326 val proof11 = |
|
327 ((@{term "\<not> (let (x, y) = (Suc y, Suc x) in y = 0)"}, |
|
328 @{term "\<not> Suc x = 0"}), |
|
329 Rule (Cong, [Rule (Let [@{term "Suc y"}, @{term "Suc x"}], |
|
330 [Rule (Refl, []), Rule (Refl, []), Rule (Refl, [])])])); |
|
331 |
|
332 reconstruct_proof @{context} proof11 |
|
333 \<close> |
|
334 |
|
335 ML \<open> |
|
336 val proof12 = |
|
337 ((@{term "\<not> (let (x, y) = (Suc y, Suc x); (u, v, w) = (y, x, y) in w = 0)"}, |
|
338 @{term "\<not> Suc x = 0"}), |
|
339 Rule (Cong, [Rule (Let [@{term "Suc y"}, @{term "Suc x"}], |
|
340 [Rule (Refl, []), Rule (Refl, []), |
|
341 Rule (Let [@{term "Suc x"}, @{term "Suc y"}, @{term "Suc x"}], |
|
342 [Rule (Refl, []), Rule (Refl, []), Rule (Refl, []), Rule (Refl, [])])])])); |
|
343 |
|
344 reconstruct_proof @{context} proof12 |
|
345 \<close> |
|
346 |
|
347 ML \<open> |
|
348 val proof13 = |
|
349 ((@{term "\<not> \<not> (let x = Suc x in x = 0)"}, |
|
350 @{term "\<not> \<not> Suc x = 0"}), |
|
351 Rule (Cong, [Rule (Cong, [Rule (Let [@{term "Suc x"}], |
|
352 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
353 |
|
354 reconstruct_proof @{context} proof13 |
|
355 \<close> |
|
356 |
|
357 ML \<open> |
|
358 val proof14 = |
|
359 ((@{term "let (x, y) = (f (a :: nat), b :: nat) in x > a"}, |
|
360 @{term "f (a :: nat) > a"}), |
|
361 Rule (Let [@{term "f (a :: nat) :: nat"}, @{term "b :: nat"}], |
|
362 [Rule (Cong, [Rule (Refl, [])]), Rule (Refl, []), Rule (Refl, [])])); |
|
363 |
|
364 reconstruct_proof @{context} proof14 |
|
365 \<close> |
|
366 |
|
367 ML \<open> |
|
368 val proof15 = |
|
369 ((@{term "let x = (let y = g (z :: nat) in f (y :: nat)) in x = Suc 0"}, |
|
370 @{term "f (g (z :: nat) :: nat) = Suc 0"}), |
|
371 Rule (Let [@{term "f (g (z :: nat) :: nat) :: nat"}], |
|
372 [Rule (Let [@{term "g (z :: nat) :: nat"}], [Rule (Refl, []), Rule (Refl, [])]), |
|
373 Rule (Refl, [])])); |
|
374 |
|
375 reconstruct_proof @{context} proof15 |
|
376 \<close> |
|
377 |
|
378 ML \<open> |
|
379 val proof16 = |
|
380 ((@{term "a > Suc b"}, |
|
381 @{term "a > Suc b"}), |
|
382 Rule (Trans @{term "a > Suc b"}, [Rule (Refl, []), Rule (Refl, [])])); |
|
383 |
|
384 reconstruct_proof @{context} proof16 |
|
385 \<close> |
|
386 |
|
387 thm Suc_1 |
|
388 thm numeral_2_eq_2 |
|
389 thm One_nat_def |
|
390 |
|
391 ML \<open> |
|
392 val proof17 = |
|
393 ((@{term "2 :: nat"}, |
|
394 @{term "Suc (Suc 0) :: nat"}), |
|
395 Rule (Trans @{term "Suc 1"}, [Rule (Taut @{thm Suc_1[symmetric]}, []), |
|
396 Rule (Cong, [Rule (Taut @{thm One_nat_def}, [])])])); |
|
397 |
|
398 reconstruct_proof @{context} proof17 |
|
399 \<close> |
|
400 |
|
401 ML \<open> |
|
402 val proof18 = |
|
403 ((@{term "let x = a in let y = b in Suc x + y"}, |
|
404 @{term "Suc a + b"}), |
|
405 Rule (Trans @{term "let y = b in Suc a + y"}, |
|
406 [Rule (Let [@{term "a :: nat"}], [Rule (Refl, []), Rule (Refl, [])]), |
|
407 Rule (Let [@{term "b :: nat"}], [Rule (Refl, []), Rule (Refl, [])])])); |
|
408 |
|
409 reconstruct_proof @{context} proof18 |
|
410 \<close> |
|
411 |
|
412 ML \<open> |
|
413 val proof19 = |
|
414 ((@{term "\<forall>x. let x = f (x :: nat) :: nat in g x"}, |
|
415 @{term "\<forall>x. g (f (x :: nat) :: nat)"}), |
|
416 Rule (Bind, [Rule (Let [@{term "f :: nat \<Rightarrow> nat"} $ Bound 0], |
|
417 [Rule (Refl, []), Rule (Refl, [])])])); |
|
418 |
|
419 reconstruct_proof @{context} proof19 |
|
420 \<close> |
|
421 |
|
422 ML \<open> |
|
423 val proof20 = |
|
424 ((@{term "\<forall>x. let y = Suc 0 in let x = f (x :: nat) :: nat in g x"}, |
|
425 @{term "\<forall>x. g (f (x :: nat) :: nat)"}), |
|
426 Rule (Bind, [Rule (Let [@{term "Suc 0"}], |
|
427 [Rule (Refl, []), Rule (Let [@{term "f (x :: nat) :: nat"}], |
|
428 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
429 |
|
430 reconstruct_proof @{context} proof20 |
|
431 \<close> |
|
432 |
|
433 ML \<open> |
|
434 val proof21 = |
|
435 ((@{term "\<forall>x :: nat. let x = f x :: nat in let y = x in p y"}, |
|
436 @{term "\<forall>z :: nat. p (f z :: nat)"}), |
|
437 Rule (Bind, [Rule (Let [@{term "f (z :: nat) :: nat"}], |
|
438 [Rule (Refl, []), Rule (Let [@{term "f (z :: nat) :: nat"}], |
|
439 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
440 |
|
441 reconstruct_proof @{context} proof21 |
|
442 \<close> |
|
443 |
|
444 ML \<open> |
|
445 val proof22 = |
|
446 ((@{term "\<forall>x :: nat. let x = f x :: nat in let y = x in p y"}, |
|
447 @{term "\<forall>x :: nat. p (f x :: nat)"}), |
|
448 Rule (Bind, [Rule (Let [@{term "f (x :: nat) :: nat"}], |
|
449 [Rule (Refl, []), Rule (Let [@{term "f (x :: nat) :: nat"}], |
|
450 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
451 |
|
452 reconstruct_proof @{context} proof22 |
|
453 \<close> |
|
454 |
|
455 ML \<open> |
|
456 val proof23 = |
|
457 ((@{term "\<forall>x :: nat. let (x, a) = (f x :: nat, 0 ::nat) in let y = x in p y"}, |
|
458 @{term "\<forall>z :: nat. p (f z :: nat)"}), |
|
459 Rule (Bind, [Rule (Let [@{term "f (z :: nat) :: nat"}, @{term "0 :: nat"}], |
|
460 [Rule (Refl, []), Rule (Refl, []), Rule (Let [@{term "f (z :: nat) :: nat"}], |
|
461 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
462 |
|
463 reconstruct_proof @{context} proof23 |
|
464 \<close> |
|
465 |
|
466 ML \<open> |
|
467 val proof24 = |
|
468 ((@{term "\<forall>x :: nat. let (x, a) = (f x :: nat, 0 ::nat) in let y = x in p y"}, |
|
469 @{term "\<forall>x :: nat. p (f x :: nat)"}), |
|
470 Rule (Bind, [Rule (Let [@{term "f (x :: nat) :: nat"}, @{term "0 :: nat"}], |
|
471 [Rule (Refl, []), Rule (Refl, []), Rule (Let [@{term "f (x :: nat) :: nat"}], |
|
472 [Rule (Refl, []), Rule (Refl, [])])])])); |
|
473 |
|
474 reconstruct_proof @{context} proof24 |
|
475 \<close> |
|
476 |
|
477 end |