src/HOL/ex/veriT_Preprocessing.thy
changeset 65016 c0ab0824ccb5
parent 64978 5b9ba120d222
child 65017 d11249edc2c2
equal deleted inserted replaced
65015:c22e092b39e9 65016:c0ab0824ccb5
    76   | str_of_rule_name Sko_Ex = "Sko_Ex"
    76   | str_of_rule_name Sko_Ex = "Sko_Ex"
    77   | str_of_rule_name Sko_All = "Sko_All"
    77   | str_of_rule_name Sko_All = "Sko_All"
    78   | str_of_rule_name (Let ts) =
    78   | str_of_rule_name (Let ts) =
    79     "Let[" ^ commas (map (Syntax.string_of_term @{context}) ts) ^ "]";
    79     "Let[" ^ commas (map (Syntax.string_of_term @{context}) ts) ^ "]";
    80 
    80 
    81 datatype rule = Rule of rule_name * rule list;
    81 datatype node = Node of rule_name * node list;
    82 
    82 
    83 fun lambda_count (Abs (_, _, t)) = lambda_count t + 1
    83 fun lambda_count (Abs (_, _, t)) = lambda_count t + 1
    84   | lambda_count ((t as Abs _) $ _) = 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
    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
    86   | lambda_count (Const (@{const_name case_prod}, _) $ t) = lambda_count t - 1
   160     (case lhs of
   160     (case lhs of
   161       Const (@{const_name Let}, _) $ _ $ u => (u $ t', rhs)
   161       Const (@{const_name Let}, _) $ _ $ u => (u $ t', rhs)
   162     | _ => raise TERM ("apply_Let_right", [lhs, rhs]))
   162     | _ => raise TERM ("apply_Let_right", [lhs, rhs]))
   163   end;
   163   end;
   164 
   164 
   165 fun reconstruct_proof ctxt (lrhs as (_, rhs), Rule (rule_name, prems)) =
   165 fun reconstruct_proof ctxt (lrhs as (_, rhs), Node (rule_name, prems)) =
   166   let
   166   let
   167     val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq lrhs);
   167     val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq lrhs);
   168     val ary = length prems;
   168     val ary = length prems;
   169 
   169 
   170     val _ = warning (Syntax.string_of_term @{context} goal);
   170     val _ = warning (Syntax.string_of_term @{context} goal);
   219 
   219 
   220 ML \<open>
   220 ML \<open>
   221 val proof0 =
   221 val proof0 =
   222   ((@{term "\<exists>x :: nat. p x"},
   222   ((@{term "\<exists>x :: nat. p x"},
   223     @{term "p (SOME x :: nat. p x)"}),
   223     @{term "p (SOME x :: nat. p x)"}),
   224    Rule (Sko_Ex, [Rule (Refl, [])]));
   224    Node (Sko_Ex, [Node (Refl, [])]));
   225 
   225 
   226 reconstruct_proof @{context} proof0;
   226 reconstruct_proof @{context} proof0;
   227 \<close>
   227 \<close>
   228 
   228 
   229 ML \<open>
   229 ML \<open>
   230 val proof1 =
   230 val proof1 =
   231   ((@{term "\<not> (\<forall>x :: nat. \<exists>y :: nat. p x y)"},
   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)"}),
   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, [])])])]));
   233    Node (Cong, [Node (Sko_All, [Node (Bind, [Node (Refl, [])])])]));
   234 
   234 
   235 reconstruct_proof @{context} proof1;
   235 reconstruct_proof @{context} proof1;
   236 \<close>
   236 \<close>
   237 
   237 
   238 ML \<open>
   238 ML \<open>
   239 val proof2 =
   239 val proof2 =
   240   ((@{term "\<forall>x :: nat. \<exists>y :: nat. \<exists>z :: nat. p x y z"},
   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)
   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)"}),
   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, [])])])]));
   243    Node (Bind, [Node (Sko_Ex, [Node (Sko_Ex, [Node (Refl, [])])])]));
   244 
   244 
   245 reconstruct_proof @{context} proof2
   245 reconstruct_proof @{context} proof2
   246 \<close>
   246 \<close>
   247 
   247 
   248 ML \<open>
   248 ML \<open>
   249 val proof3 =
   249 val proof3 =
   250   ((@{term "\<forall>x :: nat. \<exists>x :: nat. \<exists>x :: nat. p x x x"},
   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)"}),
   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, [])])])]));
   252    Node (Bind, [Node (Sko_Ex, [Node (Sko_Ex, [Node (Refl, [])])])]));
   253 
   253 
   254 reconstruct_proof @{context} proof3
   254 reconstruct_proof @{context} proof3
   255 \<close>
   255 \<close>
   256 
   256 
   257 ML \<open>
   257 ML \<open>
   258 val proof4 =
   258 val proof4 =
   259   ((@{term "\<forall>x :: nat. \<exists>x :: nat. \<exists>x :: nat. p x x x"},
   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)"}),
   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, [])])])]));
   261    Node (Bind, [Node (Bind, [Node (Sko_Ex, [Node (Refl, [])])])]));
   262 
   262 
   263 reconstruct_proof @{context} proof4
   263 reconstruct_proof @{context} proof4
   264 \<close>
   264 \<close>
   265 
   265 
   266 ML \<open>
   266 ML \<open>
   267 val proof5 =
   267 val proof5 =
   268   ((@{term "\<forall>x :: nat. q \<and> (\<exists>x :: nat. \<exists>x :: nat. p x x x)"},
   268   ((@{term "\<forall>x :: nat. q \<and> (\<exists>x :: nat. \<exists>x :: nat. p x x x)"},
   269     @{term "\<forall>x :: nat. q \<and>
   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))"}),
   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,
   271    Node (Bind, [Node (Cong, [Node (Refl, []), Node (Bind, [Node (Sko_Ex,
   272      [Rule (Refl, [])])])])]));
   272      [Node (Refl, [])])])])]));
   273 
   273 
   274 reconstruct_proof @{context} proof5
   274 reconstruct_proof @{context} proof5
   275 \<close>
   275 \<close>
   276 
   276 
   277 ML \<open>
   277 ML \<open>
   278 val proof6 =
   278 val proof6 =
   279   ((@{term "\<not> (\<forall>x :: nat. q \<and> (\<exists>x :: nat. \<forall>x :: nat. p x x x))"},
   279   ((@{term "\<not> (\<forall>x :: nat. p \<and> (\<exists>x :: nat. \<forall>x :: nat. q x x))"},
   280     @{term "\<not> (\<forall>x :: nat. q \<and>
   280     @{term "\<not> (\<forall>x :: nat. p \<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)))"}),
   281         (\<exists>x :: nat. q (SOME x :: nat. \<not> q x x) (SOME x. \<not> q x x)))"}),
   282    Rule (Cong, [Rule (Bind, [Rule (Cong, [Rule (Refl, []), Rule (Bind, [Rule (Sko_All,
   282    Node (Cong, [Node (Bind, [Node (Cong, [Node (Refl, []), Node (Bind, [Node (Sko_All,
   283      [Rule (Refl, [])])])])])]));
   283      [Node (Refl, [])])])])])]));
   284 
   284 
   285 reconstruct_proof @{context} proof6
   285 reconstruct_proof @{context} proof6
   286 \<close>
   286 \<close>
   287 
   287 
   288 ML \<open>
   288 ML \<open>
   289 val proof7 =
   289 val proof7 =
   290   ((@{term "\<not> \<not> (\<exists>x. p x)"},
   290   ((@{term "\<not> \<not> (\<exists>x. p x)"},
   291     @{term "\<not> \<not> p (SOME x. p x)"}),
   291     @{term "\<not> \<not> p (SOME x. p x)"}),
   292    Rule (Cong, [Rule (Cong, [Rule (Sko_Ex, [Rule (Refl, [])])])]));
   292    Node (Cong, [Node (Cong, [Node (Sko_Ex, [Node (Refl, [])])])]));
   293 
   293 
   294 reconstruct_proof @{context} proof7
   294 reconstruct_proof @{context} proof7
   295 \<close>
   295 \<close>
   296 
   296 
   297 ML \<open>
   297 ML \<open>
   298 val proof8 =
   298 val proof8 =
   299   ((@{term "\<not> \<not> (let x = Suc x in x = 0)"},
   299   ((@{term "\<not> \<not> (let x = Suc x in x = 0)"},
   300     @{term "\<not> \<not> Suc x = 0"}),
   300     @{term "\<not> \<not> Suc x = 0"}),
   301    Rule (Cong, [Rule (Cong, [Rule (Let [@{term "Suc x"}],
   301    Node (Cong, [Node (Cong, [Node (Let [@{term "Suc x"}],
   302      [Rule (Refl, []), Rule (Refl, [])])])]));
   302      [Node (Refl, []), Node (Refl, [])])])]));
   303 
   303 
   304 reconstruct_proof @{context} proof8
   304 reconstruct_proof @{context} proof8
   305 \<close>
   305 \<close>
   306 
   306 
   307 ML \<open>
   307 ML \<open>
   308 val proof9 =
   308 val proof9 =
   309   ((@{term "\<not> (let x = Suc x in x = 0)"},
   309   ((@{term "\<not> (let x = Suc x in x = 0)"},
   310     @{term "\<not> Suc x = 0"}),
   310     @{term "\<not> Suc x = 0"}),
   311    Rule (Cong, [Rule (Let [@{term "Suc x"}], [Rule (Refl, []), Rule (Refl, [])])]));
   311    Node (Cong, [Node (Let [@{term "Suc x"}], [Node (Refl, []), Node (Refl, [])])]));
   312 
   312 
   313 reconstruct_proof @{context} proof9
   313 reconstruct_proof @{context} proof9
   314 \<close>
   314 \<close>
   315 
   315 
   316 ML \<open>
   316 ML \<open>
   317 val proof10 =
   317 val proof10 =
   318   ((@{term "\<exists>x :: nat. p (x + 0)"},
   318   ((@{term "\<exists>x :: nat. p (x + 0)"},
   319     @{term "\<exists>x :: nat. p x"}),
   319     @{term "\<exists>x :: nat. p x"}),
   320    Rule (Bind, [Rule (Cong, [Rule (Taut @{thm add_0_right}, [])])]));
   320    Node (Bind, [Node (Cong, [Node (Taut @{thm add_0_right}, [])])]));
   321 
   321 
   322 reconstruct_proof @{context} proof10;
   322 reconstruct_proof @{context} proof10;
   323 \<close>
   323 \<close>
   324 
   324 
   325 ML \<open>
   325 ML \<open>
   326 val proof11 =
   326 val proof11 =
   327   ((@{term "\<not> (let (x, y) = (Suc y, Suc x) in y = 0)"},
   327   ((@{term "\<not> (let (x, y) = (Suc y, Suc x) in y = 0)"},
   328     @{term "\<not> Suc x = 0"}),
   328     @{term "\<not> Suc x = 0"}),
   329    Rule (Cong, [Rule (Let [@{term "Suc y"}, @{term "Suc x"}],
   329    Node (Cong, [Node (Let [@{term "Suc y"}, @{term "Suc x"}],
   330      [Rule (Refl, []), Rule (Refl, []), Rule (Refl, [])])]));
   330      [Node (Refl, []), Node (Refl, []), Node (Refl, [])])]));
   331 
   331 
   332 reconstruct_proof @{context} proof11
   332 reconstruct_proof @{context} proof11
   333 \<close>
   333 \<close>
   334 
   334 
   335 ML \<open>
   335 ML \<open>
   336 val proof12 =
   336 val proof12 =
   337   ((@{term "\<not> (let (x, y) = (Suc y, Suc x); (u, v, w) = (y, x, y) in w = 0)"},
   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"}),
   338     @{term "\<not> Suc x = 0"}),
   339    Rule (Cong, [Rule (Let [@{term "Suc y"}, @{term "Suc x"}],
   339    Node (Cong, [Node (Let [@{term "Suc y"}, @{term "Suc x"}],
   340      [Rule (Refl, []), Rule (Refl, []),
   340      [Node (Refl, []), Node (Refl, []),
   341        Rule (Let [@{term "Suc x"}, @{term "Suc y"}, @{term "Suc x"}],
   341        Node (Let [@{term "Suc x"}, @{term "Suc y"}, @{term "Suc x"}],
   342          [Rule (Refl, []), Rule (Refl, []), Rule (Refl, []), Rule (Refl, [])])])]));
   342          [Node (Refl, []), Node (Refl, []), Node (Refl, []), Node (Refl, [])])])]));
   343 
   343 
   344 reconstruct_proof @{context} proof12
   344 reconstruct_proof @{context} proof12
   345 \<close>
   345 \<close>
   346 
   346 
   347 ML \<open>
   347 ML \<open>
   348 val proof13 =
   348 val proof13 =
   349   ((@{term "\<not> \<not> (let x = Suc x in x = 0)"},
   349   ((@{term "\<not> \<not> (let x = Suc x in x = 0)"},
   350     @{term "\<not> \<not> Suc x = 0"}),
   350     @{term "\<not> \<not> Suc x = 0"}),
   351    Rule (Cong, [Rule (Cong, [Rule (Let [@{term "Suc x"}],
   351    Node (Cong, [Node (Cong, [Node (Let [@{term "Suc x"}],
   352      [Rule (Refl, []), Rule (Refl, [])])])]));
   352      [Node (Refl, []), Node (Refl, [])])])]));
   353 
   353 
   354 reconstruct_proof @{context} proof13
   354 reconstruct_proof @{context} proof13
   355 \<close>
   355 \<close>
   356 
   356 
   357 ML \<open>
   357 ML \<open>
   358 val proof14 =
   358 val proof14 =
   359   ((@{term "let (x, y) = (f (a :: nat), b :: nat) in x > a"},
   359   ((@{term "let (x, y) = (f (a :: nat), b :: nat) in x > a"},
   360     @{term "f (a :: nat) > a"}),
   360     @{term "f (a :: nat) > a"}),
   361    Rule (Let [@{term "f (a :: nat) :: nat"}, @{term "b :: nat"}],
   361    Node (Let [@{term "f (a :: nat) :: nat"}, @{term "b :: nat"}],
   362      [Rule (Cong, [Rule (Refl, [])]), Rule (Refl, []), Rule (Refl, [])]));
   362      [Node (Cong, [Node (Refl, [])]), Node (Refl, []), Node (Refl, [])]));
   363 
   363 
   364 reconstruct_proof @{context} proof14
   364 reconstruct_proof @{context} proof14
   365 \<close>
   365 \<close>
   366 
   366 
   367 ML \<open>
   367 ML \<open>
   368 val proof15 =
   368 val proof15 =
   369   ((@{term "let x = (let y = g (z :: nat) in f (y :: nat)) in x = Suc 0"},
   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"}),
   370     @{term "f (g (z :: nat) :: nat) = Suc 0"}),
   371    Rule (Let [@{term "f (g (z :: nat) :: nat) :: nat"}],
   371    Node (Let [@{term "f (g (z :: nat) :: nat) :: nat"}],
   372      [Rule (Let [@{term "g (z :: nat) :: nat"}], [Rule (Refl, []), Rule (Refl, [])]),
   372      [Node (Let [@{term "g (z :: nat) :: nat"}], [Node (Refl, []), Node (Refl, [])]),
   373       Rule (Refl, [])]));
   373       Node (Refl, [])]));
   374 
   374 
   375 reconstruct_proof @{context} proof15
   375 reconstruct_proof @{context} proof15
   376 \<close>
   376 \<close>
   377 
   377 
   378 ML \<open>
   378 ML \<open>
   379 val proof16 =
   379 val proof16 =
   380   ((@{term "a > Suc b"},
   380   ((@{term "a > Suc b"},
   381     @{term "a > Suc b"}),
   381     @{term "a > Suc b"}),
   382    Rule (Trans @{term "a > Suc b"}, [Rule (Refl, []), Rule (Refl, [])]));
   382    Node (Trans @{term "a > Suc b"}, [Node (Refl, []), Node (Refl, [])]));
   383 
   383 
   384 reconstruct_proof @{context} proof16
   384 reconstruct_proof @{context} proof16
   385 \<close>
   385 \<close>
   386 
   386 
   387 thm Suc_1
   387 thm Suc_1
   390 
   390 
   391 ML \<open>
   391 ML \<open>
   392 val proof17 =
   392 val proof17 =
   393   ((@{term "2 :: nat"},
   393   ((@{term "2 :: nat"},
   394     @{term "Suc (Suc 0) :: nat"}),
   394     @{term "Suc (Suc 0) :: nat"}),
   395    Rule (Trans @{term "Suc 1"}, [Rule (Taut @{thm Suc_1[symmetric]}, []),
   395    Node (Trans @{term "Suc 1"}, [Node (Taut @{thm Suc_1[symmetric]}, []),
   396      Rule (Cong, [Rule (Taut @{thm One_nat_def}, [])])]));
   396      Node (Cong, [Node (Taut @{thm One_nat_def}, [])])]));
   397 
   397 
   398 reconstruct_proof @{context} proof17
   398 reconstruct_proof @{context} proof17
   399 \<close>
   399 \<close>
   400 
   400 
   401 ML \<open>
   401 ML \<open>
   402 val proof18 =
   402 val proof18 =
   403   ((@{term "let x = a in let y = b in Suc x + y"},
   403   ((@{term "let x = a in let y = b in Suc x + y"},
   404     @{term "Suc a + b"}),
   404     @{term "Suc a + b"}),
   405    Rule (Trans @{term "let y = b in Suc a + y"},
   405    Node (Trans @{term "let y = b in Suc a + y"},
   406      [Rule (Let [@{term "a :: nat"}], [Rule (Refl, []), Rule (Refl, [])]),
   406      [Node (Let [@{term "a :: nat"}], [Node (Refl, []), Node (Refl, [])]),
   407       Rule (Let [@{term "b :: nat"}], [Rule (Refl, []), Rule (Refl, [])])]));
   407       Node (Let [@{term "b :: nat"}], [Node (Refl, []), Node (Refl, [])])]));
   408 
   408 
   409 reconstruct_proof @{context} proof18
   409 reconstruct_proof @{context} proof18
   410 \<close>
   410 \<close>
   411 
   411 
   412 ML \<open>
   412 ML \<open>
   413 val proof19 =
   413 val proof19 =
   414   ((@{term "\<forall>x. let x = f (x :: nat) :: nat in g x"},
   414   ((@{term "\<forall>x. let x = f (x :: nat) :: nat in g x"},
   415     @{term "\<forall>x. g (f (x :: nat) :: nat)"}),
   415     @{term "\<forall>x. g (f (x :: nat) :: nat)"}),
   416    Rule (Bind, [Rule (Let [@{term "f :: nat \<Rightarrow> nat"} $ Bound 0],
   416    Node (Bind, [Node (Let [@{term "f :: nat \<Rightarrow> nat"} $ Bound 0],
   417      [Rule (Refl, []), Rule (Refl, [])])]));
   417      [Node (Refl, []), Node (Refl, [])])]));
   418 
   418 
   419 reconstruct_proof @{context} proof19
   419 reconstruct_proof @{context} proof19
   420 \<close>
   420 \<close>
   421 
   421 
   422 ML \<open>
   422 ML \<open>
   423 val proof20 =
   423 val proof20 =
   424   ((@{term "\<forall>x. let y = Suc 0 in let x = f (x :: nat) :: nat in g x"},
   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)"}),
   425     @{term "\<forall>x. g (f (x :: nat) :: nat)"}),
   426    Rule (Bind, [Rule (Let [@{term "Suc 0"}],
   426    Node (Bind, [Node (Let [@{term "Suc 0"}],
   427      [Rule (Refl, []), Rule (Let [@{term "f (x :: nat) :: nat"}],
   427      [Node (Refl, []), Node (Let [@{term "f (x :: nat) :: nat"}],
   428         [Rule (Refl, []), Rule (Refl, [])])])]));
   428         [Node (Refl, []), Node (Refl, [])])])]));
   429 
   429 
   430 reconstruct_proof @{context} proof20
   430 reconstruct_proof @{context} proof20
   431 \<close>
   431 \<close>
   432 
   432 
   433 ML \<open>
   433 ML \<open>
   434 val proof21 =
   434 val proof21 =
   435   ((@{term "\<forall>x :: nat. let x = f x :: nat in let y = x in p y"},
   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)"}),
   436     @{term "\<forall>z :: nat. p (f z :: nat)"}),
   437    Rule (Bind, [Rule (Let [@{term "f (z :: nat) :: nat"}],
   437    Node (Bind, [Node (Let [@{term "f (z :: nat) :: nat"}],
   438      [Rule (Refl, []), Rule (Let [@{term "f (z :: nat) :: nat"}],
   438      [Node (Refl, []), Node (Let [@{term "f (z :: nat) :: nat"}],
   439         [Rule (Refl, []), Rule (Refl, [])])])]));
   439         [Node (Refl, []), Node (Refl, [])])])]));
   440 
   440 
   441 reconstruct_proof @{context} proof21
   441 reconstruct_proof @{context} proof21
   442 \<close>
   442 \<close>
   443 
   443 
   444 ML \<open>
   444 ML \<open>
   445 val proof22 =
   445 val proof22 =
   446   ((@{term "\<forall>x :: nat. let x = f x :: nat in let y = x in p y"},
   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)"}),
   447     @{term "\<forall>x :: nat. p (f x :: nat)"}),
   448    Rule (Bind, [Rule (Let [@{term "f (x :: nat) :: nat"}],
   448    Node (Bind, [Node (Let [@{term "f (x :: nat) :: nat"}],
   449      [Rule (Refl, []), Rule (Let [@{term "f (x :: nat) :: nat"}],
   449      [Node (Refl, []), Node (Let [@{term "f (x :: nat) :: nat"}],
   450         [Rule (Refl, []), Rule (Refl, [])])])]));
   450         [Node (Refl, []), Node (Refl, [])])])]));
   451 
   451 
   452 reconstruct_proof @{context} proof22
   452 reconstruct_proof @{context} proof22
   453 \<close>
   453 \<close>
   454 
   454 
   455 ML \<open>
   455 ML \<open>
   456 val proof23 =
   456 val proof23 =
   457   ((@{term "\<forall>x :: nat. let (x, a) = (f x :: nat, 0 ::nat) in let y = x in p y"},
   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)"}),
   458     @{term "\<forall>z :: nat. p (f z :: nat)"}),
   459    Rule (Bind, [Rule (Let [@{term "f (z :: nat) :: nat"}, @{term "0 :: nat"}],
   459    Node (Bind, [Node (Let [@{term "f (z :: nat) :: nat"}, @{term "0 :: nat"}],
   460      [Rule (Refl, []), Rule (Refl, []), Rule (Let [@{term "f (z :: nat) :: nat"}],
   460      [Node (Refl, []), Node (Refl, []), Node (Let [@{term "f (z :: nat) :: nat"}],
   461         [Rule (Refl, []), Rule (Refl, [])])])]));
   461         [Node (Refl, []), Node (Refl, [])])])]));
   462 
   462 
   463 reconstruct_proof @{context} proof23
   463 reconstruct_proof @{context} proof23
   464 \<close>
   464 \<close>
   465 
   465 
   466 ML \<open>
   466 ML \<open>
   467 val proof24 =
   467 val proof24 =
   468   ((@{term "\<forall>x :: nat. let (x, a) = (f x :: nat, 0 ::nat) in let y = x in p y"},
   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)"}),
   469     @{term "\<forall>x :: nat. p (f x :: nat)"}),
   470    Rule (Bind, [Rule (Let [@{term "f (x :: nat) :: nat"}, @{term "0 :: nat"}],
   470    Node (Bind, [Node (Let [@{term "f (x :: nat) :: nat"}, @{term "0 :: nat"}],
   471      [Rule (Refl, []), Rule (Refl, []), Rule (Let [@{term "f (x :: nat) :: nat"}],
   471      [Node (Refl, []), Node (Refl, []), Node (Let [@{term "f (x :: nat) :: nat"}],
   472         [Rule (Refl, []), Rule (Refl, [])])])]));
   472         [Node (Refl, []), Node (Refl, [])])])]));
   473 
   473 
   474 reconstruct_proof @{context} proof24
   474 reconstruct_proof @{context} proof24
   475 \<close>
   475 \<close>
   476 
   476 
   477 end
   477 end