src/HOL/Datatype.thy
author nipkow
Sun Sep 14 17:53:27 2003 +0200 (2003-09-14)
changeset 14187 26dfcd0ac436
parent 13635 c41e88151b54
child 14208 144f45277d5a
permissions -rw-r--r--
Added new theorems
berghofe@5181
     1
(*  Title:      HOL/Datatype.thy
berghofe@5181
     2
    ID:         $Id$
wenzelm@11954
     3
    Author:     Stefan Berghofer and Markus Wenzel, TU Muenchen
wenzelm@11954
     4
    License:    GPL (GNU GENERAL PUBLIC LICENSE)
berghofe@5181
     5
*)
berghofe@5181
     6
wenzelm@12918
     7
header {* Datatypes *}
wenzelm@11954
     8
wenzelm@11954
     9
theory Datatype = Datatype_Universe:
wenzelm@11954
    10
wenzelm@11954
    11
subsection {* Representing primitive types *}
berghofe@5181
    12
berghofe@5759
    13
rep_datatype bool
wenzelm@11954
    14
  distinct True_not_False False_not_True
wenzelm@11954
    15
  induction bool_induct
wenzelm@11954
    16
wenzelm@11954
    17
declare case_split [cases type: bool]
wenzelm@11954
    18
  -- "prefer plain propositional version"
wenzelm@11954
    19
wenzelm@11954
    20
rep_datatype unit
wenzelm@11954
    21
  induction unit_induct
berghofe@5181
    22
berghofe@5181
    23
rep_datatype prod
wenzelm@11954
    24
  inject Pair_eq
wenzelm@11954
    25
  induction prod_induct
wenzelm@11954
    26
wenzelm@12918
    27
rep_datatype sum
wenzelm@12918
    28
  distinct Inl_not_Inr Inr_not_Inl
wenzelm@12918
    29
  inject Inl_eq Inr_eq
wenzelm@12918
    30
  induction sum_induct
wenzelm@12918
    31
wenzelm@12918
    32
ML {*
wenzelm@12918
    33
  val [sum_case_Inl, sum_case_Inr] = thms "sum.cases";
wenzelm@12918
    34
  bind_thm ("sum_case_Inl", sum_case_Inl);
wenzelm@12918
    35
  bind_thm ("sum_case_Inr", sum_case_Inr);
wenzelm@12918
    36
*} -- {* compatibility *}
wenzelm@12918
    37
wenzelm@12918
    38
lemma surjective_sum: "sum_case (%x::'a. f (Inl x)) (%y::'b. f (Inr y)) s = f(s)"
wenzelm@12918
    39
  apply (rule_tac s = s in sumE)
wenzelm@12918
    40
   apply (erule ssubst)
wenzelm@12918
    41
   apply (rule sum_case_Inl)
wenzelm@12918
    42
  apply (erule ssubst)
wenzelm@12918
    43
  apply (rule sum_case_Inr)
wenzelm@12918
    44
  done
wenzelm@12918
    45
wenzelm@12918
    46
lemma sum_case_weak_cong: "s = t ==> sum_case f g s = sum_case f g t"
wenzelm@12918
    47
  -- {* Prevents simplification of @{text f} and @{text g}: much faster. *}
wenzelm@12918
    48
  by (erule arg_cong)
wenzelm@12918
    49
wenzelm@12918
    50
lemma sum_case_inject:
wenzelm@12918
    51
  "sum_case f1 f2 = sum_case g1 g2 ==> (f1 = g1 ==> f2 = g2 ==> P) ==> P"
wenzelm@12918
    52
proof -
wenzelm@12918
    53
  assume a: "sum_case f1 f2 = sum_case g1 g2"
wenzelm@12918
    54
  assume r: "f1 = g1 ==> f2 = g2 ==> P"
wenzelm@12918
    55
  show P
wenzelm@12918
    56
    apply (rule r)
wenzelm@12918
    57
     apply (rule ext)
wenzelm@12918
    58
     apply (cut_tac x = "Inl x" in a [THEN fun_cong])
wenzelm@12918
    59
     apply simp
wenzelm@12918
    60
    apply (rule ext)
wenzelm@12918
    61
    apply (cut_tac x = "Inr x" in a [THEN fun_cong])
wenzelm@12918
    62
    apply simp
wenzelm@12918
    63
    done
wenzelm@12918
    64
qed
wenzelm@12918
    65
berghofe@13635
    66
constdefs
berghofe@13635
    67
  Suml :: "('a => 'c) => 'a + 'b => 'c"
berghofe@13635
    68
  "Suml == (%f. sum_case f arbitrary)"
berghofe@13635
    69
berghofe@13635
    70
  Sumr :: "('b => 'c) => 'a + 'b => 'c"
berghofe@13635
    71
  "Sumr == sum_case arbitrary"
berghofe@13635
    72
berghofe@13635
    73
lemma Suml_inject: "Suml f = Suml g ==> f = g"
berghofe@13635
    74
  by (unfold Suml_def) (erule sum_case_inject)
berghofe@13635
    75
berghofe@13635
    76
lemma Sumr_inject: "Sumr f = Sumr g ==> f = g"
berghofe@13635
    77
  by (unfold Sumr_def) (erule sum_case_inject)
berghofe@13635
    78
berghofe@13635
    79
berghofe@13635
    80
subsection {* Finishing the datatype package setup *}
berghofe@13635
    81
berghofe@13635
    82
text {* Belongs to theory @{text Datatype_Universe}; hides popular names. *}
berghofe@13635
    83
hide const Node Atom Leaf Numb Lim Split Case Suml Sumr
berghofe@13635
    84
hide type node item
berghofe@13635
    85
wenzelm@12918
    86
wenzelm@12918
    87
subsection {* Further cases/induct rules for tuples *}
wenzelm@11954
    88
wenzelm@11954
    89
lemma prod_cases3 [case_names fields, cases type]:
wenzelm@11954
    90
    "(!!a b c. y = (a, b, c) ==> P) ==> P"
wenzelm@11954
    91
  apply (cases y)
wenzelm@11954
    92
  apply (case_tac b)
wenzelm@11954
    93
  apply blast
wenzelm@11954
    94
  done
wenzelm@11954
    95
wenzelm@11954
    96
lemma prod_induct3 [case_names fields, induct type]:
wenzelm@11954
    97
    "(!!a b c. P (a, b, c)) ==> P x"
wenzelm@11954
    98
  by (cases x) blast
wenzelm@11954
    99
wenzelm@11954
   100
lemma prod_cases4 [case_names fields, cases type]:
wenzelm@11954
   101
    "(!!a b c d. y = (a, b, c, d) ==> P) ==> P"
wenzelm@11954
   102
  apply (cases y)
wenzelm@11954
   103
  apply (case_tac c)
wenzelm@11954
   104
  apply blast
wenzelm@11954
   105
  done
wenzelm@11954
   106
wenzelm@11954
   107
lemma prod_induct4 [case_names fields, induct type]:
wenzelm@11954
   108
    "(!!a b c d. P (a, b, c, d)) ==> P x"
wenzelm@11954
   109
  by (cases x) blast
berghofe@5181
   110
wenzelm@11954
   111
lemma prod_cases5 [case_names fields, cases type]:
wenzelm@11954
   112
    "(!!a b c d e. y = (a, b, c, d, e) ==> P) ==> P"
wenzelm@11954
   113
  apply (cases y)
wenzelm@11954
   114
  apply (case_tac d)
wenzelm@11954
   115
  apply blast
wenzelm@11954
   116
  done
wenzelm@11954
   117
wenzelm@11954
   118
lemma prod_induct5 [case_names fields, induct type]:
wenzelm@11954
   119
    "(!!a b c d e. P (a, b, c, d, e)) ==> P x"
wenzelm@11954
   120
  by (cases x) blast
wenzelm@11954
   121
wenzelm@11954
   122
lemma prod_cases6 [case_names fields, cases type]:
wenzelm@11954
   123
    "(!!a b c d e f. y = (a, b, c, d, e, f) ==> P) ==> P"
wenzelm@11954
   124
  apply (cases y)
wenzelm@11954
   125
  apply (case_tac e)
wenzelm@11954
   126
  apply blast
wenzelm@11954
   127
  done
wenzelm@11954
   128
wenzelm@11954
   129
lemma prod_induct6 [case_names fields, induct type]:
wenzelm@11954
   130
    "(!!a b c d e f. P (a, b, c, d, e, f)) ==> P x"
wenzelm@11954
   131
  by (cases x) blast
wenzelm@11954
   132
wenzelm@11954
   133
lemma prod_cases7 [case_names fields, cases type]:
wenzelm@11954
   134
    "(!!a b c d e f g. y = (a, b, c, d, e, f, g) ==> P) ==> P"
wenzelm@11954
   135
  apply (cases y)
wenzelm@11954
   136
  apply (case_tac f)
wenzelm@11954
   137
  apply blast
wenzelm@11954
   138
  done
wenzelm@11954
   139
wenzelm@11954
   140
lemma prod_induct7 [case_names fields, induct type]:
wenzelm@11954
   141
    "(!!a b c d e f g. P (a, b, c, d, e, f, g)) ==> P x"
wenzelm@11954
   142
  by (cases x) blast
berghofe@5759
   143
wenzelm@12918
   144
wenzelm@12918
   145
subsection {* The option type *}
wenzelm@12918
   146
wenzelm@12918
   147
datatype 'a option = None | Some 'a
wenzelm@12918
   148
wenzelm@12918
   149
lemma not_None_eq [iff]: "(x ~= None) = (EX y. x = Some y)"
wenzelm@12918
   150
  by (induct x) auto
wenzelm@12918
   151
wenzelm@12918
   152
lemma not_Some_eq [iff]: "(ALL y. x ~= Some y) = (x = None)"
wenzelm@12918
   153
  by (induct x) auto
wenzelm@12918
   154
wenzelm@12918
   155
lemma option_caseE:
wenzelm@12918
   156
  "(case x of None => P | Some y => Q y) ==>
wenzelm@12918
   157
    (x = None ==> P ==> R) ==>
wenzelm@12918
   158
    (!!y. x = Some y ==> Q y ==> R) ==> R"
wenzelm@12918
   159
  by (cases x) simp_all
wenzelm@12918
   160
wenzelm@12918
   161
wenzelm@12918
   162
subsubsection {* Operations *}
wenzelm@12918
   163
wenzelm@12918
   164
consts
wenzelm@12918
   165
  the :: "'a option => 'a"
wenzelm@12918
   166
primrec
wenzelm@12918
   167
  "the (Some x) = x"
wenzelm@12918
   168
wenzelm@12918
   169
consts
wenzelm@12918
   170
  o2s :: "'a option => 'a set"
wenzelm@12918
   171
primrec
wenzelm@12918
   172
  "o2s None = {}"
wenzelm@12918
   173
  "o2s (Some x) = {x}"
wenzelm@12918
   174
wenzelm@12918
   175
lemma ospec [dest]: "(ALL x:o2s A. P x) ==> A = Some x ==> P x"
wenzelm@12918
   176
  by simp
wenzelm@12918
   177
wenzelm@12918
   178
ML_setup {* claset_ref() := claset() addSD2 ("ospec", thm "ospec") *}
wenzelm@12918
   179
wenzelm@12918
   180
lemma elem_o2s [iff]: "(x : o2s xo) = (xo = Some x)"
wenzelm@12918
   181
  by (cases xo) auto
wenzelm@12918
   182
wenzelm@12918
   183
lemma o2s_empty_eq [simp]: "(o2s xo = {}) = (xo = None)"
wenzelm@12918
   184
  by (cases xo) auto
wenzelm@12918
   185
wenzelm@12918
   186
wenzelm@12918
   187
constdefs
wenzelm@12918
   188
  option_map :: "('a => 'b) => ('a option => 'b option)"
wenzelm@12918
   189
  "option_map == %f y. case y of None => None | Some x => Some (f x)"
wenzelm@12918
   190
wenzelm@12918
   191
lemma option_map_None [simp]: "option_map f None = None"
wenzelm@12918
   192
  by (simp add: option_map_def)
wenzelm@12918
   193
wenzelm@12918
   194
lemma option_map_Some [simp]: "option_map f (Some x) = Some (f x)"
wenzelm@12918
   195
  by (simp add: option_map_def)
wenzelm@12918
   196
nipkow@14187
   197
lemma option_map_is_None[iff]:
nipkow@14187
   198
 "(option_map f opt = None) = (opt = None)"
nipkow@14187
   199
by (simp add: option_map_def split add: option.split)
nipkow@14187
   200
wenzelm@12918
   201
lemma option_map_eq_Some [iff]:
wenzelm@12918
   202
    "(option_map f xo = Some y) = (EX z. xo = Some z & f z = y)"
nipkow@14187
   203
by (simp add: option_map_def split add: option.split)
nipkow@14187
   204
nipkow@14187
   205
lemma option_map_comp:
nipkow@14187
   206
 "option_map f (option_map g opt) = option_map (f o g) opt"
nipkow@14187
   207
by (simp add: option_map_def split add: option.split)
wenzelm@12918
   208
wenzelm@12918
   209
lemma option_map_o_sum_case [simp]:
wenzelm@12918
   210
    "option_map f o sum_case g h = sum_case (option_map f o g) (option_map f o h)"
wenzelm@12918
   211
  apply (rule ext)
wenzelm@12918
   212
  apply (simp split add: sum.split)
wenzelm@12918
   213
  done
wenzelm@12918
   214
berghofe@5181
   215
end