src/Doc/Datatypes/Datatypes.thy
changeset 53025 c820c9e9e8f4
parent 53018 11ebef554439
child 53028 a1e64c804c35
equal deleted inserted replaced
53024:e0968e1f6fe9 53025:c820c9e9e8f4
    42 
    42 
    43     datatype_new 'a treeFS = NodeFS 'a "'a treeFS fset"
    43     datatype_new 'a treeFS = NodeFS 'a "'a treeFS fset"
    44 
    44 
    45 text {*
    45 text {*
    46 \noindent
    46 \noindent
    47 Another strong point is that the package supports local definitions:
    47 Another strong point is the support for local definitions:
    48 *}
    48 *}
    49 
    49 
    50     context linorder
    50     context linorder
    51     begin
    51     begin
    52     datatype_new flag = Less | Eq | Greater
    52     datatype_new flag = Less | Eq | Greater
    55 text {*
    55 text {*
    56 \noindent
    56 \noindent
    57 The package also provides some convenience, notably automatically generated
    57 The package also provides some convenience, notably automatically generated
    58 destructors (discriminators and selectors).
    58 destructors (discriminators and selectors).
    59 
    59 
    60 In addition to plain inductive datatypes, the package supports coinductive
    60 In addition to plain inductive datatypes, the new package supports coinductive
    61 datatypes, or \emph{codatatypes}, which may have infinite values. For example,
    61 datatypes, or \emph{codatatypes}, which may have infinite values. For example,
    62 the following command introduces the type of lazy lists:
    62 the following command introduces the type of lazy lists:
    63 *}
    63 *}
    64 
    64 
    65     codatatype 'a llist = LNil | LCons 'a "'a llist"
    65     codatatype 'a llist (*<*)(map: lmap) (*>*)= LNil | LCons 'a "'a llist"
    66 
    66 
    67 text {*
    67 text {*
    68 \noindent
    68 \noindent
    69 Mixed inductive--coinductive recursion is possible via nesting. Compare the
    69 Mixed inductive--coinductive recursion is possible via nesting. Compare the
    70 following four examples:
    70 following four examples:
    71 
    71 *}
    72 %%% TODO: Avoid 0
    72 
    73 *}
    73 (*<*)
    74 
    74     locale dummy_tree
    75     datatype_new 'a treeFF0 = NodeFF 'a "'a treeFF0 list"
    75     begin
    76     datatype_new 'a treeFI0 = NodeFI 'a "'a treeFI0 llist"
    76 (*>*)
    77     codatatype 'a treeIF0 = NodeIF 'a "'a treeIF0 list"
    77     datatype_new 'a treeFF = NodeFF 'a "'a treeFF list"
    78     codatatype 'a treeII0 = NodeII 'a "'a treeII0 llist"
    78     datatype_new 'a treeFI = NodeFI 'a "'a treeFI llist"
       
    79     codatatype 'a treeIF = NodeIF 'a "'a treeIF list"
       
    80     codatatype 'a treeII = NodeII 'a "'a treeII llist"
       
    81 (*<*)
       
    82     end
       
    83 (*>*)
    79 
    84 
    80 text {*
    85 text {*
    81 The first two tree types allow only finite branches, whereas the last two allow
    86 The first two tree types allow only finite branches, whereas the last two allow
    82 infinite branches. Orthogonally, the nodes in the first and third types have
    87 infinite branches. Orthogonally, the nodes in the first and third types have
    83 finite branching, whereas those of the second and fourth may have infinitely
    88 finite branching, whereas those of the second and fourth may have infinitely
   197 *}
   202 *}
   198 
   203 
   199     datatype_new trool = Truue | Faalse | Perhaaps
   204     datatype_new trool = Truue | Faalse | Perhaaps
   200 
   205 
   201 text {*
   206 text {*
   202 Haskell-style option type:
   207 Option type:
   203 *}
   208 *}
   204 
   209 
   205     datatype_new 'a maybe = Nothing | Just 'a
   210 (*<*)
       
   211     hide_const None Some
       
   212 (*>*)
       
   213     datatype_new 'a option = None | Some 'a
   206 
   214 
   207 text {*
   215 text {*
   208 triple:
   216 triple:
   209 *}
   217 *}
   210 
   218 
   215 
   223 
   216 text {*
   224 text {*
   217 simplest recursive type: natural numbers
   225 simplest recursive type: natural numbers
   218 *}
   226 *}
   219 
   227 
   220     datatype_new nat = Zero | Suc nat
   228 (*<*)
       
   229     (* FIXME: remove "rep_compat" once "datatype_new" is integrated with "fun" *)
       
   230 (*>*)
       
   231     datatype_new (*<*)(rep_compat) (*>*)nat = Zero | Suc nat
   221 
   232 
   222 text {*
   233 text {*
   223 Setup to be able to write @{text 0} instead of @{const Zero}:
   234 Setup to be able to write @{text 0} instead of @{const Zero}:
   224 *}
   235 *}
   225 
   236 
   271 text {*
   282 text {*
   272 Nested recursion = Have recursion through a type constructor.
   283 Nested recursion = Have recursion through a type constructor.
   273 
   284 
   274 The introduction showed some examples of trees with nesting through lists.
   285 The introduction showed some examples of trees with nesting through lists.
   275 
   286 
   276 More complex example, which reuses our maybe:
   287 More complex example, which reuses our option type:
   277 *}
   288 *}
   278 
   289 
   279     datatype_new 'a btree =
   290     datatype_new 'a btree =
   280       BNode 'a "'a btree maybe" "'a btree maybe"
   291       BNode 'a "'a btree option" "'a btree option"
   281 
   292 
   282 text {*
   293 text {*
   283 Recursion may not be arbitrary; e.g. impossible to define
   294 Recursion may not be arbitrary; e.g. impossible to define
   284 *}
   295 *}
   285 
   296 
   328 The discriminators and selectors are collectively called \emph{destructors}. The
   339 The discriminators and selectors are collectively called \emph{destructors}. The
   329 @{text "t."} prefix is an optional component of the name and is normally hidden.
   340 @{text "t."} prefix is an optional component of the name and is normally hidden.
   330 
   341 
   331 The set functions, map function, relator, discriminators, and selectors can be
   342 The set functions, map function, relator, discriminators, and selectors can be
   332 given custom names, as in the example below:
   343 given custom names, as in the example below:
   333 
       
   334 %%% FIXME: get rid of 0 below
       
   335 *}
   344 *}
   336 
   345 
   337 (*<*)
   346 (*<*)
   338     no_translations
   347     no_translations
   339       "[x, xs]" == "x # [xs]"
   348       "[x, xs]" == "x # [xs]"
   342     no_notation
   351     no_notation
   343       Nil ("[]") and
   352       Nil ("[]") and
   344       Cons (infixr "#" 65)
   353       Cons (infixr "#" 65)
   345 
   354 
   346     hide_const Nil Cons hd tl map
   355     hide_const Nil Cons hd tl map
       
   356 
       
   357     locale dummy_list
       
   358     begin
   347 (*>*)
   359 (*>*)
   348     datatype_new (set0: 'a) list0 (map: map0 rel: list0_all2) =
   360     datatype_new (set: 'a) list (map: map rel: list_all2) =
   349       null: Nil (defaults tl: Nil)
   361       null: Nil (defaults tl: Nil)
   350     | Cons (hd: 'a) (tl: "'a list0")
   362     | Cons (hd: 'a) (tl: "'a list")
   351 
   363 
   352 text {*
   364 text {*
   353 \noindent
   365 \noindent
   354 The command introduces a discriminator @{const null} and a pair of selectors
   366 The command introduces a discriminator @{const null} and a pair of selectors
   355 @{const hd} and @{const tl} characterized as follows:
   367 @{const hd} and @{const tl} characterized as follows:
   356 %
   368 %
   357 \[@{thm list0.collapse(1)[of xs, no_vars]}
   369 \[@{thm list.collapse(1)[of xs, no_vars]}
   358   \qquad @{thm list0.collapse(2)[of xs, no_vars]}\]
   370   \qquad @{thm list.collapse(2)[of xs, no_vars]}\]
   359 %
   371 %
   360 For two-constructor datatypes, a single discriminator constant suffices. The
   372 For two-constructor datatypes, a single discriminator constant suffices. The
   361 discriminator associated with @{const Cons} is simply @{text "\<not> null"}.
   373 discriminator associated with @{const Cons} is simply @{text "\<not> null"}.
   362 
   374 
   363 The \keyw{defaults} keyword following the @{const Nil} constructor specifies a
   375 The \keyw{defaults} keyword following the @{const Nil} constructor specifies a
   378 
   390 
   379 %%% FIXME: remove trailing underscore and use locale trick instead once this is
   391 %%% FIXME: remove trailing underscore and use locale trick instead once this is
   380 %%% supported.
   392 %%% supported.
   381 *}
   393 *}
   382 
   394 
       
   395 (*<*)
       
   396     end
       
   397 (*>*)
   383     datatype_new ('a, 'b) prod (infixr "*" 20) =
   398     datatype_new ('a, 'b) prod (infixr "*" 20) =
   384       Pair 'a 'b
   399       Pair 'a 'b
   385 
   400 
   386 (*<*)
       
   387     hide_const Nil Cons hd tl
       
   388 (*>*)
       
   389     datatype_new (set: 'a) list (map: map rel: list_all2) =
   401     datatype_new (set: 'a) list (map: map rel: list_all2) =
   390       null: Nil ("[]")
   402       null: Nil ("[]")
   391     | Cons (hd: 'a) (tl: "'a list") (infixr "#" 65)
   403     | Cons (hd: 'a) (tl: "'a list") (infixr "#" 65)
   392 
   404 
   393 text {*
   405 text {*
   394 Incidentally, this is how the traditional syntaxes are set up in @{theory List}:
   406 Incidentally, this is how the traditional syntaxes can be set up:
   395 *}
   407 *}
   396 
   408 
   397     syntax "_list" :: "args \<Rightarrow> 'a list" ("[(_)]")
   409     syntax "_list" :: "args \<Rightarrow> 'a list" ("[(_)]")
   398 
   410 
   399     translations
   411     translations
   576 text {*
   588 text {*
   577   * simple (depth 1) pattern matching on the left-hand side
   589   * simple (depth 1) pattern matching on the left-hand side
   578 *}
   590 *}
   579 
   591 
   580     primrec_new bool_of_trool :: "trool \<Rightarrow> bool" where
   592     primrec_new bool_of_trool :: "trool \<Rightarrow> bool" where
   581       "real_of_trool Faalse = False" |
   593       "bool_of_trool Faalse = False" |
   582       "real_of_trool Truue = True"
   594       "bool_of_trool Truue = True"
   583 
   595 
   584 text {*
   596 text {*
   585   * OK to specify the cases in a different order
   597   * OK to specify the cases in a different order
   586   * OK to leave out some case (but get a warning -- maybe we need a "quiet"
   598   * OK to leave out some case (but get a warning -- maybe we need a "quiet"
   587     or "silent" flag?)
   599     or "silent" flag?)
   588     * case is then unspecified
   600     * case is then unspecified
   589 
   601 
   590 More examples:
   602 More examples:
   591 *}
   603 *}
   592 
   604 
   593     primrec_new list_of_maybe :: "'a maybe \<Rightarrow> 'a list" where
   605     primrec_new the_list :: "'a option \<Rightarrow> 'a list" where
   594       "list_of_maybe Nothing = []" |
   606       "the_list None = []" |
   595       "list_of_maybe (Just a) = [a]"
   607       "the_list (Some a) = [a]"
   596 
   608 
   597     primrec_new maybe_def :: "'a \<Rightarrow> 'a maybe \<Rightarrow> 'a" where
   609     primrec_new the_default :: "'a \<Rightarrow> 'a option \<Rightarrow> 'a" where
   598       "maybe_def d Nothing = d" |
   610       "the_default d None = d" |
   599       "maybe_def _ (Just a) = a"
   611       "the_default _ (Some a) = a"
   600 
   612 
   601     primrec_new mirrror :: "('a, 'b, 'c) triple \<Rightarrow> ('c, 'b, 'a) triple" where
   613     primrec_new mirrror :: "('a, 'b, 'c) triple \<Rightarrow> ('c, 'b, 'a) triple" where
   602       "mirrror (Triple a b c) = Triple c b a"
   614       "mirrror (Triple a b c) = Triple c b a"
   603 
   615 
   604 
   616 
   625 
   637 
   626     primrec_new tfold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a, 'b) tlist \<Rightarrow> 'b" where
   638     primrec_new tfold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a, 'b) tlist \<Rightarrow> 'b" where
   627       "tfold _ (TNil b) = b" |
   639       "tfold _ (TNil b) = b" |
   628       "tfold f (TCons a as) = f a (tfold f as)"
   640       "tfold f (TCons a as) = f a (tfold f as)"
   629 
   641 
       
   642 text {*
       
   643 Show one example where fun is needed.
       
   644 *}
   630 
   645 
   631 subsubsection {* Mutual Recursion *}
   646 subsubsection {* Mutual Recursion *}
   632 
   647 
   633 text {*
   648 text {*
   634 E.g., converting even/odd naturals to plain old naturals:
   649 E.g., converting even/odd naturals to plain old naturals:
   641       "nat_of_enat EZero = 0" |
   656       "nat_of_enat EZero = 0" |
   642       "nat_of_enat (ESuc n) = Suc (nat_of_onat n)" |
   657       "nat_of_enat (ESuc n) = Suc (nat_of_onat n)" |
   643       "nat_of_onat (OSuc n) = Suc (nat_of_enat n)"
   658       "nat_of_onat (OSuc n) = Suc (nat_of_enat n)"
   644 
   659 
   645 text {*
   660 text {*
   646 Mutual recursion is even possible within a single type, an innovation over the
   661 Mutual recursion is be possible within a single type, but currently only using fun:
   647 old package:
   662 *}
   648 *}
   663 
   649 
   664 (*<*)
   650     primrec_new
   665     (* FIXME: remove hack once "primrec_new" is in place *)
       
   666     rep_datatype "0\<Colon>nat" Suc
       
   667     unfolding zero_nat_def by (erule nat.induct, assumption) auto
       
   668 (*>*)
       
   669     fun
   651       even :: "nat \<Rightarrow> bool" and
   670       even :: "nat \<Rightarrow> bool" and
   652       odd :: "nat \<Rightarrow> bool"
   671       odd :: "nat \<Rightarrow> bool"
   653     where
   672     where
   654       "even 0 = True" |
   673       "even 0 = True" |
   655       "even (Suc n) = odd n" |
   674       "even (Suc n) = odd n" |
   656       "odd 0 = False" |
   675       "odd 0 = False" |
   657       "odd (Suc n) = even n"
   676       "odd (Suc n) = even n"
   658 
   677 
   659 text {*
   678 text {*
   660 More elaborate:
   679 More elaborate example that works with primrec_new:
   661 *}
   680 *}
   662 
   681 
   663     primrec_new
   682     primrec_new
   664       eval\<^sub>e :: "('a, 'b) exp \<Rightarrow> real" and
   683       eval\<^sub>e :: "('a, 'b) exp \<Rightarrow> real" and
   665       eval\<^sub>t :: "('a, 'b) trm \<Rightarrow> real" and
   684       eval\<^sub>t :: "('a, 'b) trm \<Rightarrow> real" and
   678 
   697 
   679 (*<*)
   698 (*<*)
   680     datatype_new 'a treeFF = NodeFF 'a "'a treeFF list"
   699     datatype_new 'a treeFF = NodeFF 'a "'a treeFF list"
   681     datatype_new 'a treeFI = NodeFI 'a "'a treeFI llist"
   700     datatype_new 'a treeFI = NodeFI 'a "'a treeFI llist"
   682 (*>*)
   701 (*>*)
   683     primrec_new atFF0 :: "'a treeFF \<Rightarrow> nat list \<Rightarrow> 'a" where
   702     primrec_new atFF :: "'a treeFF \<Rightarrow> nat list \<Rightarrow> 'a" where
   684       "atFF0 (NodeFF a ts) js =
   703       "atFF (NodeFF a ts) js =
   685          (case js of
   704          (case js of
   686             [] \<Rightarrow> a
   705             [] \<Rightarrow> a
   687           | j # js' \<Rightarrow> at (map (\<lambda>t. atFF0 t js') ts) j)"
   706           | j # js' \<Rightarrow> at (map (\<lambda>t. atFF t js') ts) j)"
   688 
   707 
   689     primrec_new atFI :: "'a treeFI \<Rightarrow> nat list \<Rightarrow> 'a" where
   708     primrec_new atFI :: "'a treeFI \<Rightarrow> nat list \<Rightarrow> 'a" where
   690       "atFF (NodeFI a ts) js =
   709       "atFI (NodeFI a ts) js =
   691          (case js of
   710          (case js of
   692             [] \<Rightarrow> a
   711             [] \<Rightarrow> a
   693           | j # js' \<Rightarrow> at (llist_map (\<lambda>t. atFF t js') ts) j)"
   712           | j # js' \<Rightarrow> at (lmap (\<lambda>t. atFI t js') ts) j)"
       
   713 
       
   714 text {*
       
   715 Explain @{const lmap}.
       
   716 *}
   694 
   717 
   695     primrec_new sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" where
   718     primrec_new sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" where
   696       "sum_btree (BNode a lt rt) =
   719       "sum_btree (BNode a lt rt) =
   697          a + maybe_def 0 (maybe_map sum_btree lt) +
   720          a + the_default 0 (option_map sum_btree lt) +
   698            maybe_def 0 (maybe_map sum_btree rt)"
   721            the_default 0 (option_map sum_btree rt)"
   699 
   722 
   700 
   723 
   701 subsubsection {* Nested-as-Mutual Recursion *}
   724 subsubsection {* Nested-as-Mutual Recursion *}
   702 
   725 
   703 text {*
   726 text {*
   719             0 \<Rightarrow> at_treeFF t
   742             0 \<Rightarrow> at_treeFF t
   720           | Suc j' \<Rightarrow> at_treesFF ts j')"
   743           | Suc j' \<Rightarrow> at_treesFF ts j')"
   721 
   744 
   722     primrec_new
   745     primrec_new
   723       sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" and
   746       sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" and
   724       sum_btree_maybe :: "('a\<Colon>plus) btree maybe \<Rightarrow> 'a"
   747       sum_btree_option :: "('a\<Colon>plus) btree option \<Rightarrow> 'a"
   725     where
   748     where
   726       "sum_btree (BNode a lt rt) =
   749       "sum_btree (BNode a lt rt) =
   727          a + sum_btree_maybe lt + sum_btree_maybe rt" |
   750          a + sum_btree_option lt + sum_btree_option rt" |
   728       "sum_btree_maybe Nothing = 0" |
   751       "sum_btree_option None = 0" |
   729       "sum_btree_maybe (Just t) = sum_btree t"
   752       "sum_btree_option (Some t) = sum_btree t"
   730 
   753 
   731 text {*
   754 text {*
   732   * this can always be avoided;
   755   * this can always be avoided;
   733      * e.g. in our previous example, we first mapped the recursive
   756      * e.g. in our previous example, we first mapped the recursive
   734        calls, then we used a generic at function to retrieve the result
   757        calls, then we used a generic at function to retrieve the result
   737     just like there's no rule when to use fold and when to use
   760     just like there's no rule when to use fold and when to use
   738     primrec_new
   761     primrec_new
   739 
   762 
   740   * higher-order approach, considering nesting as nesting, is more
   763   * higher-order approach, considering nesting as nesting, is more
   741     compositional -- e.g. we saw how we could reuse an existing polymorphic
   764     compositional -- e.g. we saw how we could reuse an existing polymorphic
   742     at or maybe_def, whereas at_treesFF is much more specific
   765     at or the_default, whereas at_treesFF is much more specific
   743 
   766 
   744   * but:
   767   * but:
   745      * is perhaps less intuitive, because it requires higher-order thinking
   768      * is perhaps less intuitive, because it requires higher-order thinking
   746      * may seem inefficient, and indeed with the code generator the
   769      * may seem inefficient, and indeed with the code generator the
   747        mutually recursive version might be nicer
   770        mutually recursive version might be nicer
  1086 Tobias Nipkow and Makarius Wenzel made this work possible. Andreas Lochbihler
  1109 Tobias Nipkow and Makarius Wenzel made this work possible. Andreas Lochbihler
  1087 provided lots of comments on earlier versions of the package, especially for the
  1110 provided lots of comments on earlier versions of the package, especially for the
  1088 coinductive part. Brian Huffman suggested major simplifications to the internal
  1111 coinductive part. Brian Huffman suggested major simplifications to the internal
  1089 constructions, much of which has yet to be implemented. Florian Haftmann and
  1112 constructions, much of which has yet to be implemented. Florian Haftmann and
  1090 Christian Urban provided general advice advice on Isabelle and package writing.
  1113 Christian Urban provided general advice advice on Isabelle and package writing.
  1091 Stefan Milius and Lutz Schr\"oder suggested an elegant prove to eliminate one of
  1114 Stefan Milius and Lutz Schr\"oder suggested an elegant proof to eliminate one of
  1092 the BNF assumptions.
  1115 the BNF assumptions.
  1093 *}
  1116 *}
  1094 
  1117 
  1095 end
  1118 end