src/HOL/Induct/SList.thy
author wenzelm
Sun Nov 02 18:21:45 2014 +0100 (2014-11-02)
changeset 58889 5b7a9633cfa8
parent 58305 57752a91eec4
child 60530 44f9873d6f6f
permissions -rw-r--r--
modernized header uniformly as section;
nipkow@35247
     1
(*  Title:      HOL/Induct/SList.thy
nipkow@35247
     2
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
nipkow@35247
     3
nipkow@35247
     4
This theory is strictly of historical interest. It illustrates how
nipkow@35247
     5
recursive datatypes can be constructed in higher-order logic from
nipkow@35247
     6
first principles. Isabelle's datatype package automates a
nipkow@35247
     7
construction of this sort.
nipkow@35247
     8
nipkow@35247
     9
Enriched theory of lists; mutual indirect recursive data-types.
nipkow@35247
    10
nipkow@35247
    11
Definition of type 'a list (strict lists) by a least fixed point
nipkow@35247
    12
nipkow@35247
    13
We use          list(A) == lfp(%Z. {NUMB(0)} <+> A <*> Z)
nipkow@35247
    14
and not         list    == lfp(%Z. {NUMB(0)} <+> range(Leaf) <*> Z)
nipkow@35247
    15
nipkow@35247
    16
so that list can serve as a "functor" for defining other recursive types.
nipkow@35247
    17
blanchet@58305
    18
This enables the conservative construction of mutual recursive datatypes
nipkow@35247
    19
such as
nipkow@35247
    20
blanchet@58305
    21
datatype 'a m = Node 'a * 'a m list
nipkow@35247
    22
*)
nipkow@35247
    23
wenzelm@58889
    24
section {* Extended List Theory (old) *}
nipkow@35247
    25
nipkow@35247
    26
theory SList
nipkow@35247
    27
imports Sexp
nipkow@35247
    28
begin
nipkow@35247
    29
nipkow@35247
    30
(*Hilbert_Choice is needed for the function "inv"*)
nipkow@35247
    31
nipkow@35247
    32
(* *********************************************************************** *)
nipkow@35247
    33
(*                                                                         *)
nipkow@35247
    34
(* Building up data type                                                   *)
nipkow@35247
    35
(*                                                                         *)
nipkow@35247
    36
(* *********************************************************************** *)
nipkow@35247
    37
nipkow@35247
    38
nipkow@35247
    39
(* Defining the Concrete Constructors *)
nipkow@35247
    40
definition
nipkow@35247
    41
  NIL  :: "'a item" where
nipkow@35247
    42
  "NIL = In0(Numb(0))"
nipkow@35247
    43
nipkow@35247
    44
definition
nipkow@35247
    45
  CONS :: "['a item, 'a item] => 'a item" where
nipkow@35247
    46
  "CONS M N = In1(Scons M N)"
nipkow@35247
    47
nipkow@35247
    48
inductive_set
nipkow@35247
    49
  list :: "'a item set => 'a item set"
nipkow@35247
    50
  for A :: "'a item set"
nipkow@35247
    51
  where
nipkow@35247
    52
    NIL_I:  "NIL: list A"
nipkow@35247
    53
  | CONS_I: "[| a: A;  M: list A |] ==> CONS a M : list A"
nipkow@35247
    54
nipkow@35247
    55
wenzelm@45694
    56
definition "List = list (range Leaf)"
wenzelm@45694
    57
wenzelm@49834
    58
typedef 'a list = "List :: 'a item set"
wenzelm@45694
    59
  morphisms Rep_List Abs_List
wenzelm@45694
    60
  unfolding List_def by (blast intro: list.NIL_I)
nipkow@35247
    61
blanchet@58112
    62
abbreviation "Case == Old_Datatype.Case"
blanchet@58112
    63
abbreviation "Split == Old_Datatype.Split"
nipkow@35247
    64
nipkow@35247
    65
definition
nipkow@35247
    66
  List_case :: "['b, ['a item, 'a item]=>'b, 'a item] => 'b" where
nipkow@35247
    67
  "List_case c d = Case(%x. c)(Split(d))"
nipkow@35247
    68
  
nipkow@35247
    69
definition
nipkow@35247
    70
  List_rec  :: "['a item, 'b, ['a item, 'a item, 'b]=>'b] => 'b" where
nipkow@35247
    71
  "List_rec M c d = wfrec (pred_sexp^+)
nipkow@35247
    72
                           (%g. List_case c (%x y. d x y (g y))) M"
nipkow@35247
    73
nipkow@35247
    74
nipkow@35247
    75
(* *********************************************************************** *)
nipkow@35247
    76
(*                                                                         *)
nipkow@35247
    77
(* Abstracting data type                                                   *)
nipkow@35247
    78
(*                                                                         *)
nipkow@35247
    79
(* *********************************************************************** *)
nipkow@35247
    80
nipkow@35247
    81
(*Declaring the abstract list constructors*)
nipkow@35247
    82
nipkow@35247
    83
no_translations
nipkow@35247
    84
  "[x, xs]" == "x#[xs]"
nipkow@35247
    85
  "[x]" == "x#[]"
nipkow@35247
    86
no_notation
nipkow@35247
    87
  Nil  ("[]") and
nipkow@35247
    88
  Cons (infixr "#" 65)
nipkow@35247
    89
nipkow@35247
    90
definition
nipkow@35247
    91
  Nil       :: "'a list"                               ("[]") where
nipkow@35247
    92
   "Nil  = Abs_List(NIL)"
nipkow@35247
    93
nipkow@35247
    94
definition
nipkow@35247
    95
  "Cons"       :: "['a, 'a list] => 'a list"           (infixr "#" 65) where
nipkow@35247
    96
   "x#xs = Abs_List(CONS (Leaf x)(Rep_List xs))"
nipkow@35247
    97
nipkow@35247
    98
definition
nipkow@35247
    99
  (* list Recursion -- the trancl is Essential; see list.ML *)
nipkow@35247
   100
  list_rec  :: "['a list, 'b, ['a, 'a list, 'b]=>'b] => 'b" where
nipkow@35247
   101
   "list_rec l c d =
nipkow@35247
   102
      List_rec(Rep_List l) c (%x y r. d(inv Leaf x)(Abs_List y) r)"
nipkow@35247
   103
nipkow@35247
   104
definition
nipkow@35247
   105
  list_case :: "['b, ['a, 'a list]=>'b, 'a list] => 'b" where
nipkow@35247
   106
   "list_case a f xs = list_rec xs a (%x xs r. f x xs)"
nipkow@35247
   107
nipkow@35247
   108
(* list Enumeration *)
nipkow@35247
   109
translations
nipkow@35247
   110
  "[x, xs]" == "x#[xs]"
nipkow@35247
   111
  "[x]"     == "x#[]"
nipkow@35247
   112
nipkow@35247
   113
  "case xs of [] => a | y#ys => b" == "CONST list_case(a, %y ys. b, xs)"
nipkow@35247
   114
nipkow@35247
   115
nipkow@35247
   116
(* *********************************************************************** *)
nipkow@35247
   117
(*                                                                         *)
nipkow@35247
   118
(* Generalized Map Functionals                                             *)
nipkow@35247
   119
(*                                                                         *)
nipkow@35247
   120
(* *********************************************************************** *)
nipkow@35247
   121
nipkow@35247
   122
  
nipkow@35247
   123
(* Generalized Map Functionals *)
nipkow@35247
   124
nipkow@35247
   125
definition
nipkow@35247
   126
  Rep_map   :: "('b => 'a item) => ('b list => 'a item)" where
nipkow@35247
   127
   "Rep_map f xs = list_rec xs  NIL(%x l r. CONS(f x) r)"
nipkow@35247
   128
nipkow@35247
   129
definition
nipkow@35247
   130
  Abs_map   :: "('a item => 'b) => 'a item => 'b list" where
nipkow@35247
   131
   "Abs_map g M  = List_rec M Nil (%N L r. g(N)#r)"
nipkow@35247
   132
nipkow@35247
   133
nipkow@35247
   134
definition
nipkow@35247
   135
  map       :: "('a=>'b) => ('a list => 'b list)" where
nipkow@35247
   136
  "map f xs = list_rec xs [] (%x l r. f(x)#r)"
nipkow@35247
   137
haftmann@39246
   138
primrec take :: "['a list,nat] => 'a list" where
nipkow@35247
   139
  take_0:  "take xs 0 = []"
haftmann@39246
   140
| take_Suc: "take xs (Suc n) = list_case [] (%x l. x # take l n) xs"
nipkow@35247
   141
nipkow@35247
   142
lemma ListI: "x : list (range Leaf) ==> x : List"
nipkow@35247
   143
by (simp add: List_def)
nipkow@35247
   144
nipkow@35247
   145
lemma ListD: "x : List ==> x : list (range Leaf)"
nipkow@35247
   146
by (simp add: List_def)
nipkow@35247
   147
nipkow@35247
   148
lemma list_unfold: "list(A) = usum {Numb(0)} (uprod A (list(A)))"
nipkow@35247
   149
  by (fast intro!: list.intros [unfolded NIL_def CONS_def]
nipkow@35247
   150
           elim: list.cases [unfolded NIL_def CONS_def])
nipkow@35247
   151
nipkow@35247
   152
(*This justifies using list in other recursive type definitions*)
nipkow@35247
   153
lemma list_mono: "A<=B ==> list(A) <= list(B)"
nipkow@35247
   154
apply (rule subsetI)
nipkow@35247
   155
apply (erule list.induct)
nipkow@35247
   156
apply (auto intro!: list.intros)
nipkow@35247
   157
done
nipkow@35247
   158
nipkow@35247
   159
(*Type checking -- list creates well-founded sets*)
nipkow@35247
   160
lemma list_sexp: "list(sexp) <= sexp"
nipkow@35247
   161
apply (rule subsetI)
nipkow@35247
   162
apply (erule list.induct)
nipkow@35247
   163
apply (unfold NIL_def CONS_def)
nipkow@35247
   164
apply (auto intro: sexp.intros sexp_In0I sexp_In1I)
nipkow@35247
   165
done
nipkow@35247
   166
nipkow@35247
   167
(* A <= sexp ==> list(A) <= sexp *)
nipkow@35247
   168
lemmas list_subset_sexp = subset_trans [OF list_mono list_sexp] 
nipkow@35247
   169
nipkow@35247
   170
nipkow@35247
   171
(*Induction for the type 'a list *)
nipkow@35247
   172
lemma list_induct:
nipkow@35247
   173
    "[| P(Nil);    
nipkow@35247
   174
        !!x xs. P(xs) ==> P(x # xs) |]  ==> P(l)"
nipkow@35247
   175
apply (unfold Nil_def Cons_def) 
nipkow@35247
   176
apply (rule Rep_List_inverse [THEN subst])
nipkow@35247
   177
(*types force good instantiation*)
nipkow@35247
   178
apply (rule Rep_List [unfolded List_def, THEN list.induct], simp)
nipkow@35247
   179
apply (erule Abs_List_inverse [unfolded List_def, THEN subst], blast) 
nipkow@35247
   180
done
nipkow@35247
   181
nipkow@35247
   182
nipkow@35247
   183
(*** Isomorphisms ***)
nipkow@35247
   184
nipkow@35247
   185
lemma inj_on_Abs_list: "inj_on Abs_List (list(range Leaf))"
nipkow@35247
   186
apply (rule inj_on_inverseI)
nipkow@35247
   187
apply (erule Abs_List_inverse [unfolded List_def])
nipkow@35247
   188
done
nipkow@35247
   189
nipkow@35247
   190
(** Distinctness of constructors **)
nipkow@35247
   191
nipkow@35247
   192
lemma CONS_not_NIL [iff]: "CONS M N ~= NIL"
nipkow@35247
   193
by (simp add: NIL_def CONS_def)
nipkow@35247
   194
nipkow@35247
   195
lemmas NIL_not_CONS [iff] = CONS_not_NIL [THEN not_sym]
wenzelm@45605
   196
lemmas CONS_neq_NIL = CONS_not_NIL [THEN notE]
nipkow@35247
   197
lemmas NIL_neq_CONS = sym [THEN CONS_neq_NIL]
nipkow@35247
   198
nipkow@35247
   199
lemma Cons_not_Nil [iff]: "x # xs ~= Nil"
nipkow@35247
   200
apply (unfold Nil_def Cons_def)
nipkow@35247
   201
apply (rule CONS_not_NIL [THEN inj_on_Abs_list [THEN inj_on_contraD]])
nipkow@35247
   202
apply (simp_all add: list.intros rangeI Rep_List [unfolded List_def])
nipkow@35247
   203
done
nipkow@35247
   204
wenzelm@45605
   205
lemmas Nil_not_Cons = Cons_not_Nil [THEN not_sym]
wenzelm@45605
   206
declare Nil_not_Cons [iff]
wenzelm@45605
   207
lemmas Cons_neq_Nil = Cons_not_Nil [THEN notE]
nipkow@35247
   208
lemmas Nil_neq_Cons = sym [THEN Cons_neq_Nil]
nipkow@35247
   209
nipkow@35247
   210
(** Injectiveness of CONS and Cons **)
nipkow@35247
   211
nipkow@35247
   212
lemma CONS_CONS_eq [iff]: "(CONS K M)=(CONS L N) = (K=L & M=N)"
nipkow@35247
   213
by (simp add: CONS_def)
nipkow@35247
   214
nipkow@35247
   215
(*For reasoning about abstract list constructors*)
nipkow@35247
   216
declare Rep_List [THEN ListD, intro] ListI [intro]
nipkow@35247
   217
declare list.intros [intro,simp]
nipkow@35247
   218
declare Leaf_inject [dest!]
nipkow@35247
   219
nipkow@35247
   220
lemma Cons_Cons_eq [iff]: "(x#xs=y#ys) = (x=y & xs=ys)"
nipkow@35247
   221
apply (simp add: Cons_def)
nipkow@35247
   222
apply (subst Abs_List_inject)
nipkow@35247
   223
apply (auto simp add: Rep_List_inject)
nipkow@35247
   224
done
nipkow@35247
   225
wenzelm@45605
   226
lemmas Cons_inject2 = Cons_Cons_eq [THEN iffD1, THEN conjE]
nipkow@35247
   227
nipkow@35247
   228
lemma CONS_D: "CONS M N: list(A) ==> M: A & N: list(A)"
wenzelm@45694
   229
  by (induct L == "CONS M N" rule: list.induct) auto
nipkow@35247
   230
nipkow@35247
   231
lemma sexp_CONS_D: "CONS M N: sexp ==> M: sexp & N: sexp"
nipkow@35247
   232
apply (simp add: CONS_def In1_def)
nipkow@35247
   233
apply (fast dest!: Scons_D)
nipkow@35247
   234
done
nipkow@35247
   235
nipkow@35247
   236
nipkow@35247
   237
(*Reasoning about constructors and their freeness*)
nipkow@35247
   238
nipkow@35247
   239
nipkow@35247
   240
lemma not_CONS_self: "N: list(A) ==> !M. N ~= CONS M N"
nipkow@35247
   241
apply (erule list.induct) apply simp_all done
nipkow@35247
   242
nipkow@35247
   243
lemma not_Cons_self2: "\<forall>x. l ~= x#l"
nipkow@35247
   244
by (induct l rule: list_induct) simp_all
nipkow@35247
   245
nipkow@35247
   246
nipkow@35247
   247
lemma neq_Nil_conv2: "(xs ~= []) = (\<exists>y ys. xs = y#ys)"
nipkow@35247
   248
by (induct xs rule: list_induct) auto
nipkow@35247
   249
nipkow@35247
   250
(** Conversion rules for List_case: case analysis operator **)
nipkow@35247
   251
nipkow@35247
   252
lemma List_case_NIL [simp]: "List_case c h NIL = c"
nipkow@35247
   253
by (simp add: List_case_def NIL_def)
nipkow@35247
   254
nipkow@35247
   255
lemma List_case_CONS [simp]: "List_case c h (CONS M N) = h M N"
nipkow@35247
   256
by (simp add: List_case_def CONS_def)
nipkow@35247
   257
nipkow@35247
   258
nipkow@35247
   259
(*** List_rec -- by wf recursion on pred_sexp ***)
nipkow@35247
   260
nipkow@35247
   261
(* The trancl(pred_sexp) is essential because pred_sexp_CONS_I1,2 would not
nipkow@35247
   262
   hold if pred_sexp^+ were changed to pred_sexp. *)
nipkow@35247
   263
nipkow@35247
   264
lemma List_rec_unfold_lemma:
nipkow@35247
   265
     "(%M. List_rec M c d) == 
nipkow@35247
   266
      wfrec (pred_sexp^+) (%g. List_case c (%x y. d x y (g y)))"
nipkow@35247
   267
by (simp add: List_rec_def)
nipkow@35247
   268
nipkow@35247
   269
lemmas List_rec_unfold = 
wenzelm@45605
   270
    def_wfrec [OF List_rec_unfold_lemma wf_pred_sexp [THEN wf_trancl]]
nipkow@35247
   271
nipkow@35247
   272
nipkow@35247
   273
(** pred_sexp lemmas **)
nipkow@35247
   274
nipkow@35247
   275
lemma pred_sexp_CONS_I1: 
nipkow@35247
   276
    "[| M: sexp;  N: sexp |] ==> (M, CONS M N) : pred_sexp^+"
nipkow@35247
   277
by (simp add: CONS_def In1_def)
nipkow@35247
   278
nipkow@35247
   279
lemma pred_sexp_CONS_I2: 
nipkow@35247
   280
    "[| M: sexp;  N: sexp |] ==> (N, CONS M N) : pred_sexp^+"
nipkow@35247
   281
by (simp add: CONS_def In1_def)
nipkow@35247
   282
nipkow@35247
   283
lemma pred_sexp_CONS_D: 
nipkow@35247
   284
    "(CONS M1 M2, N) : pred_sexp^+ ==>  
nipkow@35247
   285
     (M1,N) : pred_sexp^+ & (M2,N) : pred_sexp^+"
nipkow@35247
   286
apply (frule pred_sexp_subset_Sigma [THEN trancl_subset_Sigma, THEN subsetD])
nipkow@35247
   287
apply (blast dest!: sexp_CONS_D intro: pred_sexp_CONS_I1 pred_sexp_CONS_I2 
nipkow@35247
   288
                    trans_trancl [THEN transD])
nipkow@35247
   289
done
nipkow@35247
   290
nipkow@35247
   291
nipkow@35247
   292
(** Conversion rules for List_rec **)
nipkow@35247
   293
nipkow@35247
   294
lemma List_rec_NIL [simp]: "List_rec NIL c h = c"
nipkow@35247
   295
apply (rule List_rec_unfold [THEN trans])
nipkow@35247
   296
apply (simp add: List_case_NIL)
nipkow@35247
   297
done
nipkow@35247
   298
nipkow@35247
   299
lemma List_rec_CONS [simp]:
nipkow@35247
   300
     "[| M: sexp;  N: sexp |] 
nipkow@35247
   301
      ==> List_rec (CONS M N) c h = h M N (List_rec N c h)"
nipkow@35247
   302
apply (rule List_rec_unfold [THEN trans])
nipkow@35247
   303
apply (simp add: pred_sexp_CONS_I2)
nipkow@35247
   304
done
nipkow@35247
   305
nipkow@35247
   306
nipkow@35247
   307
(*** list_rec -- by List_rec ***)
nipkow@35247
   308
nipkow@35247
   309
lemmas Rep_List_in_sexp =
nipkow@35247
   310
    subsetD [OF range_Leaf_subset_sexp [THEN list_subset_sexp]
nipkow@35247
   311
                Rep_List [THEN ListD]] 
nipkow@35247
   312
nipkow@35247
   313
nipkow@35247
   314
lemma list_rec_Nil [simp]: "list_rec Nil c h = c"
nipkow@35247
   315
by (simp add: list_rec_def ListI [THEN Abs_List_inverse] Nil_def)
nipkow@35247
   316
nipkow@35247
   317
nipkow@35247
   318
lemma list_rec_Cons [simp]: "list_rec (a#l) c h = h a l (list_rec l c h)"
nipkow@35247
   319
by (simp add: list_rec_def ListI [THEN Abs_List_inverse] Cons_def
nipkow@35247
   320
              Rep_List_inverse Rep_List [THEN ListD] inj_Leaf Rep_List_in_sexp)
nipkow@35247
   321
nipkow@35247
   322
nipkow@35247
   323
(*Type checking.  Useful?*)
nipkow@35247
   324
lemma List_rec_type:
nipkow@35247
   325
     "[| M: list(A);      
nipkow@35247
   326
         A<=sexp;         
nipkow@35247
   327
         c: C(NIL);       
nipkow@35247
   328
         !!x y r. [| x: A;  y: list(A);  r: C(y) |] ==> h x y r: C(CONS x y)  
nipkow@35247
   329
      |] ==> List_rec M c h : C(M :: 'a item)"
nipkow@35247
   330
apply (erule list.induct, simp) 
nipkow@35247
   331
apply (insert list_subset_sexp) 
nipkow@35247
   332
apply (subst List_rec_CONS, blast+)
nipkow@35247
   333
done
nipkow@35247
   334
nipkow@35247
   335
nipkow@35247
   336
nipkow@35247
   337
(** Generalized map functionals **)
nipkow@35247
   338
nipkow@35247
   339
lemma Rep_map_Nil [simp]: "Rep_map f Nil = NIL"
nipkow@35247
   340
by (simp add: Rep_map_def)
nipkow@35247
   341
nipkow@35247
   342
lemma Rep_map_Cons [simp]: 
nipkow@35247
   343
    "Rep_map f(x#xs) = CONS(f x)(Rep_map f xs)"
nipkow@35247
   344
by (simp add: Rep_map_def)
nipkow@35247
   345
nipkow@35247
   346
lemma Rep_map_type: "(!!x. f(x): A) ==> Rep_map f xs: list(A)"
nipkow@35247
   347
apply (simp add: Rep_map_def)
nipkow@35247
   348
apply (rule list_induct, auto)
nipkow@35247
   349
done
nipkow@35247
   350
nipkow@35247
   351
lemma Abs_map_NIL [simp]: "Abs_map g NIL = Nil"
nipkow@35247
   352
by (simp add: Abs_map_def)
nipkow@35247
   353
nipkow@35247
   354
lemma Abs_map_CONS [simp]: 
nipkow@35247
   355
    "[| M: sexp;  N: sexp |] ==> Abs_map g (CONS M N) = g(M) # Abs_map g N"
nipkow@35247
   356
by (simp add: Abs_map_def)
nipkow@35247
   357
nipkow@35247
   358
(*Eases the use of primitive recursion.*)
nipkow@35247
   359
lemma def_list_rec_NilCons:
nipkow@35247
   360
    "[| !!xs. f(xs) = list_rec xs c h  |] 
nipkow@35247
   361
     ==> f [] = c & f(x#xs) = h x xs (f xs)"
nipkow@35247
   362
by simp 
nipkow@35247
   363
nipkow@35247
   364
lemma Abs_map_inverse:
nipkow@35247
   365
     "[| M: list(A);  A<=sexp;  !!z. z: A ==> f(g(z)) = z |]  
nipkow@35247
   366
      ==> Rep_map f (Abs_map g M) = M"
nipkow@35247
   367
apply (erule list.induct, simp_all)
nipkow@35247
   368
apply (insert list_subset_sexp) 
nipkow@35247
   369
apply (subst Abs_map_CONS, blast)
nipkow@35247
   370
apply blast 
nipkow@35247
   371
apply simp 
nipkow@35247
   372
done
nipkow@35247
   373
nipkow@35247
   374
(*Rep_map_inverse is obtained via Abs_Rep_map and map_ident*)
nipkow@35247
   375
nipkow@35247
   376
(** list_case **)
nipkow@35247
   377
nipkow@35247
   378
(* setting up rewrite sets *)
nipkow@35247
   379
nipkow@35247
   380
text{*Better to have a single theorem with a conjunctive conclusion.*}
nipkow@35247
   381
declare def_list_rec_NilCons [OF list_case_def, simp]
nipkow@35247
   382
nipkow@35247
   383
(** list_case **)
nipkow@35247
   384
nipkow@35247
   385
lemma expand_list_case: 
nipkow@35247
   386
 "P(list_case a f xs) = ((xs=[] --> P a ) & (!y ys. xs=y#ys --> P(f y ys)))"
nipkow@35247
   387
by (induct xs rule: list_induct) simp_all
nipkow@35247
   388
nipkow@35247
   389
nipkow@35247
   390
(**** Function definitions ****)
nipkow@35247
   391
nipkow@35247
   392
declare def_list_rec_NilCons [OF map_def, simp]
nipkow@35247
   393
nipkow@35247
   394
(** The functional "map" and the generalized functionals **)
nipkow@35247
   395
nipkow@35247
   396
lemma Abs_Rep_map: 
nipkow@35247
   397
     "(!!x. f(x): sexp) ==>  
nipkow@35247
   398
        Abs_map g (Rep_map f xs) = map (%t. g(f(t))) xs"
nipkow@35247
   399
apply (induct xs rule: list_induct)
nipkow@35247
   400
apply (simp_all add: Rep_map_type list_sexp [THEN subsetD])
nipkow@35247
   401
done
nipkow@35247
   402
nipkow@35247
   403
nipkow@35247
   404
(** Additional mapping lemmas **)
nipkow@35247
   405
nipkow@35247
   406
lemma map_ident [simp]: "map(%x. x)(xs) = xs"
nipkow@35247
   407
by (induct xs rule: list_induct) simp_all
nipkow@35247
   408
nipkow@35247
   409
lemma map_compose: "map(f o g)(xs) = map f (map g xs)"
nipkow@35247
   410
apply (simp add: o_def)
nipkow@35247
   411
apply (induct xs rule: list_induct)
nipkow@35247
   412
apply simp_all
nipkow@35247
   413
done
nipkow@35247
   414
nipkow@35247
   415
nipkow@35247
   416
(** take **)
nipkow@35247
   417
nipkow@35247
   418
lemma take_Suc1 [simp]: "take [] (Suc x) = []"
nipkow@35247
   419
by simp
nipkow@35247
   420
nipkow@35247
   421
lemma take_Suc2 [simp]: "take(a#xs)(Suc x) = a#take xs x"
nipkow@35247
   422
by simp
nipkow@35247
   423
nipkow@35247
   424
lemma take_Nil [simp]: "take [] n = []"
nipkow@35247
   425
by (induct n) simp_all
nipkow@35247
   426
nipkow@35247
   427
lemma take_take_eq [simp]: "\<forall>n. take (take xs n) n = take xs n"
nipkow@35247
   428
apply (induct xs rule: list_induct)
nipkow@35247
   429
apply simp_all
nipkow@35247
   430
apply (rule allI)
nipkow@35247
   431
apply (induct_tac n)
nipkow@35247
   432
apply auto
nipkow@35247
   433
done
nipkow@35247
   434
nipkow@35247
   435
end