src/ZF/ex/Primrec.ML
changeset 1461 6bcb44e4d6e5
parent 782 200a16083201
child 2469 b50b8c0eec01
equal deleted inserted replaced
1460:5a6f2aabd538 1461:6bcb44e4d6e5
     1 (*  Title: 	ZF/ex/Primrec
     1 (*  Title:      ZF/ex/Primrec
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1994  University of Cambridge
     4     Copyright   1994  University of Cambridge
     5 
     5 
     6 Primitive Recursive Functions
     6 Primitive Recursive Functions
     7 
     7 
     8 Proof adopted from
     8 Proof adopted from
    23 (** Useful special cases of evaluation ***)
    23 (** Useful special cases of evaluation ***)
    24 
    24 
    25 val pr_ss = arith_ss 
    25 val pr_ss = arith_ss 
    26     addsimps list.case_eqns
    26     addsimps list.case_eqns
    27     addsimps [list_rec_Nil, list_rec_Cons, 
    27     addsimps [list_rec_Nil, list_rec_Cons, 
    28 	      drop_0, drop_Nil, drop_succ_Cons,
    28               drop_0, drop_Nil, drop_succ_Cons,
    29 	      map_Nil, map_Cons]
    29               map_Nil, map_Cons]
    30     setsolver (type_auto_tac pr_typechecks);
    30     setsolver (type_auto_tac pr_typechecks);
    31 
    31 
    32 goalw Primrec.thy [SC_def]
    32 goalw Primrec.thy [SC_def]
    33     "!!x l. [| x:nat;  l: list(nat) |] ==> SC ` (Cons(x,l)) = succ(x)";
    33     "!!x l. [| x:nat;  l: list(nat) |] ==> SC ` (Cons(x,l)) = succ(x)";
    34 by (asm_simp_tac pr_ss 1);
    34 by (asm_simp_tac pr_ss 1);
    66 (* c: primrec ==> c: list(nat) -> nat *)
    66 (* c: primrec ==> c: list(nat) -> nat *)
    67 val primrec_into_fun = primrec.dom_subset RS subsetD;
    67 val primrec_into_fun = primrec.dom_subset RS subsetD;
    68 
    68 
    69 val pr_ss = pr_ss 
    69 val pr_ss = pr_ss 
    70     setsolver (type_auto_tac ([primrec_into_fun] @ 
    70     setsolver (type_auto_tac ([primrec_into_fun] @ 
    71 			      pr_typechecks @ primrec.intrs));
    71                               pr_typechecks @ primrec.intrs));
    72 
    72 
    73 goalw Primrec.thy [ACK_def] "!!i. i:nat ==> ACK(i): primrec";
    73 goalw Primrec.thy [ACK_def] "!!i. i:nat ==> ACK(i): primrec";
    74 by (etac nat_induct 1);
    74 by (etac nat_induct 1);
    75 by (ALLGOALS (asm_simp_tac pr_ss));
    75 by (ALLGOALS (asm_simp_tac pr_ss));
    76 qed "ACK_in_primrec";
    76 qed "ACK_in_primrec";
   110 by (asm_simp_tac (pr_ss addsimps [CONST,PREC_succ,COMP_1,PROJ_0]) 1);
   110 by (asm_simp_tac (pr_ss addsimps [CONST,PREC_succ,COMP_1,PROJ_0]) 1);
   111 qed "ack_succ_succ";
   111 qed "ack_succ_succ";
   112 
   112 
   113 val ack_ss = 
   113 val ack_ss = 
   114     pr_ss addsimps [ack_0, ack_succ_0, ack_succ_succ, 
   114     pr_ss addsimps [ack_0, ack_succ_0, ack_succ_succ, 
   115 		    ack_type, nat_into_Ord];
   115                     ack_type, nat_into_Ord];
   116 
   116 
   117 (*PROPERTY A 4*)
   117 (*PROPERTY A 4*)
   118 goal Primrec.thy "!!i. i:nat ==> ALL j:nat. j < ack(i,j)";
   118 goal Primrec.thy "!!i. i:nat ==> ALL j:nat. j < ack(i,j)";
   119 by (etac nat_induct 1);
   119 by (etac nat_induct 1);
   120 by (asm_simp_tac ack_ss 1);
   120 by (asm_simp_tac ack_ss 1);
   121 by (rtac ballI 1);
   121 by (rtac ballI 1);
   122 by (eres_inst_tac [("n","j")] nat_induct 1);
   122 by (eres_inst_tac [("n","j")] nat_induct 1);
   123 by (DO_GOAL [rtac (nat_0I RS nat_0_le RS lt_trans),
   123 by (DO_GOAL [rtac (nat_0I RS nat_0_le RS lt_trans),
   124 	     asm_simp_tac ack_ss] 1);
   124              asm_simp_tac ack_ss] 1);
   125 by (DO_GOAL [etac (succ_leI RS lt_trans1),
   125 by (DO_GOAL [etac (succ_leI RS lt_trans1),
   126 	     asm_simp_tac ack_ss] 1);
   126              asm_simp_tac ack_ss] 1);
   127 qed "lt_ack2_lemma";
   127 qed "lt_ack2_lemma";
   128 bind_thm ("lt_ack2", (lt_ack2_lemma RS bspec));
   128 bind_thm ("lt_ack2", (lt_ack2_lemma RS bspec));
   129 
   129 
   130 (*PROPERTY A 5-, the single-step lemma*)
   130 (*PROPERTY A 5-, the single-step lemma*)
   131 goal Primrec.thy "!!i j. [| i:nat; j:nat |] ==> ack(i,j) < ack(i, succ(j))";
   131 goal Primrec.thy "!!i j. [| i:nat; j:nat |] ==> ack(i,j) < ack(i, succ(j))";
   271 val PROJ_case = PROJ_case_lemma RS bspec;
   271 val PROJ_case = PROJ_case_lemma RS bspec;
   272 
   272 
   273 (** COMP case **)
   273 (** COMP case **)
   274 
   274 
   275 goal Primrec.thy
   275 goal Primrec.thy
   276  "!!fs. fs : list({f: primrec .					\
   276  "!!fs. fs : list({f: primrec .                                 \
   277 \              	   EX kf:nat. ALL l:list(nat). 			\
   277 \                  EX kf:nat. ALL l:list(nat).                  \
   278 \		    	      f`l < ack(kf, list_add(l))})	\
   278 \                             f`l < ack(kf, list_add(l))})      \
   279 \      ==> EX k:nat. ALL l: list(nat). 				\
   279 \      ==> EX k:nat. ALL l: list(nat).                          \
   280 \                list_add(map(%f. f ` l, fs)) < ack(k, list_add(l))";
   280 \                list_add(map(%f. f ` l, fs)) < ack(k, list_add(l))";
   281 by (etac list.induct 1);
   281 by (etac list.induct 1);
   282 by (DO_GOAL [res_inst_tac [("x","0")] bexI,
   282 by (DO_GOAL [res_inst_tac [("x","0")] bexI,
   283 	     asm_simp_tac (ack2_ss addsimps [lt_ack1, nat_0_le]),
   283              asm_simp_tac (ack2_ss addsimps [lt_ack1, nat_0_le]),
   284 	     resolve_tac nat_typechecks] 1);
   284              resolve_tac nat_typechecks] 1);
   285 by (safe_tac ZF_cs);
   285 by (safe_tac ZF_cs);
   286 by (asm_simp_tac ack2_ss 1);
   286 by (asm_simp_tac ack2_ss 1);
   287 by (rtac (ballI RS bexI) 1);
   287 by (rtac (ballI RS bexI) 1);
   288 by (rtac (add_lt_mono RS lt_trans) 1);
   288 by (rtac (add_lt_mono RS lt_trans) 1);
   289 by (REPEAT (FIRSTGOAL (etac bspec)));
   289 by (REPEAT (FIRSTGOAL (etac bspec)));
   290 by (rtac ack_add_bound 5);
   290 by (rtac ack_add_bound 5);
   291 by (tc_tac []);
   291 by (tc_tac []);
   292 qed "COMP_map_lemma";
   292 qed "COMP_map_lemma";
   293 
   293 
   294 goalw Primrec.thy [COMP_def]
   294 goalw Primrec.thy [COMP_def]
   295  "!!g. [| g: primrec;  kg: nat;					\
   295  "!!g. [| g: primrec;  kg: nat;                                 \
   296 \         ALL l:list(nat). g`l < ack(kg, list_add(l));		\
   296 \         ALL l:list(nat). g`l < ack(kg, list_add(l));          \
   297 \         fs : list({f: primrec .				\
   297 \         fs : list({f: primrec .                               \
   298 \                    EX kf:nat. ALL l:list(nat). 		\
   298 \                    EX kf:nat. ALL l:list(nat).                \
   299 \		    	f`l < ack(kf, list_add(l))}) 		\
   299 \                       f`l < ack(kf, list_add(l))})            \
   300 \      |] ==> EX k:nat. ALL l: list(nat). COMP(g,fs)`l < ack(k, list_add(l))";
   300 \      |] ==> EX k:nat. ALL l: list(nat). COMP(g,fs)`l < ack(k, list_add(l))";
   301 by (asm_simp_tac ZF_ss 1);
   301 by (asm_simp_tac ZF_ss 1);
   302 by (forward_tac [list_CollectD] 1);
   302 by (forward_tac [list_CollectD] 1);
   303 by (etac (COMP_map_lemma RS bexE) 1);
   303 by (etac (COMP_map_lemma RS bexE) 1);
   304 by (rtac (ballI RS bexI) 1);
   304 by (rtac (ballI RS bexI) 1);
   310 qed "COMP_case";
   310 qed "COMP_case";
   311 
   311 
   312 (** PREC case **)
   312 (** PREC case **)
   313 
   313 
   314 goalw Primrec.thy [PREC_def]
   314 goalw Primrec.thy [PREC_def]
   315  "!!f g. [| ALL l:list(nat). f`l #+ list_add(l) < ack(kf, list_add(l));	\
   315  "!!f g. [| ALL l:list(nat). f`l #+ list_add(l) < ack(kf, list_add(l)); \
   316 \           ALL l:list(nat). g`l #+ list_add(l) < ack(kg, list_add(l));	\
   316 \           ALL l:list(nat). g`l #+ list_add(l) < ack(kg, list_add(l)); \
   317 \           f: primrec;  kf: nat;					\
   317 \           f: primrec;  kf: nat;                                       \
   318 \           g: primrec;  kg: nat;					\
   318 \           g: primrec;  kg: nat;                                       \
   319 \           l: list(nat)						\
   319 \           l: list(nat)                                                \
   320 \        |] ==> PREC(f,g)`l #+ list_add(l) < ack(succ(kf#+kg), list_add(l))";
   320 \        |] ==> PREC(f,g)`l #+ list_add(l) < ack(succ(kf#+kg), list_add(l))";
   321 by (etac list.elim 1);
   321 by (etac list.elim 1);
   322 by (asm_simp_tac (ack2_ss addsimps [[nat_le_refl, lt_ack2] MRS lt_trans]) 1);
   322 by (asm_simp_tac (ack2_ss addsimps [[nat_le_refl, lt_ack2] MRS lt_trans]) 1);
   323 by (asm_simp_tac ack2_ss 1);
   323 by (asm_simp_tac ack2_ss 1);
   324 by (etac ssubst 1);  (*get rid of the needless assumption*)
   324 by (etac ssubst 1);  (*get rid of the needless assumption*)
   325 by (eres_inst_tac [("n","a")] nat_induct 1);
   325 by (eres_inst_tac [("n","a")] nat_induct 1);
   326 (*base case*)
   326 (*base case*)
   327 by (DO_GOAL [asm_simp_tac ack2_ss, rtac lt_trans, etac bspec,
   327 by (DO_GOAL [asm_simp_tac ack2_ss, rtac lt_trans, etac bspec,
   328 	     assume_tac, rtac (add_le_self RS ack_lt_mono1),
   328              assume_tac, rtac (add_le_self RS ack_lt_mono1),
   329 	     REPEAT o ares_tac (ack_typechecks)] 1);
   329              REPEAT o ares_tac (ack_typechecks)] 1);
   330 (*ind step*)
   330 (*ind step*)
   331 by (asm_simp_tac (ack2_ss addsimps [add_succ_right]) 1);
   331 by (asm_simp_tac (ack2_ss addsimps [add_succ_right]) 1);
   332 by (rtac (succ_leI RS lt_trans1) 1);
   332 by (rtac (succ_leI RS lt_trans1) 1);
   333 by (res_inst_tac [("j", "g ` ?ll #+ ?mm")] lt_trans1 1);
   333 by (res_inst_tac [("j", "g ` ?ll #+ ?mm")] lt_trans1 1);
   334 by (etac bspec 2);
   334 by (etac bspec 2);
   341 by (etac ack_lt_mono2 5);
   341 by (etac ack_lt_mono2 5);
   342 by (tc_tac []);
   342 by (tc_tac []);
   343 qed "PREC_case_lemma";
   343 qed "PREC_case_lemma";
   344 
   344 
   345 goal Primrec.thy
   345 goal Primrec.thy
   346  "!!f g. [| f: primrec;  kf: nat;				\
   346  "!!f g. [| f: primrec;  kf: nat;                               \
   347 \           g: primrec;  kg: nat;				\
   347 \           g: primrec;  kg: nat;                               \
   348 \           ALL l:list(nat). f`l < ack(kf, list_add(l));	\
   348 \           ALL l:list(nat). f`l < ack(kf, list_add(l));        \
   349 \           ALL l:list(nat). g`l < ack(kg, list_add(l)) 	\
   349 \           ALL l:list(nat). g`l < ack(kg, list_add(l))         \
   350 \        |] ==> EX k:nat. ALL l: list(nat). 			\
   350 \        |] ==> EX k:nat. ALL l: list(nat).                     \
   351 \		    PREC(f,g)`l< ack(k, list_add(l))";
   351 \                   PREC(f,g)`l< ack(k, list_add(l))";
   352 by (rtac (ballI RS bexI) 1);
   352 by (rtac (ballI RS bexI) 1);
   353 by (rtac ([add_le_self, PREC_case_lemma] MRS lt_trans1) 1);
   353 by (rtac ([add_le_self, PREC_case_lemma] MRS lt_trans1) 1);
   354 by (REPEAT
   354 by (REPEAT
   355     (SOMEGOAL
   355     (SOMEGOAL
   356      (FIRST' [test_assume_tac,
   356      (FIRST' [test_assume_tac,
   357 	      match_tac (ack_typechecks),
   357               match_tac (ack_typechecks),
   358 	      rtac (ack_add_bound2 RS ballI) THEN' etac bspec])));
   358               rtac (ack_add_bound2 RS ballI) THEN' etac bspec])));
   359 qed "PREC_case";
   359 qed "PREC_case";
   360 
   360 
   361 goal Primrec.thy
   361 goal Primrec.thy
   362     "!!f. f:primrec ==> EX k:nat. ALL l:list(nat). f`l < ack(k, list_add(l))";
   362     "!!f. f:primrec ==> EX k:nat. ALL l:list(nat). f`l < ack(k, list_add(l))";
   363 by (etac primrec.induct 1);
   363 by (etac primrec.induct 1);
   364 by (safe_tac ZF_cs);
   364 by (safe_tac ZF_cs);
   365 by (DEPTH_SOLVE
   365 by (DEPTH_SOLVE
   366     (ares_tac ([SC_case, CONST_case, PROJ_case, COMP_case, PREC_case,
   366     (ares_tac ([SC_case, CONST_case, PROJ_case, COMP_case, PREC_case,
   367 		       bexI, ballI] @ nat_typechecks) 1));
   367                        bexI, ballI] @ nat_typechecks) 1));
   368 qed "ack_bounds_primrec";
   368 qed "ack_bounds_primrec";
   369 
   369 
   370 goal Primrec.thy
   370 goal Primrec.thy
   371     "~ (lam l:list(nat). list_case(0, %x xs. ack(x,x), l)) : primrec";
   371     "~ (lam l:list(nat). list_case(0, %x xs. ack(x,x), l)) : primrec";
   372 by (rtac notI 1);
   372 by (rtac notI 1);