src/HOL/Induct/SList.ML
changeset 5069 3ea049f7979d
parent 4831 dae4d63a1318
child 5143 b94cd208f073
equal deleted inserted replaced
5068:fb28eaa07e01 5069:3ea049f7979d
     8 
     8 
     9 open SList;
     9 open SList;
    10 
    10 
    11 val list_con_defs = [NIL_def, CONS_def];
    11 val list_con_defs = [NIL_def, CONS_def];
    12 
    12 
    13 goal SList.thy "list(A) = {Numb(0)} <+> (A <*> list(A))";
    13 Goal "list(A) = {Numb(0)} <+> (A <*> list(A))";
    14 let val rew = rewrite_rule list_con_defs in  
    14 let val rew = rewrite_rule list_con_defs in  
    15 by (fast_tac (claset() addSIs (equalityI :: map rew list.intrs)
    15 by (fast_tac (claset() addSIs (equalityI :: map rew list.intrs)
    16                       addEs [rew list.elim]) 1)
    16                       addEs [rew list.elim]) 1)
    17 end;
    17 end;
    18 qed "list_unfold";
    18 qed "list_unfold";
    19 
    19 
    20 (*This justifies using list in other recursive type definitions*)
    20 (*This justifies using list in other recursive type definitions*)
    21 goalw SList.thy list.defs "!!A B. A<=B ==> list(A) <= list(B)";
    21 Goalw list.defs "!!A B. A<=B ==> list(A) <= list(B)";
    22 by (rtac lfp_mono 1);
    22 by (rtac lfp_mono 1);
    23 by (REPEAT (ares_tac basic_monos 1));
    23 by (REPEAT (ares_tac basic_monos 1));
    24 qed "list_mono";
    24 qed "list_mono";
    25 
    25 
    26 (*Type checking -- list creates well-founded sets*)
    26 (*Type checking -- list creates well-founded sets*)
    27 goalw SList.thy (list_con_defs @ list.defs) "list(sexp) <= sexp";
    27 Goalw (list_con_defs @ list.defs) "list(sexp) <= sexp";
    28 by (rtac lfp_lowerbound 1);
    28 by (rtac lfp_lowerbound 1);
    29 by (fast_tac (claset() addIs sexp.intrs@[sexp_In0I,sexp_In1I]) 1);
    29 by (fast_tac (claset() addIs sexp.intrs@[sexp_In0I,sexp_In1I]) 1);
    30 qed "list_sexp";
    30 qed "list_sexp";
    31 
    31 
    32 (* A <= sexp ==> list(A) <= sexp *)
    32 (* A <= sexp ==> list(A) <= sexp *)
    47     EVERY [res_inst_tac [("l",a)] list_induct2 M,
    47     EVERY [res_inst_tac [("l",a)] list_induct2 M,
    48            rename_last_tac a ["1"] (M+1)];
    48            rename_last_tac a ["1"] (M+1)];
    49 
    49 
    50 (*** Isomorphisms ***)
    50 (*** Isomorphisms ***)
    51 
    51 
    52 goal SList.thy "inj(Rep_list)";
    52 Goal "inj(Rep_list)";
    53 by (rtac inj_inverseI 1);
    53 by (rtac inj_inverseI 1);
    54 by (rtac Rep_list_inverse 1);
    54 by (rtac Rep_list_inverse 1);
    55 qed "inj_Rep_list";
    55 qed "inj_Rep_list";
    56 
    56 
    57 goal SList.thy "inj_on Abs_list (list(range Leaf))";
    57 Goal "inj_on Abs_list (list(range Leaf))";
    58 by (rtac inj_on_inverseI 1);
    58 by (rtac inj_on_inverseI 1);
    59 by (etac Abs_list_inverse 1);
    59 by (etac Abs_list_inverse 1);
    60 qed "inj_on_Abs_list";
    60 qed "inj_on_Abs_list";
    61 
    61 
    62 (** Distinctness of constructors **)
    62 (** Distinctness of constructors **)
    63 
    63 
    64 goalw SList.thy list_con_defs "CONS M N ~= NIL";
    64 Goalw list_con_defs "CONS M N ~= NIL";
    65 by (rtac In1_not_In0 1);
    65 by (rtac In1_not_In0 1);
    66 qed "CONS_not_NIL";
    66 qed "CONS_not_NIL";
    67 bind_thm ("NIL_not_CONS", (CONS_not_NIL RS not_sym));
    67 bind_thm ("NIL_not_CONS", (CONS_not_NIL RS not_sym));
    68 
    68 
    69 bind_thm ("CONS_neq_NIL", (CONS_not_NIL RS notE));
    69 bind_thm ("CONS_neq_NIL", (CONS_not_NIL RS notE));
    70 val NIL_neq_CONS = sym RS CONS_neq_NIL;
    70 val NIL_neq_CONS = sym RS CONS_neq_NIL;
    71 
    71 
    72 goalw SList.thy [Nil_def,Cons_def] "x # xs ~= Nil";
    72 Goalw [Nil_def,Cons_def] "x # xs ~= Nil";
    73 by (rtac (CONS_not_NIL RS (inj_on_Abs_list RS inj_on_contraD)) 1);
    73 by (rtac (CONS_not_NIL RS (inj_on_Abs_list RS inj_on_contraD)) 1);
    74 by (REPEAT (resolve_tac (list.intrs @ [rangeI, Rep_list]) 1));
    74 by (REPEAT (resolve_tac (list.intrs @ [rangeI, Rep_list]) 1));
    75 qed "Cons_not_Nil";
    75 qed "Cons_not_Nil";
    76 
    76 
    77 bind_thm ("Nil_not_Cons", Cons_not_Nil RS not_sym);
    77 bind_thm ("Nil_not_Cons", Cons_not_Nil RS not_sym);
    78 
    78 
    79 (** Injectiveness of CONS and Cons **)
    79 (** Injectiveness of CONS and Cons **)
    80 
    80 
    81 goalw SList.thy [CONS_def] "(CONS K M=CONS L N) = (K=L & M=N)";
    81 Goalw [CONS_def] "(CONS K M=CONS L N) = (K=L & M=N)";
    82 by (fast_tac (claset() addSEs [Scons_inject, make_elim In1_inject]) 1);
    82 by (fast_tac (claset() addSEs [Scons_inject, make_elim In1_inject]) 1);
    83 qed "CONS_CONS_eq";
    83 qed "CONS_CONS_eq";
    84 
    84 
    85 (*For reasoning about abstract list constructors*)
    85 (*For reasoning about abstract list constructors*)
    86 AddIs ([Rep_list] @ list.intrs);
    86 AddIs ([Rep_list] @ list.intrs);
    88 AddIffs [CONS_not_NIL, NIL_not_CONS, CONS_CONS_eq];
    88 AddIffs [CONS_not_NIL, NIL_not_CONS, CONS_CONS_eq];
    89 
    89 
    90 AddSDs [inj_on_Abs_list RS inj_onD,
    90 AddSDs [inj_on_Abs_list RS inj_onD,
    91         inj_Rep_list RS injD, Leaf_inject];
    91         inj_Rep_list RS injD, Leaf_inject];
    92 
    92 
    93 goalw SList.thy [Cons_def] "(x#xs=y#ys) = (x=y & xs=ys)";
    93 Goalw [Cons_def] "(x#xs=y#ys) = (x=y & xs=ys)";
    94 by (Fast_tac 1);
    94 by (Fast_tac 1);
    95 qed "Cons_Cons_eq";
    95 qed "Cons_Cons_eq";
    96 bind_thm ("Cons_inject2", (Cons_Cons_eq RS iffD1 RS conjE));
    96 bind_thm ("Cons_inject2", (Cons_Cons_eq RS iffD1 RS conjE));
    97 
    97 
    98 val [major] = goal SList.thy "CONS M N: list(A) ==> M: A & N: list(A)";
    98 val [major] = goal SList.thy "CONS M N: list(A) ==> M: A & N: list(A)";
   111 (*Reasoning about constructors and their freeness*)
   111 (*Reasoning about constructors and their freeness*)
   112 Addsimps list.intrs;
   112 Addsimps list.intrs;
   113 
   113 
   114 AddIffs [Cons_not_Nil, Nil_not_Cons, Cons_Cons_eq];
   114 AddIffs [Cons_not_Nil, Nil_not_Cons, Cons_Cons_eq];
   115 
   115 
   116 goal SList.thy "!!N. N: list(A) ==> !M. N ~= CONS M N";
   116 Goal "!!N. N: list(A) ==> !M. N ~= CONS M N";
   117 by (etac list.induct 1);
   117 by (etac list.induct 1);
   118 by (ALLGOALS Asm_simp_tac);
   118 by (ALLGOALS Asm_simp_tac);
   119 qed "not_CONS_self";
   119 qed "not_CONS_self";
   120 
   120 
   121 goal SList.thy "!x. l ~= x#l";
   121 Goal "!x. l ~= x#l";
   122 by (list_ind_tac "l" 1);
   122 by (list_ind_tac "l" 1);
   123 by (ALLGOALS Asm_simp_tac);
   123 by (ALLGOALS Asm_simp_tac);
   124 qed "not_Cons_self2";
   124 qed "not_Cons_self2";
   125 
   125 
   126 
   126 
   127 goal SList.thy "(xs ~= []) = (? y ys. xs = y#ys)";
   127 Goal "(xs ~= []) = (? y ys. xs = y#ys)";
   128 by (list_ind_tac "xs" 1);
   128 by (list_ind_tac "xs" 1);
   129 by (Simp_tac 1);
   129 by (Simp_tac 1);
   130 by (Asm_simp_tac 1);
   130 by (Asm_simp_tac 1);
   131 by (REPEAT(resolve_tac [exI,refl,conjI] 1));
   131 by (REPEAT(resolve_tac [exI,refl,conjI] 1));
   132 qed "neq_Nil_conv2";
   132 qed "neq_Nil_conv2";
   133 
   133 
   134 (** Conversion rules for List_case: case analysis operator **)
   134 (** Conversion rules for List_case: case analysis operator **)
   135 
   135 
   136 goalw SList.thy [List_case_def,NIL_def] "List_case c h NIL = c";
   136 Goalw [List_case_def,NIL_def] "List_case c h NIL = c";
   137 by (rtac Case_In0 1);
   137 by (rtac Case_In0 1);
   138 qed "List_case_NIL";
   138 qed "List_case_NIL";
   139 
   139 
   140 goalw SList.thy [List_case_def,CONS_def]  "List_case c h (CONS M N) = h M N";
   140 Goalw [List_case_def,CONS_def]  "List_case c h (CONS M N) = h M N";
   141 by (Simp_tac 1);
   141 by (Simp_tac 1);
   142 qed "List_case_CONS";
   142 qed "List_case_CONS";
   143 
   143 
   144 Addsimps [List_case_NIL, List_case_CONS];
   144 Addsimps [List_case_NIL, List_case_CONS];
   145 
   145 
   147 (*** List_rec -- by wf recursion on pred_sexp ***)
   147 (*** List_rec -- by wf recursion on pred_sexp ***)
   148 
   148 
   149 (* The trancl(pred_sexp) is essential because pred_sexp_CONS_I1,2 would not
   149 (* The trancl(pred_sexp) is essential because pred_sexp_CONS_I1,2 would not
   150    hold if pred_sexp^+ were changed to pred_sexp. *)
   150    hold if pred_sexp^+ were changed to pred_sexp. *)
   151 
   151 
   152 goal SList.thy
   152 Goal
   153    "(%M. List_rec M c d) = wfrec (trancl pred_sexp) \
   153    "(%M. List_rec M c d) = wfrec (trancl pred_sexp) \
   154                            \     (%g. List_case c (%x y. d x y (g y)))";
   154                            \     (%g. List_case c (%x y. d x y (g y)))";
   155 by (simp_tac (HOL_ss addsimps [List_rec_def]) 1);
   155 by (simp_tac (HOL_ss addsimps [List_rec_def]) 1);
   156 val List_rec_unfold = standard 
   156 val List_rec_unfold = standard 
   157   ((wf_pred_sexp RS wf_trancl) RS ((result() RS eq_reflection) RS def_wfrec));
   157   ((wf_pred_sexp RS wf_trancl) RS ((result() RS eq_reflection) RS def_wfrec));
   162  *                     |> standard;
   162  *                     |> standard;
   163  *---------------------------------------------------------------------------*)
   163  *---------------------------------------------------------------------------*)
   164 
   164 
   165 (** pred_sexp lemmas **)
   165 (** pred_sexp lemmas **)
   166 
   166 
   167 goalw SList.thy [CONS_def,In1_def]
   167 Goalw [CONS_def,In1_def]
   168     "!!M. [| M: sexp;  N: sexp |] ==> (M, CONS M N) : pred_sexp^+";
   168     "!!M. [| M: sexp;  N: sexp |] ==> (M, CONS M N) : pred_sexp^+";
   169 by (Asm_simp_tac 1);
   169 by (Asm_simp_tac 1);
   170 qed "pred_sexp_CONS_I1";
   170 qed "pred_sexp_CONS_I1";
   171 
   171 
   172 goalw SList.thy [CONS_def,In1_def]
   172 Goalw [CONS_def,In1_def]
   173     "!!M. [| M: sexp;  N: sexp |] ==> (N, CONS M N) : pred_sexp^+";
   173     "!!M. [| M: sexp;  N: sexp |] ==> (N, CONS M N) : pred_sexp^+";
   174 by (Asm_simp_tac 1);
   174 by (Asm_simp_tac 1);
   175 qed "pred_sexp_CONS_I2";
   175 qed "pred_sexp_CONS_I2";
   176 
   176 
   177 val [prem] = goal SList.thy
   177 val [prem] = goal SList.thy
   184                       prem RSN (2, trans_trancl RS transD)] 1));
   184                       prem RSN (2, trans_trancl RS transD)] 1));
   185 qed "pred_sexp_CONS_D";
   185 qed "pred_sexp_CONS_D";
   186 
   186 
   187 (** Conversion rules for List_rec **)
   187 (** Conversion rules for List_rec **)
   188 
   188 
   189 goal SList.thy "List_rec NIL c h = c";
   189 Goal "List_rec NIL c h = c";
   190 by (rtac (List_rec_unfold RS trans) 1);
   190 by (rtac (List_rec_unfold RS trans) 1);
   191 by (Simp_tac 1);
   191 by (Simp_tac 1);
   192 qed "List_rec_NIL";
   192 qed "List_rec_NIL";
   193 
   193 
   194 goal SList.thy "!!M. [| M: sexp;  N: sexp |] ==> \
   194 Goal "!!M. [| M: sexp;  N: sexp |] ==> \
   195 \    List_rec (CONS M N) c h = h M N (List_rec N c h)";
   195 \    List_rec (CONS M N) c h = h M N (List_rec N c h)";
   196 by (rtac (List_rec_unfold RS trans) 1);
   196 by (rtac (List_rec_unfold RS trans) 1);
   197 by (asm_simp_tac (simpset() addsimps [pred_sexp_CONS_I2]) 1);
   197 by (asm_simp_tac (simpset() addsimps [pred_sexp_CONS_I2]) 1);
   198 qed "List_rec_CONS";
   198 qed "List_rec_CONS";
   199 
   199 
   235 by (ALLGOALS(asm_simp_tac (simpset() addsimps ([sexp_A_I,sexp_ListA_I]@prems))));
   235 by (ALLGOALS(asm_simp_tac (simpset() addsimps ([sexp_A_I,sexp_ListA_I]@prems))));
   236 qed "List_rec_type";
   236 qed "List_rec_type";
   237 
   237 
   238 (** Generalized map functionals **)
   238 (** Generalized map functionals **)
   239 
   239 
   240 goalw SList.thy [Rep_map_def] "Rep_map f Nil = NIL";
   240 Goalw [Rep_map_def] "Rep_map f Nil = NIL";
   241 by (rtac list_rec_Nil 1);
   241 by (rtac list_rec_Nil 1);
   242 qed "Rep_map_Nil";
   242 qed "Rep_map_Nil";
   243 
   243 
   244 goalw SList.thy [Rep_map_def]
   244 Goalw [Rep_map_def]
   245     "Rep_map f (x#xs) = CONS (f x) (Rep_map f xs)";
   245     "Rep_map f (x#xs) = CONS (f x) (Rep_map f xs)";
   246 by (rtac list_rec_Cons 1);
   246 by (rtac list_rec_Cons 1);
   247 qed "Rep_map_Cons";
   247 qed "Rep_map_Cons";
   248 
   248 
   249 goalw SList.thy [Rep_map_def] "!!f. (!!x. f(x): A) ==> Rep_map f xs: list(A)";
   249 Goalw [Rep_map_def] "!!f. (!!x. f(x): A) ==> Rep_map f xs: list(A)";
   250 by (rtac list_induct2 1);
   250 by (rtac list_induct2 1);
   251 by (ALLGOALS Asm_simp_tac);
   251 by (ALLGOALS Asm_simp_tac);
   252 qed "Rep_map_type";
   252 qed "Rep_map_type";
   253 
   253 
   254 goalw SList.thy [Abs_map_def] "Abs_map g NIL = Nil";
   254 Goalw [Abs_map_def] "Abs_map g NIL = Nil";
   255 by (rtac List_rec_NIL 1);
   255 by (rtac List_rec_NIL 1);
   256 qed "Abs_map_NIL";
   256 qed "Abs_map_NIL";
   257 
   257 
   258 val prems = goalw SList.thy [Abs_map_def]
   258 val prems = goalw SList.thy [Abs_map_def]
   259     "[| M: sexp;  N: sexp |] ==> \
   259     "[| M: sexp;  N: sexp |] ==> \
   301    filter_Nil, filter_Cons];
   301    filter_Nil, filter_Cons];
   302 
   302 
   303 
   303 
   304 (** @ - append **)
   304 (** @ - append **)
   305 
   305 
   306 goal SList.thy "(xs@ys)@zs = xs@(ys@zs)";
   306 Goal "(xs@ys)@zs = xs@(ys@zs)";
   307 by (list_ind_tac "xs" 1);
   307 by (list_ind_tac "xs" 1);
   308 by (ALLGOALS Asm_simp_tac);
   308 by (ALLGOALS Asm_simp_tac);
   309 qed "append_assoc2";
   309 qed "append_assoc2";
   310 
   310 
   311 goal SList.thy "xs @ [] = xs";
   311 Goal "xs @ [] = xs";
   312 by (list_ind_tac "xs" 1);
   312 by (list_ind_tac "xs" 1);
   313 by (ALLGOALS Asm_simp_tac);
   313 by (ALLGOALS Asm_simp_tac);
   314 qed "append_Nil4";
   314 qed "append_Nil4";
   315 
   315 
   316 (** mem **)
   316 (** mem **)
   317 
   317 
   318 goal SList.thy "x mem (xs@ys) = (x mem xs | x mem ys)";
   318 Goal "x mem (xs@ys) = (x mem xs | x mem ys)";
   319 by (list_ind_tac "xs" 1);
   319 by (list_ind_tac "xs" 1);
   320 by (ALLGOALS Asm_simp_tac);
   320 by (ALLGOALS Asm_simp_tac);
   321 qed "mem_append2";
   321 qed "mem_append2";
   322 
   322 
   323 goal SList.thy "x mem [x:xs. P(x)] = (x mem xs & P(x))";
   323 Goal "x mem [x:xs. P(x)] = (x mem xs & P(x))";
   324 by (list_ind_tac "xs" 1);
   324 by (list_ind_tac "xs" 1);
   325 by (ALLGOALS Asm_simp_tac);
   325 by (ALLGOALS Asm_simp_tac);
   326 qed "mem_filter2";
   326 qed "mem_filter2";
   327 
   327 
   328 
   328 
   339 
   339 
   340 (*Rep_map_inverse is obtained via Abs_Rep_map and map_ident*)
   340 (*Rep_map_inverse is obtained via Abs_Rep_map and map_ident*)
   341 
   341 
   342 (** list_case **)
   342 (** list_case **)
   343 
   343 
   344 goal SList.thy
   344 Goal
   345  "P(list_case a f xs) = ((xs=[] --> P(a)) & \
   345  "P(list_case a f xs) = ((xs=[] --> P(a)) & \
   346 \                        (!y ys. xs=y#ys --> P(f y ys)))";
   346 \                        (!y ys. xs=y#ys --> P(f y ys)))";
   347 by (list_ind_tac "xs" 1);
   347 by (list_ind_tac "xs" 1);
   348 by (ALLGOALS Asm_simp_tac);
   348 by (ALLGOALS Asm_simp_tac);
   349 qed "split_list_case2";
   349 qed "split_list_case2";
   350 
   350 
   351 
   351 
   352 (** Additional mapping lemmas **)
   352 (** Additional mapping lemmas **)
   353 
   353 
   354 goal SList.thy "map (%x. x) xs = xs";
   354 Goal "map (%x. x) xs = xs";
   355 by (list_ind_tac "xs" 1);
   355 by (list_ind_tac "xs" 1);
   356 by (ALLGOALS Asm_simp_tac);
   356 by (ALLGOALS Asm_simp_tac);
   357 qed "map_ident2";
   357 qed "map_ident2";
   358 
   358 
   359 goal SList.thy "map f (xs@ys) = map f xs @ map f ys";
   359 Goal "map f (xs@ys) = map f xs @ map f ys";
   360 by (list_ind_tac "xs" 1);
   360 by (list_ind_tac "xs" 1);
   361 by (ALLGOALS Asm_simp_tac);
   361 by (ALLGOALS Asm_simp_tac);
   362 qed "map_append2";
   362 qed "map_append2";
   363 
   363 
   364 goalw SList.thy [o_def] "map (f o g) xs = map f (map g xs)";
   364 Goalw [o_def] "map (f o g) xs = map f (map g xs)";
   365 by (list_ind_tac "xs" 1);
   365 by (list_ind_tac "xs" 1);
   366 by (ALLGOALS Asm_simp_tac);
   366 by (ALLGOALS Asm_simp_tac);
   367 qed "map_compose2";
   367 qed "map_compose2";
   368 
   368 
   369 goal SList.thy "!!f. (!!x. f(x): sexp) ==> \
   369 Goal "!!f. (!!x. f(x): sexp) ==> \
   370 \       Abs_map g (Rep_map f xs) = map (%t. g(f(t))) xs";
   370 \       Abs_map g (Rep_map f xs) = map (%t. g(f(t))) xs";
   371 by (list_ind_tac "xs" 1);
   371 by (list_ind_tac "xs" 1);
   372 by (ALLGOALS (asm_simp_tac(simpset() addsimps
   372 by (ALLGOALS (asm_simp_tac(simpset() addsimps
   373 			   [Rep_map_type, list_sexp RS subsetD])));
   373 			   [Rep_map_type, list_sexp RS subsetD])));
   374 qed "Abs_Rep_map";
   374 qed "Abs_Rep_map";