src/Doc/Datatypes/Datatypes.thy
author blanchet
Mon, 02 Dec 2013 20:31:54 +0100
changeset 55989 a21a2223c02b
parent 55975 168790252038
child 55994 82a78bc9fa0d
permissions -rw-r--r--
minor doc update
blanchet@53929
     1
(*  Title:      Doc/Datatypes/Datatypes.thy
blanchet@53929
     2
    Author:     Jasmin Blanchette, TU Muenchen
blanchet@54754
     3
    Author:     Lorenz Panny, TU Muenchen
blanchet@54754
     4
    Author:     Andrei Popescu, TU Muenchen
blanchet@54754
     5
    Author:     Dmitriy Traytel, TU Muenchen
blanchet@53929
     6
blanchet@53929
     7
Tutorial for (co)datatype definitions with the new package.
blanchet@53929
     8
*)
blanchet@53929
     9
blanchet@53929
    10
theory Datatypes
blanchet@55775
    11
imports Setup "~~/src/HOL/Library/Simps_Case_Conv"
blanchet@53929
    12
begin
blanchet@53929
    13
blanchet@53965
    14
section {* Introduction
blanchet@53965
    15
  \label{sec:introduction} *}
blanchet@53929
    16
blanchet@53929
    17
text {*
blanchet@54165
    18
The 2013 edition of Isabelle introduced a new definitional package for freely
blanchet@54165
    19
generated datatypes and codatatypes. The datatype support is similar to that
blanchet@54165
    20
provided by the earlier package due to Berghofer and Wenzel
blanchet@54165
    21
\cite{Berghofer-Wenzel:1999:TPHOL}, documented in the Isar reference manual
blanchet@54672
    22
\cite{isabelle-isar-ref}; indeed, replacing the keyword \keyw{datatype} by
blanchet@54165
    23
@{command datatype_new} is usually all that is needed to port existing theories
blanchet@54165
    24
to use the new package.
blanchet@53977
    25
blanchet@53978
    26
Perhaps the main advantage of the new package is that it supports recursion
blanchet@54756
    27
through a large class of non-datatypes, such as finite sets:
blanchet@53929
    28
*}
blanchet@53929
    29
blanchet@54781
    30
    datatype_new 'a tree\<^sub>f\<^sub>s = Node\<^sub>f\<^sub>s (lbl\<^sub>f\<^sub>s: 'a) (sub\<^sub>f\<^sub>s: "'a tree\<^sub>f\<^sub>s fset")
blanchet@53929
    31
blanchet@53929
    32
text {*
blanchet@53931
    33
\noindent
blanchet@54162
    34
Another strong point is the support for local definitions:
blanchet@53929
    35
*}
blanchet@53929
    36
blanchet@53942
    37
    context linorder
blanchet@53942
    38
    begin
blanchet@53978
    39
    datatype_new flag = Less | Eq | Greater
blanchet@53942
    40
    end
blanchet@53929
    41
blanchet@53929
    42
text {*
blanchet@53931
    43
\noindent
blanchet@55639
    44
Furthermore, the package provides a lot of convenience, including automatically
blanchet@55639
    45
generated discriminators, selectors, and relators as well as a wealth of
blanchet@55639
    46
properties about them.
blanchet@55639
    47
blanchet@55639
    48
In addition to inductive datatypes, the new package supports coinductive
blanchet@55639
    49
datatypes, or \emph{codatatypes}, which allow infinite values. For example, the
blanchet@55639
    50
following command introduces the type of lazy lists, which comprises both finite
blanchet@55639
    51
and infinite values:
blanchet@53929
    52
*}
blanchet@53929
    53
blanchet@54760
    54
(*<*)
blanchet@54886
    55
    locale early
blanchet@55524
    56
    locale late
blanchet@54760
    57
(*>*)
blanchet@54886
    58
    codatatype (*<*)(in early) (*>*)'a llist = LNil | LCons 'a "'a llist"
blanchet@53931
    59
blanchet@53931
    60
text {*
blanchet@53931
    61
\noindent
blanchet@53977
    62
Mixed inductive--coinductive recursion is possible via nesting. Compare the
blanchet@54165
    63
following four Rose tree examples:
blanchet@53931
    64
*}
blanchet@53931
    65
blanchet@54886
    66
    datatype_new (*<*)(in early) (*>*)'a tree\<^sub>f\<^sub>f = Node\<^sub>f\<^sub>f 'a "'a tree\<^sub>f\<^sub>f list"
blanchet@54886
    67
    datatype_new (*<*)(in early) (*>*)'a tree\<^sub>f\<^sub>i = Node\<^sub>f\<^sub>i 'a "'a tree\<^sub>f\<^sub>i llist"
blanchet@54886
    68
    codatatype (*<*)(in early) (*>*)'a tree\<^sub>i\<^sub>f = Node\<^sub>i\<^sub>f 'a "'a tree\<^sub>i\<^sub>f list"
blanchet@54886
    69
    codatatype (*<*)(in early) (*>*)'a tree\<^sub>i\<^sub>i = Node\<^sub>i\<^sub>i 'a "'a tree\<^sub>i\<^sub>i llist"
blanchet@53931
    70
blanchet@53931
    71
text {*
blanchet@55639
    72
The first two tree types allow only paths of finite length, whereas the last two
blanchet@55639
    73
allow infinite paths. Orthogonally, the nodes in the first and third types have
blanchet@55639
    74
finitely many direct subtrees, whereas those of the second and fourth may have
blanchet@55639
    75
infinite branching.
blanchet@53977
    76
blanchet@53931
    77
To use the package, it is necessary to import the @{theory BNF} theory, which
blanchet@54689
    78
can be precompiled into the \texttt{HOL-BNF} image. The following commands show
blanchet@53943
    79
how to launch jEdit/PIDE with the image loaded and how to build the image
blanchet@53943
    80
without launching jEdit:
blanchet@53931
    81
*}
blanchet@53931
    82
blanchet@53931
    83
text {*
blanchet@53931
    84
\noindent
blanchet@53943
    85
\ \ \ \ \texttt{isabelle jedit -l HOL-BNF} \\
blanchet@53964
    86
\noindent
blanchet@53965
    87
\hbox{}\ \ \ \ \texttt{isabelle build -b HOL-BNF}
blanchet@53931
    88
*}
blanchet@53931
    89
blanchet@53931
    90
text {*
blanchet@53942
    91
The package, like its predecessor, fully adheres to the LCF philosophy
blanchet@53942
    92
\cite{mgordon79}: The characteristic theorems associated with the specified
blanchet@53942
    93
(co)datatypes are derived rather than introduced axiomatically.%
blanchet@54680
    94
\footnote{If the @{text quick_and_dirty} option is enabled, some of the
blanchet@53978
    95
internal constructions and most of the internal proof obligations are skipped.}
blanchet@53942
    96
The package's metatheory is described in a pair of papers
blanchet@54689
    97
\cite{traytel-et-al-2012,blanchette-et-al-wit}. The central notion is that of a
blanchet@54689
    98
\emph{bounded natural functor} (BNF)---a well-behaved type constructor for which
blanchet@54689
    99
nested (co)recursion is supported.
blanchet@53931
   100
blanchet@53931
   101
This tutorial is organized as follows:
blanchet@53931
   102
blanchet@53942
   103
\begin{itemize}
blanchet@53959
   104
\setlength{\itemsep}{0pt}
blanchet@53959
   105
blanchet@53942
   106
\item Section \ref{sec:defining-datatypes}, ``Defining Datatypes,''
blanchet@53959
   107
describes how to specify datatypes using the @{command datatype_new} command.
blanchet@53931
   108
blanchet@54155
   109
\item Section \ref{sec:defining-recursive-functions}, ``Defining Recursive
blanchet@53942
   110
Functions,'' describes how to specify recursive functions using
blanchet@54672
   111
@{command primrec_new}, \keyw{fun}, and \keyw{function}.
blanchet@53931
   112
blanchet@53942
   113
\item Section \ref{sec:defining-codatatypes}, ``Defining Codatatypes,''
blanchet@54966
   114
describes how to specify codatatypes using the @{command codatatype} command.
blanchet@53931
   115
blanchet@54155
   116
\item Section \ref{sec:defining-corecursive-functions}, ``Defining Corecursive
blanchet@53942
   117
Functions,'' describes how to specify corecursive functions using the
blanchet@54963
   118
@{command primcorec} and @{command primcorecursive} commands.
blanchet@53942
   119
blanchet@54155
   120
\item Section \ref{sec:registering-bounded-natural-functors}, ``Registering
blanchet@54689
   121
Bounded Natural Functors,'' explains how to use the @{command bnf} command
blanchet@54689
   122
to register arbitrary type constructors as BNFs.
blanchet@53942
   123
blanchet@54689
   124
\item Section
blanchet@54754
   125
\ref{sec:deriving-destructors-and-theorems-for-free-constructors},
blanchet@54754
   126
``Deriving Destructors and Theorems for Free Constructors,'' explains how to
blanchet@54689
   127
use the command @{command wrap_free_constructors} to derive destructor constants
blanchet@54689
   128
and theorems for freely generated types, as performed internally by @{command
blanchet@54966
   129
datatype_new} and @{command codatatype}.
blanchet@53942
   130
blanchet@54754
   131
%\item Section \ref{sec:standard-ml-interface}, ``Standard ML Interface,''
blanchet@54754
   132
%describes the package's programmatic interface.
blanchet@53942
   133
blanchet@54754
   134
%\item Section \ref{sec:interoperability}, ``Interoperability,''
blanchet@54754
   135
%is concerned with the packages' interaction with other Isabelle packages and
blanchet@54754
   136
%tools, such as the code generator and the counterexample generators.
blanchet@53942
   137
blanchet@54754
   138
%\item Section \ref{sec:known-bugs-and-limitations}, ``Known Bugs and
blanchet@54754
   139
%Limitations,'' concludes with known open issues at the time of writing.
blanchet@53942
   140
\end{itemize}
blanchet@53959
   141
blanchet@53959
   142
blanchet@53959
   143
\newbox\boxA
blanchet@55637
   144
\setbox\boxA=\hbox{\texttt{NOSPAM}}
blanchet@55637
   145
blanchet@55637
   146
\newcommand\authoremaili{\texttt{blan{\color{white}NOSPAM}\kern-\wd\boxA{}chette@\allowbreak
blanchet@53959
   147
in.\allowbreak tum.\allowbreak de}}
blanchet@55637
   148
\newcommand\authoremailii{\texttt{lore{\color{white}NOSPAM}\kern-\wd\boxA{}nz.panny@\allowbreak
blanchet@54165
   149
\allowbreak tum.\allowbreak de}}
blanchet@55637
   150
\newcommand\authoremailiii{\texttt{pope{\color{white}NOSPAM}\kern-\wd\boxA{}scua@\allowbreak
blanchet@53959
   151
in.\allowbreak tum.\allowbreak de}}
blanchet@55637
   152
\newcommand\authoremailiv{\texttt{tray{\color{white}NOSPAM}\kern-\wd\boxA{}tel@\allowbreak
blanchet@53959
   153
in.\allowbreak tum.\allowbreak de}}
blanchet@53959
   154
blanchet@54165
   155
The commands @{command datatype_new} and @{command primrec_new} are expected to
blanchet@55000
   156
replace \keyw{datatype} and \keyw{primrec} in a future release. Authors of new
blanchet@54672
   157
theories are encouraged to use the new commands, and maintainers of older
blanchet@54165
   158
theories may want to consider upgrading.
blanchet@53978
   159
blanchet@53978
   160
Comments and bug reports concerning either the tool or this tutorial should be
blanchet@54165
   161
directed to the authors at \authoremaili, \authoremailii, \authoremailiii,
blanchet@54165
   162
and \authoremailiv.
blanchet@53931
   163
*}
blanchet@53931
   164
blanchet@54628
   165
blanchet@53964
   166
section {* Defining Datatypes
blanchet@53942
   167
  \label{sec:defining-datatypes} *}
blanchet@53942
   168
blanchet@53942
   169
text {*
blanchet@54783
   170
Datatypes can be specified using the @{command datatype_new} command.
blanchet@53942
   171
*}
blanchet@53929
   172
blanchet@53961
   173
blanchet@54754
   174
subsection {* Introductory Examples
blanchet@54754
   175
  \label{ssec:datatype-introductory-examples} *}
blanchet@53931
   176
blanchet@54783
   177
text {*
blanchet@54783
   178
Datatypes are illustrated through concrete examples featuring different flavors
blanchet@54783
   179
of recursion. More examples can be found in the directory
blanchet@55637
   180
\verb|~~/src/HOL/|\allowbreak\verb|BNF/Examples|.
blanchet@54783
   181
*}
blanchet@54758
   182
blanchet@54758
   183
subsubsection {* Nonrecursive Types
blanchet@54758
   184
  \label{sssec:datatype-nonrecursive-types} *}
blanchet@53931
   185
blanchet@53942
   186
text {*
blanchet@54165
   187
Datatypes are introduced by specifying the desired names and argument types for
blanchet@54628
   188
their constructors. \emph{Enumeration} types are the simplest form of datatype.
blanchet@54165
   189
All their constructors are nullary:
blanchet@53942
   190
*}
blanchet@53942
   191
blanchet@53965
   192
    datatype_new trool = Truue | Faalse | Perhaaps
blanchet@53942
   193
blanchet@53942
   194
text {*
blanchet@54165
   195
\noindent
blanchet@54628
   196
Here, @{const Truue}, @{const Faalse}, and @{const Perhaaps} have the type @{typ trool}.
blanchet@54165
   197
blanchet@54165
   198
Polymorphic types are possible, such as the following option type, modeled after
blanchet@54165
   199
its homologue from the @{theory Option} theory:
blanchet@53942
   200
*}
blanchet@53942
   201
blanchet@54162
   202
(*<*)
blanchet@54162
   203
    hide_const None Some
blanchet@54162
   204
(*>*)
blanchet@54162
   205
    datatype_new 'a option = None | Some 'a
blanchet@53942
   206
blanchet@53942
   207
text {*
blanchet@54165
   208
\noindent
blanchet@54628
   209
The constructors are @{text "None :: 'a option"} and
blanchet@54628
   210
@{text "Some :: 'a \<Rightarrow> 'a option"}.
blanchet@54165
   211
blanchet@54165
   212
The next example has three type parameters:
blanchet@53942
   213
*}
blanchet@53942
   214
blanchet@53942
   215
    datatype_new ('a, 'b, 'c) triple = Triple 'a 'b 'c
blanchet@53942
   216
blanchet@54165
   217
text {*
blanchet@54165
   218
\noindent
blanchet@54165
   219
The constructor is
blanchet@54628
   220
@{text "Triple :: 'a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> ('a, 'b, 'c) triple"}.
blanchet@54165
   221
Unlike in Standard ML, curried constructors are supported. The uncurried variant
blanchet@54165
   222
is also possible:
blanchet@54165
   223
*}
blanchet@54165
   224
blanchet@54165
   225
    datatype_new ('a, 'b, 'c) triple\<^sub>u = Triple\<^sub>u "'a * 'b * 'c"
blanchet@54165
   226
blanchet@53942
   227
text {*
blanchet@54628
   228
\noindent
blanchet@54689
   229
Occurrences of nonatomic types on the right-hand side of the equal sign must be
blanchet@54689
   230
enclosed in double quotes, as is customary in Isabelle.
blanchet@53942
   231
*}
blanchet@53942
   232
blanchet@53961
   233
blanchet@55000
   234
subsubsection {* Simple Recursion
blanchet@55000
   235
  \label{sssec:datatype-simple-recursion} *}
blanchet@55000
   236
blanchet@55000
   237
text {*
blanchet@55000
   238
Natural numbers are the simplest example of a recursive type:
blanchet@55000
   239
*}
blanchet@55000
   240
blanchet@55000
   241
    datatype_new nat = Zero | Suc nat
blanchet@55000
   242
blanchet@55000
   243
text {*
blanchet@55000
   244
\noindent
blanchet@55639
   245
Lists were shown in the introduction. Terminated lists are a variant that
blanchet@55639
   246
stores a value of type @{typ 'b} at the very end:
blanchet@55000
   247
*}
blanchet@55000
   248
blanchet@55000
   249
    datatype_new (*<*)(in early) (*>*)('a, 'b) tlist = TNil 'b | TCons 'a "('a, 'b) tlist"
blanchet@55000
   250
blanchet@55000
   251
blanchet@54758
   252
subsubsection {* Mutual Recursion
blanchet@54758
   253
  \label{sssec:datatype-mutual-recursion} *}
blanchet@53931
   254
blanchet@53942
   255
text {*
blanchet@54689
   256
\emph{Mutually recursive} types are introduced simultaneously and may refer to
blanchet@54689
   257
each other. The example below introduces a pair of types for even and odd
blanchet@54689
   258
natural numbers:
blanchet@53942
   259
*}
blanchet@53942
   260
blanchet@54760
   261
    datatype_new even_nat = Even_Zero | Even_Suc odd_nat
blanchet@54760
   262
    and odd_nat = Odd_Suc even_nat
blanchet@53942
   263
blanchet@53942
   264
text {*
blanchet@54628
   265
\noindent
blanchet@54628
   266
Arithmetic expressions are defined via terms, terms via factors, and factors via
blanchet@54628
   267
expressions:
blanchet@53942
   268
*}
blanchet@53942
   269
blanchet@53978
   270
    datatype_new ('a, 'b) exp =
blanchet@53978
   271
      Term "('a, 'b) trm" | Sum "('a, 'b) trm" "('a, 'b) exp"
blanchet@53942
   272
    and ('a, 'b) trm =
blanchet@53978
   273
      Factor "('a, 'b) fct" | Prod "('a, 'b) fct" "('a, 'b) trm"
blanchet@53978
   274
    and ('a, 'b) fct =
blanchet@53978
   275
      Const 'a | Var 'b | Expr "('a, 'b) exp"
blanchet@53942
   276
blanchet@53961
   277
blanchet@54758
   278
subsubsection {* Nested Recursion
blanchet@54758
   279
  \label{sssec:datatype-nested-recursion} *}
blanchet@53931
   280
blanchet@53942
   281
text {*
blanchet@54628
   282
\emph{Nested recursion} occurs when recursive occurrences of a type appear under
blanchet@54628
   283
a type constructor. The introduction showed some examples of trees with nesting
blanchet@54812
   284
through lists. A more complex example, that reuses our @{type option} type,
blanchet@54628
   285
follows:
blanchet@53942
   286
*}
blanchet@53942
   287
blanchet@53980
   288
    datatype_new 'a btree =
blanchet@54162
   289
      BNode 'a "'a btree option" "'a btree option"
blanchet@53942
   290
blanchet@53942
   291
text {*
blanchet@54628
   292
\noindent
blanchet@54628
   293
Not all nestings are admissible. For example, this command will fail:
blanchet@53942
   294
*}
blanchet@53942
   295
blanchet@55639
   296
    datatype_new 'a wrong = W1 | W2 (*<*)'a
blanchet@54679
   297
    typ (*>*)"'a wrong \<Rightarrow> 'a"
blanchet@53943
   298
blanchet@53943
   299
text {*
blanchet@54628
   300
\noindent
blanchet@54628
   301
The issue is that the function arrow @{text "\<Rightarrow>"} allows recursion
blanchet@54628
   302
only through its right-hand side. This issue is inherited by polymorphic
blanchet@54628
   303
datatypes defined in terms of~@{text "\<Rightarrow>"}:
blanchet@54628
   304
*}
blanchet@54628
   305
blanchet@54628
   306
    datatype_new ('a, 'b) fn = Fn "'a \<Rightarrow> 'b"
blanchet@55639
   307
    datatype_new 'a also_wrong = W1 | W2 (*<*)'a
blanchet@54679
   308
    typ (*>*)"('a also_wrong, 'a) fn"
blanchet@54628
   309
blanchet@54628
   310
text {*
blanchet@54628
   311
\noindent
blanchet@54758
   312
This is legal:
blanchet@54758
   313
*}
blanchet@54758
   314
blanchet@54758
   315
    datatype_new 'a ftree = FTLeaf 'a | FTNode "'a \<Rightarrow> 'a ftree"
blanchet@54758
   316
blanchet@54758
   317
text {*
blanchet@54758
   318
\noindent
blanchet@54628
   319
In general, type constructors @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"}
blanchet@54628
   320
allow recursion on a subset of their type arguments @{text 'a\<^sub>1}, \ldots,
blanchet@54628
   321
@{text 'a\<^sub>m}. These type arguments are called \emph{live}; the remaining
blanchet@54628
   322
type arguments are called \emph{dead}. In @{typ "'a \<Rightarrow> 'b"} and
blanchet@54628
   323
@{typ "('a, 'b) fn"}, the type variable @{typ 'a} is dead and @{typ 'b} is live.
blanchet@54689
   324
blanchet@54784
   325
Type constructors must be registered as BNFs to have live arguments. This is
blanchet@54784
   326
done automatically for datatypes and codatatypes introduced by the @{command
blanchet@54966
   327
datatype_new} and @{command codatatype} commands.
blanchet@54689
   328
Section~\ref{sec:registering-bounded-natural-functors} explains how to register
blanchet@54689
   329
arbitrary type constructors as BNFs.
blanchet@55639
   330
blanchet@55639
   331
Here is another example that fails:
blanchet@53943
   332
*}
blanchet@53943
   333
blanchet@55639
   334
    datatype_new 'a pow_list = PNil 'a (*<*)'a
blanchet@55639
   335
    datatype_new 'a pow_list' = PNil' 'a (*>*)| PCons "('a * 'a) pow_list"
blanchet@55639
   336
blanchet@55639
   337
text {*
blanchet@55639
   338
\noindent
blanchet@55639
   339
This one features a different flavor of nesting, where the recursive call in the
blanchet@55639
   340
type specification occurs around (rather than inside) another type constructor.
blanchet@55639
   341
*}
blanchet@55639
   342
blanchet@55639
   343
subsubsection {* Auxiliary Constants and Properties
blanchet@55639
   344
  \label{sssec:datatype-auxiliary-constants-and-properties} *}
blanchet@53942
   345
blanchet@53942
   346
text {*
blanchet@54628
   347
The @{command datatype_new} command introduces various constants in addition to
blanchet@54754
   348
the constructors. With each datatype are associated set functions, a map
blanchet@54754
   349
function, a relator, discriminators, and selectors, all of which can be given
blanchet@55639
   350
custom names. In the example below, the familiar names @{text null}, @{text hd},
blanchet@55639
   351
@{text tl}, @{text set}, @{text map}, and @{text list_all2}, override the
blanchet@55639
   352
default names @{text is_Nil}, @{text un_Cons1}, @{text un_Cons2},
blanchet@55864
   353
@{text set_list}, @{text map_list}, and @{text rel_list}:
blanchet@53942
   354
*}
blanchet@53931
   355
blanchet@53978
   356
(*<*)
blanchet@53978
   357
    no_translations
blanchet@53978
   358
      "[x, xs]" == "x # [xs]"
blanchet@53978
   359
      "[x]" == "x # []"
blanchet@53978
   360
blanchet@53978
   361
    no_notation
blanchet@53978
   362
      Nil ("[]") and
blanchet@53978
   363
      Cons (infixr "#" 65)
blanchet@53978
   364
blanchet@54680
   365
    hide_type list
blanchet@55867
   366
    hide_const Nil Cons hd tl set map list_all2
blanchet@54162
   367
blanchet@54886
   368
    context early begin
blanchet@53978
   369
(*>*)
blanchet@54162
   370
    datatype_new (set: 'a) list (map: map rel: list_all2) =
blanchet@53959
   371
      null: Nil (defaults tl: Nil)
blanchet@54162
   372
    | Cons (hd: 'a) (tl: "'a list")
blanchet@53959
   373
blanchet@53959
   374
text {*
blanchet@53959
   375
\noindent
blanchet@55639
   376
blanchet@55639
   377
\begin{tabular}{@ {}ll@ {}}
blanchet@55639
   378
Constructors: &
blanchet@55639
   379
  @{text "Nil \<Colon> 'a list"} \\
blanchet@55639
   380
&
blanchet@55639
   381
  @{text "Cons \<Colon> 'a \<Rightarrow> 'a list \<Rightarrow> 'a list"} \\
blanchet@55639
   382
Discriminator: &
blanchet@55639
   383
  @{text "null \<Colon> 'a list \<Rightarrow> bool"} \\
blanchet@55639
   384
Selectors: &
blanchet@55639
   385
  @{text "hd \<Colon> 'a list \<Rightarrow> 'a"} \\
blanchet@55639
   386
&
blanchet@55639
   387
  @{text "tl \<Colon> 'a list \<Rightarrow> 'a list"} \\
blanchet@55639
   388
Set function: &
blanchet@55639
   389
  @{text "set \<Colon> 'a list \<Rightarrow> 'a set"} \\
blanchet@55639
   390
Map function: &
blanchet@55639
   391
  @{text "map \<Colon> ('a \<Rightarrow> 'b) \<Rightarrow> 'a list \<Rightarrow> 'b list"} \\
blanchet@55639
   392
Relator: &
blanchet@55639
   393
  @{text "list_all2 \<Colon> ('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> bool"}
blanchet@55639
   394
\end{tabular}
blanchet@55639
   395
blanchet@55639
   396
The discriminator @{const null} and the selectors @{const hd} and @{const tl}
blanchet@55639
   397
are characterized as follows:
blanchet@53959
   398
%
blanchet@54162
   399
\[@{thm list.collapse(1)[of xs, no_vars]}
blanchet@54162
   400
  \qquad @{thm list.collapse(2)[of xs, no_vars]}\]
blanchet@53959
   401
%
blanchet@55639
   402
For two-constructor datatypes, a single discriminator constant is sufficient.
blanchet@55639
   403
The discriminator associated with @{const Cons} is simply
blanchet@54628
   404
@{term "\<lambda>xs. \<not> null xs"}.
blanchet@53959
   405
blanchet@54690
   406
The @{text defaults} clause following the @{const Nil} constructor specifies a
blanchet@54690
   407
default value for selectors associated with other constructors. Here, it is used
blanchet@54690
   408
to ensure that the tail of the empty list is itself (instead of being left
blanchet@54672
   409
unspecified).
blanchet@53959
   410
blanchet@54754
   411
Because @{const Nil} is nullary, it is also possible to use
blanchet@54628
   412
@{term "\<lambda>xs. xs = Nil"} as a discriminator. This is specified by
blanchet@54671
   413
entering ``@{text "="}'' instead of the identifier @{const null}. Although this
blanchet@54672
   414
may look appealing, the mixture of constructors and selectors in the
blanchet@54671
   415
characteristic theorems can lead Isabelle's automation to switch between the
blanchet@54671
   416
constructor and the destructor view in surprising ways.
blanchet@53959
   417
blanchet@55000
   418
The usual mixfix syntax annotations are available for both types and
blanchet@55000
   419
constructors. For example:
blanchet@53959
   420
*}
blanchet@53959
   421
blanchet@54162
   422
(*<*)
blanchet@54162
   423
    end
blanchet@54162
   424
(*>*)
blanchet@54689
   425
    datatype_new ('a, 'b) prod (infixr "*" 20) = Pair 'a 'b
blanchet@54689
   426
blanchet@54689
   427
text {* \blankline *}
blanchet@53959
   428
blanchet@53978
   429
    datatype_new (set: 'a) list (map: map rel: list_all2) =
blanchet@53959
   430
      null: Nil ("[]")
blanchet@53978
   431
    | Cons (hd: 'a) (tl: "'a list") (infixr "#" 65)
blanchet@53978
   432
blanchet@53978
   433
text {*
blanchet@54672
   434
\noindent
blanchet@55000
   435
Incidentally, this is how the traditional syntax can be set up:
blanchet@53978
   436
*}
blanchet@53978
   437
blanchet@53978
   438
    syntax "_list" :: "args \<Rightarrow> 'a list" ("[(_)]")
blanchet@53978
   439
blanchet@54689
   440
text {* \blankline *}
blanchet@54689
   441
blanchet@53978
   442
    translations
blanchet@53978
   443
      "[x, xs]" == "x # [xs]"
blanchet@53978
   444
      "[x]" == "x # []"
blanchet@53959
   445
blanchet@53961
   446
blanchet@54754
   447
subsection {* Command Syntax
blanchet@54754
   448
  \label{ssec:datatype-command-syntax} *}
blanchet@54754
   449
blanchet@54754
   450
blanchet@54758
   451
subsubsection {* \keyw{datatype\_new}
blanchet@54758
   452
  \label{sssec:datatype-new} *}
blanchet@53931
   453
blanchet@53959
   454
text {*
blanchet@54966
   455
\begin{matharray}{rcl}
blanchet@54966
   456
  @{command_def "datatype_new"} & : & @{text "local_theory \<rightarrow> local_theory"}
blanchet@54966
   457
\end{matharray}
blanchet@53959
   458
blanchet@53961
   459
@{rail "
blanchet@54966
   460
  @@{command datatype_new} target? @{syntax dt_options}? \\
blanchet@53961
   461
    (@{syntax dt_name} '=' (@{syntax ctor} + '|') + @'and')
blanchet@53965
   462
  ;
blanchet@54760
   463
  @{syntax_def dt_options}: '(' (('no_discs_sels' | 'rep_compat') + ',') ')'
blanchet@53961
   464
"}
blanchet@53959
   465
blanchet@55000
   466
The syntactic entity \synt{target} can be used to specify a local
blanchet@54671
   467
context---e.g., @{text "(in linorder)"}. It is documented in the Isar reference
blanchet@54671
   468
manual \cite{isabelle-isar-ref}.
blanchet@54671
   469
%
blanchet@54671
   470
The optional target is optionally followed by datatype-specific options:
blanchet@53959
   471
blanchet@53961
   472
\begin{itemize}
blanchet@53961
   473
\setlength{\itemsep}{0pt}
blanchet@53959
   474
blanchet@53961
   475
\item
blanchet@54760
   476
The @{text "no_discs_sels"} option indicates that no discriminators or selectors
blanchet@54680
   477
should be generated.
blanchet@53959
   478
blanchet@53961
   479
\item
blanchet@54781
   480
The @{text "rep_compat"} option indicates that the generated names should
blanchet@54781
   481
contain optional (and normally not displayed) ``@{text "new."}'' components to
blanchet@54781
   482
prevent clashes with a later call to \keyw{rep\_datatype}. See
blanchet@53961
   483
Section~\ref{ssec:datatype-compatibility-issues} for details.
blanchet@53961
   484
\end{itemize}
blanchet@53959
   485
blanchet@53964
   486
The left-hand sides of the datatype equations specify the name of the type to
blanchet@54671
   487
define, its type parameters, and additional information:
blanchet@53959
   488
blanchet@53961
   489
@{rail "
blanchet@54671
   490
  @{syntax_def dt_name}: @{syntax tyargs}? name @{syntax map_rel}? mixfix?
blanchet@53961
   491
  ;
blanchet@54671
   492
  @{syntax_def tyargs}: typefree | '(' ((name ':')? typefree + ',') ')'
blanchet@53961
   493
  ;
blanchet@54671
   494
  @{syntax_def map_rel}: '(' ((('map' | 'rel') ':' name) +) ')'
blanchet@53961
   495
"}
blanchet@53961
   496
blanchet@53964
   497
\noindent
blanchet@55000
   498
The syntactic entity \synt{name} denotes an identifier, \synt{typefree}
blanchet@54671
   499
denotes fixed type variable (@{typ 'a}, @{typ 'b}, \ldots), and \synt{mixfix}
blanchet@54671
   500
denotes the usual parenthesized mixfix notation. They are documented in the Isar
blanchet@54671
   501
reference manual \cite{isabelle-isar-ref}.
blanchet@53961
   502
blanchet@53964
   503
The optional names preceding the type variables allow to override the default
blanchet@55864
   504
names of the set functions (@{text set1_t}, \ldots, @{text setM_t}).
blanchet@54784
   505
Inside a mutually recursive specification, all defined datatypes must
blanchet@54784
   506
mention exactly the same type variables in the same order.
blanchet@53959
   507
blanchet@53961
   508
@{rail "
blanchet@54671
   509
  @{syntax_def ctor}: (name ':')? name (@{syntax ctor_arg} * ) \\
blanchet@54671
   510
    @{syntax dt_sel_defaults}? mixfix?
blanchet@53961
   511
"}
blanchet@53961
   512
blanchet@54672
   513
\medskip
blanchet@54672
   514
blanchet@53964
   515
\noindent
blanchet@55000
   516
The main constituents of a constructor specification are the name of the
blanchet@53964
   517
constructor and the list of its argument types. An optional discriminator name
blanchet@54691
   518
can be supplied at the front to override the default name
blanchet@54691
   519
(@{text t.is_C\<^sub>j}).
blanchet@53959
   520
blanchet@53961
   521
@{rail "
blanchet@54671
   522
  @{syntax_def ctor_arg}: type | '(' name ':' type ')'
blanchet@53964
   523
"}
blanchet@53964
   524
blanchet@54672
   525
\medskip
blanchet@54672
   526
blanchet@53964
   527
\noindent
blanchet@53964
   528
In addition to the type of a constructor argument, it is possible to specify a
blanchet@53964
   529
name for the corresponding selector to override the default name
blanchet@54691
   530
(@{text un_C\<^sub>ji}). The same selector names can be reused for several
blanchet@54691
   531
constructors as long as they share the same type.
blanchet@53964
   532
blanchet@53964
   533
@{rail "
blanchet@54758
   534
  @{syntax_def dt_sel_defaults}: '(' 'defaults' (name ':' term +) ')'
blanchet@53961
   535
"}
blanchet@53964
   536
blanchet@53964
   537
\noindent
blanchet@53964
   538
Given a constructor
blanchet@53964
   539
@{text "C \<Colon> \<sigma>\<^sub>1 \<Rightarrow> \<dots> \<Rightarrow> \<sigma>\<^sub>p \<Rightarrow> \<sigma>"},
blanchet@53964
   540
default values can be specified for any selector
blanchet@53964
   541
@{text "un_D \<Colon> \<sigma> \<Rightarrow> \<tau>"}
blanchet@54672
   542
associated with other constructors. The specified default value must be of type
blanchet@53965
   543
@{text "\<sigma>\<^sub>1 \<Rightarrow> \<dots> \<Rightarrow> \<sigma>\<^sub>p \<Rightarrow> \<tau>"}
blanchet@55000
   544
(i.e., it may depend on @{text C}'s arguments).
blanchet@53959
   545
*}
blanchet@53959
   546
blanchet@54754
   547
blanchet@54758
   548
subsubsection {* \keyw{datatype\_new\_compat}
blanchet@54758
   549
  \label{sssec:datatype-new-compat} *}
blanchet@54754
   550
blanchet@54754
   551
text {*
blanchet@54966
   552
\begin{matharray}{rcl}
blanchet@54966
   553
  @{command_def "datatype_new_compat"} & : & @{text "local_theory \<rightarrow> local_theory"}
blanchet@54966
   554
\end{matharray}
blanchet@54966
   555
blanchet@54966
   556
@{rail "
blanchet@54966
   557
  @@{command datatype_new_compat} names
blanchet@54966
   558
"}
blanchet@54966
   559
blanchet@54966
   560
\noindent
blanchet@54758
   561
The old datatype package provides some functionality that is not yet replicated
blanchet@54758
   562
in the new package:
blanchet@54758
   563
blanchet@54758
   564
\begin{itemize}
blanchet@54886
   565
\setlength{\itemsep}{0pt}
blanchet@54886
   566
blanchet@54758
   567
\item It is integrated with \keyw{fun} and \keyw{function}
blanchet@54758
   568
\cite{isabelle-function}, Nitpick \cite{isabelle-nitpick}, Quickcheck,
blanchet@54758
   569
and other packages.
blanchet@54758
   570
blanchet@54758
   571
\item It is extended by various add-ons, notably to produce instances of the
blanchet@54758
   572
@{const size} function.
blanchet@54758
   573
\end{itemize}
blanchet@54758
   574
blanchet@54758
   575
\noindent
blanchet@55000
   576
New-style datatypes can in most cases be registered as old-style datatypes using
blanchet@54966
   577
@{command datatype_new_compat}. The \textit{names} argument is a space-separated
blanchet@54966
   578
list of type names that are mutually recursive. For example:
blanchet@54758
   579
*}
blanchet@54758
   580
blanchet@54760
   581
    datatype_new_compat even_nat odd_nat
blanchet@54758
   582
blanchet@54758
   583
text {* \blankline *}
blanchet@54758
   584
blanchet@54760
   585
    thm even_nat_odd_nat.size
blanchet@54758
   586
blanchet@54758
   587
text {* \blankline *}
blanchet@54758
   588
blanchet@54760
   589
    ML {* Datatype_Data.get_info @{theory} @{type_name even_nat} *}
blanchet@54758
   590
blanchet@54758
   591
text {*
blanchet@54885
   592
A few remarks concern nested recursive datatypes only:
blanchet@54885
   593
blanchet@54885
   594
\begin{itemize}
blanchet@54886
   595
\setlength{\itemsep}{0pt}
blanchet@54886
   596
blanchet@54885
   597
\item The old-style, nested-as-mutual induction rule, iterator theorems, and
blanchet@54885
   598
recursor theorems are generated under their usual names but with ``@{text
blanchet@54885
   599
"compat_"}'' prefixed (e.g., @{text compat_tree.induct}).
blanchet@54885
   600
blanchet@54885
   601
\item All types through which recursion takes place must be new-style datatypes
blanchet@54885
   602
or the function type. In principle, it should be possible to support old-style
blanchet@54885
   603
datatypes as well, but the command does not support this yet (and there is
blanchet@54885
   604
currently no way to register old-style datatypes as new-style datatypes).
blanchet@55636
   605
blanchet@55636
   606
\item The recursor produced for types that recurse through functions has a
blanchet@55636
   607
different signature than with the old package. This makes it impossible to use
blanchet@55636
   608
the old \keyw{primrec} command.
blanchet@54885
   609
\end{itemize}
blanchet@54885
   610
blanchet@54885
   611
An alternative to @{command datatype_new_compat} is to use the old package's
blanchet@54885
   612
\keyw{rep\_datatype} command. The associated proof obligations must then be
blanchet@54885
   613
discharged manually.
blanchet@54754
   614
*}
blanchet@54754
   615
blanchet@54754
   616
blanchet@54754
   617
subsection {* Generated Constants
blanchet@54754
   618
  \label{ssec:datatype-generated-constants} *}
blanchet@54754
   619
blanchet@54754
   620
text {*
blanchet@54760
   621
Given a datatype @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"}
blanchet@54754
   622
with $m > 0$ live type variables and $n$ constructors
blanchet@54754
   623
@{text "t.C\<^sub>1"}, \ldots, @{text "t.C\<^sub>n"}, the
blanchet@54754
   624
following auxiliary constants are introduced:
blanchet@54754
   625
blanchet@54754
   626
\begin{itemize}
blanchet@54754
   627
\setlength{\itemsep}{0pt}
blanchet@54754
   628
blanchet@55867
   629
\item \relax{Case combinator}: @{text t.case_t} (rendered using the familiar
blanchet@54754
   630
@{text case}--@{text of} syntax)
blanchet@54754
   631
blanchet@54754
   632
\item \relax{Discriminators}: @{text "t.is_C\<^sub>1"}, \ldots,
blanchet@54754
   633
@{text "t.is_C\<^sub>n"}
blanchet@54754
   634
blanchet@54754
   635
\item \relax{Selectors}:
blanchet@54754
   636
@{text t.un_C\<^sub>11}$, \ldots, @{text t.un_C\<^sub>1k\<^sub>1}, \\
blanchet@54754
   637
\phantom{\relax{Selectors:}} \quad\vdots \\
blanchet@54754
   638
\phantom{\relax{Selectors:}} @{text t.un_C\<^sub>n1}$, \ldots, @{text t.un_C\<^sub>nk\<^sub>n}.
blanchet@54754
   639
blanchet@54754
   640
\item \relax{Set functions} (or \relax{natural transformations}):
blanchet@55864
   641
@{text set1_t}, \ldots, @{text t.setm_t}
blanchet@55864
   642
blanchet@55864
   643
\item \relax{Map function} (or \relax{functorial action}): @{text t.map_t}
blanchet@55864
   644
blanchet@55864
   645
\item \relax{Relator}: @{text t.rel_t}
blanchet@55864
   646
blanchet@55867
   647
\item \relax{Iterator}: @{text t.fold_t}
blanchet@55867
   648
blanchet@55867
   649
\item \relax{Recursor}: @{text t.rec_t}
blanchet@54754
   650
blanchet@54754
   651
\end{itemize}
blanchet@54754
   652
blanchet@54754
   653
\noindent
blanchet@54754
   654
The case combinator, discriminators, and selectors are collectively called
blanchet@54754
   655
\emph{destructors}. The prefix ``@{text "t."}'' is an optional component of the
blanchet@55864
   656
names and is normally hidden.
blanchet@54754
   657
*}
blanchet@54754
   658
blanchet@54754
   659
blanchet@53977
   660
subsection {* Generated Theorems
blanchet@53977
   661
  \label{ssec:datatype-generated-theorems} *}
blanchet@53965
   662
blanchet@53965
   663
text {*
blanchet@54681
   664
The characteristic theorems generated by @{command datatype_new} are grouped in
blanchet@54760
   665
three broad categories:
blanchet@54672
   666
blanchet@54680
   667
\begin{itemize}
blanchet@54886
   668
\setlength{\itemsep}{0pt}
blanchet@54886
   669
blanchet@54680
   670
\item The \emph{free constructor theorems} are properties about the constructors
blanchet@54680
   671
and destructors that can be derived for any freely generated type. Internally,
blanchet@54679
   672
the derivation is performed by @{command wrap_free_constructors}.
blanchet@54672
   673
blanchet@54689
   674
\item The \emph{functorial theorems} are properties of datatypes related to
blanchet@54689
   675
their BNF nature.
blanchet@54689
   676
blanchet@54689
   677
\item The \emph{inductive theorems} are properties of datatypes related to
blanchet@54681
   678
their inductive nature.
blanchet@54689
   679
blanchet@54680
   680
\end{itemize}
blanchet@54672
   681
blanchet@54672
   682
\noindent
blanchet@54679
   683
The full list of named theorems can be obtained as usual by entering the
blanchet@54680
   684
command \keyw{print\_theorems} immediately after the datatype definition.
blanchet@54679
   685
This list normally excludes low-level theorems that reveal internal
blanchet@54689
   686
constructions. To make these accessible, add the line
blanchet@54679
   687
*}
blanchet@54672
   688
blanchet@54679
   689
    declare [[bnf_note_all]]
blanchet@54679
   690
(*<*)
blanchet@54679
   691
    declare [[bnf_note_all = false]]
blanchet@54679
   692
(*>*)
blanchet@54672
   693
blanchet@54689
   694
text {*
blanchet@54689
   695
\noindent
blanchet@54689
   696
to the top of the theory file.
blanchet@54689
   697
*}
blanchet@54672
   698
blanchet@54758
   699
subsubsection {* Free Constructor Theorems
blanchet@54758
   700
  \label{sssec:free-constructor-theorems} *}
blanchet@54672
   701
blanchet@54680
   702
(*<*)
blanchet@54974
   703
    consts nonnull :: 'a
blanchet@54680
   704
(*>*)
blanchet@54680
   705
blanchet@54672
   706
text {*
blanchet@55000
   707
The first subgroup of properties is concerned with the constructors.
blanchet@54680
   708
They are listed below for @{typ "'a list"}:
blanchet@54680
   709
blanchet@54689
   710
\begin{indentblock}
blanchet@54680
   711
\begin{description}
blanchet@54681
   712
blanchet@54779
   713
\item[@{text "t."}\hthm{inject} @{text "[iff, induct_simp]"}\rm:] ~ \\
blanchet@54681
   714
@{thm list.inject[no_vars]}
blanchet@54681
   715
blanchet@54779
   716
\item[@{text "t."}\hthm{distinct} @{text "[simp, induct_simp]"}\rm:] ~ \\
blanchet@54680
   717
@{thm list.distinct(1)[no_vars]} \\
blanchet@54680
   718
@{thm list.distinct(2)[no_vars]}
blanchet@54680
   719
blanchet@54779
   720
\item[@{text "t."}\hthm{exhaust} @{text "[cases t, case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
blanchet@54680
   721
@{thm list.exhaust[no_vars]}
blanchet@54680
   722
blanchet@54779
   723
\item[@{text "t."}\hthm{nchotomy}\rm:] ~ \\
blanchet@54680
   724
@{thm list.nchotomy[no_vars]}
blanchet@54680
   725
blanchet@54680
   726
\end{description}
blanchet@54689
   727
\end{indentblock}
blanchet@54680
   728
blanchet@54680
   729
\noindent
blanchet@54758
   730
In addition, these nameless theorems are registered as safe elimination rules:
blanchet@54758
   731
blanchet@54758
   732
\begin{indentblock}
blanchet@54758
   733
\begin{description}
blanchet@54758
   734
blanchet@55759
   735
\item[@{text "t."}\hthm{distinct {\upshape[}THEN notE}@{text ", elim!"}\hthm{\upshape]}\rm:] ~ \\
blanchet@54758
   736
@{thm list.distinct(1)[THEN notE, elim!, no_vars]} \\
blanchet@54758
   737
@{thm list.distinct(2)[THEN notE, elim!, no_vars]}
blanchet@54758
   738
blanchet@54758
   739
\end{description}
blanchet@54758
   740
\end{indentblock}
blanchet@54758
   741
blanchet@54758
   742
\noindent
blanchet@54680
   743
The next subgroup is concerned with the case combinator:
blanchet@54680
   744
blanchet@54689
   745
\begin{indentblock}
blanchet@54680
   746
\begin{description}
blanchet@54681
   747
blanchet@54935
   748
\item[@{text "t."}\hthm{case} @{text "[simp, code]"}\rm:] ~ \\
blanchet@54680
   749
@{thm list.case(1)[no_vars]} \\
blanchet@54680
   750
@{thm list.case(2)[no_vars]}
blanchet@54680
   751
blanchet@54779
   752
\item[@{text "t."}\hthm{case\_cong}\rm:] ~ \\
blanchet@54680
   753
@{thm list.case_cong[no_vars]}
blanchet@54680
   754
blanchet@54779
   755
\item[@{text "t."}\hthm{weak\_case\_cong} @{text "[cong]"}\rm:] ~ \\
blanchet@54680
   756
@{thm list.weak_case_cong[no_vars]}
blanchet@54680
   757
blanchet@54779
   758
\item[@{text "t."}\hthm{split}\rm:] ~ \\
blanchet@54680
   759
@{thm list.split[no_vars]}
blanchet@54680
   760
blanchet@54779
   761
\item[@{text "t."}\hthm{split\_asm}\rm:] ~ \\
blanchet@54680
   762
@{thm list.split_asm[no_vars]}
blanchet@54680
   763
blanchet@54681
   764
\item[@{text "t."}\hthm{splits} = @{text "split split_asm"}]
blanchet@54680
   765
blanchet@54680
   766
\end{description}
blanchet@54689
   767
\end{indentblock}
blanchet@54680
   768
blanchet@54680
   769
\noindent
blanchet@54680
   770
The third and last subgroup revolves around discriminators and selectors:
blanchet@54680
   771
blanchet@54689
   772
\begin{indentblock}
blanchet@54680
   773
\begin{description}
blanchet@54681
   774
blanchet@54831
   775
\item[@{text "t."}\hthm{disc} @{text "[simp]"}\rm:] ~ \\
blanchet@54831
   776
@{thm list.disc(1)[no_vars]} \\
blanchet@54831
   777
@{thm list.disc(2)[no_vars]}
blanchet@54831
   778
blanchet@54840
   779
\item[@{text "t."}\hthm{discI}\rm:] ~ \\
blanchet@54840
   780
@{thm list.discI(1)[no_vars]} \\
blanchet@54840
   781
@{thm list.discI(2)[no_vars]}
blanchet@54840
   782
blanchet@54942
   783
\item[@{text "t."}\hthm{sel} @{text "[simp, code]"}\rm:] ~ \\
blanchet@54831
   784
@{thm list.sel(1)[no_vars]} \\
blanchet@54831
   785
@{thm list.sel(2)[no_vars]}
blanchet@54680
   786
blanchet@54779
   787
\item[@{text "t."}\hthm{collapse} @{text "[simp]"}\rm:] ~ \\
blanchet@54680
   788
@{thm list.collapse(1)[no_vars]} \\
blanchet@54680
   789
@{thm list.collapse(2)[no_vars]}
blanchet@54680
   790
blanchet@54974
   791
\item[@{text "t."}\hthm{disc\_exclude} @{text "[dest]"}\rm:] ~ \\
blanchet@54680
   792
These properties are missing for @{typ "'a list"} because there is only one
blanchet@54680
   793
proper discriminator. Had the datatype been introduced with a second
blanchet@54974
   794
discriminator called @{const nonnull}, they would have read thusly: \\[\jot]
blanchet@54974
   795
@{prop "null list \<Longrightarrow> \<not> nonnull list"} \\
blanchet@54974
   796
@{prop "nonnull list \<Longrightarrow> \<not> null list"}
blanchet@54680
   797
blanchet@54779
   798
\item[@{text "t."}\hthm{disc\_exhaust} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
blanchet@54680
   799
@{thm list.disc_exhaust[no_vars]}
blanchet@54680
   800
blanchet@55053
   801
\item[@{text "t."}\hthm{sel\_exhaust} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
blanchet@55053
   802
@{thm list.sel_exhaust[no_vars]}
blanchet@55053
   803
blanchet@54779
   804
\item[@{text "t."}\hthm{expand}\rm:] ~ \\
blanchet@54680
   805
@{thm list.expand[no_vars]}
blanchet@54680
   806
blanchet@55054
   807
\item[@{text "t."}\hthm{sel\_split}\rm:] ~ \\
blanchet@55054
   808
@{thm list.sel_split[no_vars]}
blanchet@55054
   809
blanchet@55054
   810
\item[@{text "t."}\hthm{sel\_split\_asm}\rm:] ~ \\
blanchet@55054
   811
@{thm list.sel_split_asm[no_vars]}
blanchet@55054
   812
blanchet@55864
   813
\item[@{text "t."}\hthm{case\_eq\_if}\rm:] ~ \\
blanchet@55864
   814
@{thm list.case_eq_if[no_vars]}
blanchet@54680
   815
blanchet@54680
   816
\end{description}
blanchet@54689
   817
\end{indentblock}
blanchet@55604
   818
blanchet@55604
   819
\noindent
blanchet@55604
   820
In addition, equational versions of @{text t.disc} are registered with the @{text "[code]"}
blanchet@55604
   821
attribute.
blanchet@54689
   822
*}
blanchet@54689
   823
blanchet@54689
   824
blanchet@54758
   825
subsubsection {* Functorial Theorems
blanchet@54758
   826
  \label{sssec:functorial-theorems} *}
blanchet@54689
   827
blanchet@54689
   828
text {*
blanchet@54760
   829
The BNF-related theorem are as follows:
blanchet@54689
   830
blanchet@54689
   831
\begin{indentblock}
blanchet@54689
   832
\begin{description}
blanchet@54689
   833
blanchet@54935
   834
\item[@{text "t."}\hthm{set} @{text "[simp, code]"}\rm:] ~ \\
blanchet@54831
   835
@{thm list.set(1)[no_vars]} \\
blanchet@54831
   836
@{thm list.set(2)[no_vars]}
blanchet@54689
   837
blanchet@54935
   838
\item[@{text "t."}\hthm{map} @{text "[simp, code]"}\rm:] ~ \\
blanchet@54689
   839
@{thm list.map(1)[no_vars]} \\
blanchet@54689
   840
@{thm list.map(2)[no_vars]}
blanchet@54689
   841
blanchet@55598
   842
\item[@{text "t."}\hthm{rel\_inject} @{text "[simp]"}\rm:] ~ \\
blanchet@54689
   843
@{thm list.rel_inject(1)[no_vars]} \\
blanchet@54689
   844
@{thm list.rel_inject(2)[no_vars]}
blanchet@54689
   845
blanchet@55598
   846
\item[@{text "t."}\hthm{rel\_distinct} @{text "[simp]"}\rm:] ~ \\
blanchet@54689
   847
@{thm list.rel_distinct(1)[no_vars]} \\
blanchet@54689
   848
@{thm list.rel_distinct(2)[no_vars]}
blanchet@54689
   849
blanchet@54689
   850
\end{description}
blanchet@54689
   851
\end{indentblock}
blanchet@55598
   852
blanchet@55598
   853
\noindent
blanchet@55598
   854
In addition, equational versions of @{text t.rel_inject} and @{text
blanchet@55598
   855
rel_distinct} are registered with the @{text "[code]"} attribute.
blanchet@54672
   856
*}
blanchet@54672
   857
blanchet@54672
   858
blanchet@54758
   859
subsubsection {* Inductive Theorems
blanchet@54758
   860
  \label{sssec:inductive-theorems} *}
blanchet@54672
   861
blanchet@54672
   862
text {*
blanchet@54760
   863
The inductive theorems are as follows:
blanchet@53965
   864
blanchet@54689
   865
\begin{indentblock}
blanchet@54681
   866
\begin{description}
blanchet@54672
   867
blanchet@54779
   868
\item[@{text "t."}\hthm{induct} @{text "[induct t, case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
blanchet@54681
   869
@{thm list.induct[no_vars]}
blanchet@54672
   870
blanchet@54779
   871
\item[@{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
blanchet@54681
   872
Given $m > 1$ mutually recursive datatypes, this induction rule can be used to
blanchet@54681
   873
prove $m$ properties simultaneously.
blanchet@54681
   874
blanchet@54935
   875
\item[@{text "t."}\hthm{fold} @{text "[simp, code]"}\rm:] ~ \\
blanchet@54681
   876
@{thm list.fold(1)[no_vars]} \\
blanchet@54681
   877
@{thm list.fold(2)[no_vars]}
blanchet@54681
   878
blanchet@54935
   879
\item[@{text "t."}\hthm{rec} @{text "[simp, code]"}\rm:] ~ \\
blanchet@54681
   880
@{thm list.rec(1)[no_vars]} \\
blanchet@54681
   881
@{thm list.rec(2)[no_vars]}
blanchet@54681
   882
blanchet@54681
   883
\end{description}
blanchet@54689
   884
\end{indentblock}
blanchet@54681
   885
blanchet@54681
   886
\noindent
blanchet@54681
   887
For convenience, @{command datatype_new} also provides the following collection:
blanchet@54681
   888
blanchet@54689
   889
\begin{indentblock}
blanchet@54681
   890
\begin{description}
blanchet@54681
   891
blanchet@54681
   892
\item[@{text "t."}\hthm{simps} = @{text t.inject} @{text t.distinct} @{text t.case} @{text t.rec} @{text t.fold} @{text t.map} @{text t.rel_inject}] ~ \\
blanchet@54831
   893
@{text t.rel_distinct} @{text t.set}
blanchet@54681
   894
blanchet@54681
   895
\end{description}
blanchet@54689
   896
\end{indentblock}
blanchet@53965
   897
*}
blanchet@53965
   898
blanchet@53931
   899
blanchet@53964
   900
subsection {* Compatibility Issues
blanchet@53961
   901
  \label{ssec:datatype-compatibility-issues} *}
blanchet@53931
   902
blanchet@53965
   903
text {*
blanchet@55134
   904
The command @{command datatype_new} has been designed to be highly compatible
blanchet@55134
   905
with the old \keyw{datatype}, to ease migration. There are nonetheless a few
blanchet@54784
   906
incompatibilities that may arise when porting to the new package:
blanchet@53965
   907
blanchet@54784
   908
\begin{itemize}
blanchet@54886
   909
\setlength{\itemsep}{0pt}
blanchet@54886
   910
blanchet@54784
   911
\item \emph{The Standard ML interfaces are different.} Tools and extensions
blanchet@54784
   912
written to call the old ML interfaces will need to be adapted to the new
blanchet@54784
   913
interfaces. Little has been done so far in this direction. Whenever possible, it
blanchet@54784
   914
is recommended to use @{command datatype_new_compat} or \keyw{rep\_datatype}
blanchet@54784
   915
to register new-style datatypes as old-style datatypes.
blanchet@54784
   916
blanchet@55910
   917
\item \emph{The constants @{text t_case} and @{text t_rec} are now called
blanchet@55910
   918
@{text case_t} and @{text rec_t}.}
blanchet@55910
   919
blanchet@55910
   920
\item \emph{The recursor @{text rec_t} has a different signature for nested
blanchet@55637
   921
recursive datatypes.} In the old package, nested recursion through non-functions
blanchet@55637
   922
was internally reduced to mutual recursion. This reduction was visible in the
blanchet@55637
   923
type of the recursor, used by \keyw{primrec}. Recursion through functions was
blanchet@55637
   924
handled specially. In the new package, nested recursion (for functions and
blanchet@55637
   925
non-functions) is handled in a more modular fashion. The old-style recursor can
blanchet@55637
   926
be generated on demand using @{command primrec_new}, as explained in
blanchet@54784
   927
Section~\ref{sssec:primrec-nested-as-mutual-recursion}, if the recursion is via
blanchet@54784
   928
new-style datatypes.
blanchet@54784
   929
blanchet@55739
   930
\item \emph{Accordingly, the induction rule is different for nested recursive
blanchet@55739
   931
datatypes.} Again, the old-style induction rule can be generated on demand using
blanchet@55739
   932
@{command primrec_new}, as explained in
blanchet@54784
   933
Section~\ref{sssec:primrec-nested-as-mutual-recursion}, if the recursion is via
blanchet@54784
   934
new-style datatypes.
blanchet@54784
   935
blanchet@55000
   936
\item \emph{The internal constructions are completely different.} Proof texts
blanchet@54784
   937
that unfold the definition of constants introduced by \keyw{datatype} will be
blanchet@54784
   938
difficult to port.
blanchet@54784
   939
blanchet@54784
   940
\item \emph{A few theorems have different names.}
blanchet@55134
   941
The properties @{text t.cases} and @{text t.recs} have been renamed
blanchet@54784
   942
@{text t.case} and @{text t.rec}. For non-mutually recursive datatypes,
blanchet@54784
   943
@{text t.inducts} is available as @{text t.induct}.
blanchet@54784
   944
For $m > 1$ mutually recursive datatypes,
blanchet@55134
   945
@{text "t\<^sub>1_\<dots>_t\<^sub>m.inducts(i)"} has been renamed
blanchet@54784
   946
@{text "t\<^sub>i.induct"}.
blanchet@54784
   947
blanchet@54784
   948
\item \emph{The @{text t.simps} collection has been extended.}
blanchet@54784
   949
Previously available theorems are available at the same index.
blanchet@54784
   950
blanchet@54784
   951
\item \emph{Variables in generated properties have different names.} This is
blanchet@54784
   952
rarely an issue, except in proof texts that refer to variable names in the
blanchet@54784
   953
@{text "[where \<dots>]"} attribute. The solution is to use the more robust
blanchet@54784
   954
@{text "[of \<dots>]"} syntax.
blanchet@54784
   955
\end{itemize}
blanchet@54784
   956
blanchet@54784
   957
In the other direction, there is currently no way to register old-style
blanchet@54784
   958
datatypes as new-style datatypes. If the goal is to define new-style datatypes
blanchet@54784
   959
with nested recursion through old-style datatypes, the old-style
blanchet@54784
   960
datatypes can be registered as a BNF
blanchet@54784
   961
(Section~\ref{sec:registering-bounded-natural-functors}). If the goal is
blanchet@54784
   962
to derive discriminators and selectors, this can be achieved using @{command
blanchet@54784
   963
wrap_free_constructors}
blanchet@54784
   964
(Section~\ref{sec:deriving-destructors-and-theorems-for-free-constructors}).
blanchet@53965
   965
*}
blanchet@53965
   966
blanchet@53929
   967
blanchet@53964
   968
section {* Defining Recursive Functions
blanchet@53942
   969
  \label{sec:defining-recursive-functions} *}
blanchet@53942
   970
blanchet@53942
   971
text {*
blanchet@55635
   972
Recursive functions over datatypes can be specified using the @{command
blanchet@55635
   973
primrec_new} command, which supports primitive recursion, or using the more
blanchet@55635
   974
general \keyw{fun} and \keyw{function} commands. Here, the focus is on @{command
blanchet@54781
   975
primrec_new}; the other two commands are described in a separate tutorial
blanchet@54783
   976
\cite{isabelle-function}.
blanchet@53965
   977
blanchet@54758
   978
%%% TODO: partial_function
blanchet@53942
   979
*}
blanchet@53929
   980
blanchet@53942
   981
blanchet@54754
   982
subsection {* Introductory Examples
blanchet@54754
   983
  \label{ssec:primrec-introductory-examples} *}
blanchet@53965
   984
blanchet@54783
   985
text {*
blanchet@54783
   986
Primitive recursion is illustrated through concrete examples based on the
blanchet@54783
   987
datatypes defined in Section~\ref{ssec:datatype-introductory-examples}. More
blanchet@54783
   988
examples can be found in the directory \verb|~~/src/HOL/BNF/Examples|.
blanchet@54783
   989
*}
blanchet@54783
   990
blanchet@54758
   991
blanchet@54758
   992
subsubsection {* Nonrecursive Types
blanchet@54758
   993
  \label{sssec:primrec-nonrecursive-types} *}
blanchet@53965
   994
blanchet@53978
   995
text {*
blanchet@54758
   996
Primitive recursion removes one layer of constructors on the left-hand side in
blanchet@54758
   997
each equation. For example:
blanchet@53978
   998
*}
blanchet@53978
   999
blanchet@53978
  1000
    primrec_new bool_of_trool :: "trool \<Rightarrow> bool" where
blanchet@54758
  1001
      "bool_of_trool Faalse \<longleftrightarrow> False" |
blanchet@54758
  1002
      "bool_of_trool Truue \<longleftrightarrow> True"
blanchet@53978
  1003
blanchet@54758
  1004
text {* \blankline *}
blanchet@53978
  1005
blanchet@54162
  1006
    primrec_new the_list :: "'a option \<Rightarrow> 'a list" where
blanchet@54162
  1007
      "the_list None = []" |
blanchet@54162
  1008
      "the_list (Some a) = [a]"
blanchet@53978
  1009
blanchet@54758
  1010
text {* \blankline *}
blanchet@54758
  1011
blanchet@54162
  1012
    primrec_new the_default :: "'a \<Rightarrow> 'a option \<Rightarrow> 'a" where
blanchet@54162
  1013
      "the_default d None = d" |
blanchet@54162
  1014
      "the_default _ (Some a) = a"
blanchet@53980
  1015
blanchet@54758
  1016
text {* \blankline *}
blanchet@54758
  1017
blanchet@53978
  1018
    primrec_new mirrror :: "('a, 'b, 'c) triple \<Rightarrow> ('c, 'b, 'a) triple" where
blanchet@53978
  1019
      "mirrror (Triple a b c) = Triple c b a"
blanchet@53978
  1020
blanchet@54758
  1021
text {*
blanchet@54758
  1022
\noindent
blanchet@54758
  1023
The equations can be specified in any order, and it is acceptable to leave out
blanchet@54758
  1024
some cases, which are then unspecified. Pattern matching on the left-hand side
blanchet@54758
  1025
is restricted to a single datatype, which must correspond to the same argument
blanchet@54758
  1026
in all equations.
blanchet@54758
  1027
*}
blanchet@53965
  1028
blanchet@54758
  1029
blanchet@54758
  1030
subsubsection {* Simple Recursion
blanchet@54758
  1031
  \label{sssec:primrec-simple-recursion} *}
blanchet@53965
  1032
blanchet@53978
  1033
text {*
blanchet@54758
  1034
For simple recursive types, recursive calls on a constructor argument are
blanchet@54758
  1035
allowed on the right-hand side:
blanchet@53978
  1036
*}
blanchet@53978
  1037
blanchet@54467
  1038
    primrec_new replicate :: "nat \<Rightarrow> 'a \<Rightarrow> 'a list" where
blanchet@54467
  1039
      "replicate Zero _ = []" |
blanchet@54781
  1040
      "replicate (Suc n) x = x # replicate n x"
blanchet@53978
  1041
blanchet@54758
  1042
text {* \blankline *}
blanchet@53980
  1043
traytel@54469
  1044
    primrec_new at :: "'a list \<Rightarrow> nat \<Rightarrow> 'a" where
blanchet@54781
  1045
      "at (x # xs) j =
blanchet@53980
  1046
         (case j of
blanchet@54781
  1047
            Zero \<Rightarrow> x
blanchet@54781
  1048
          | Suc j' \<Rightarrow> at xs j')"
blanchet@53980
  1049
blanchet@54758
  1050
text {* \blankline *}
blanchet@54758
  1051
blanchet@54886
  1052
    primrec_new (*<*)(in early) (*>*)tfold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a, 'b) tlist \<Rightarrow> 'b" where
blanchet@54781
  1053
      "tfold _ (TNil y) = y" |
blanchet@54781
  1054
      "tfold f (TCons x xs) = f x (tfold f xs)"
blanchet@53978
  1055
blanchet@54162
  1056
text {*
blanchet@54758
  1057
\noindent
blanchet@55775
  1058
Pattern matching is only available for the argument on which the recursion takes
blanchet@55775
  1059
place. Fortunately, it is easy to generate pattern-maching equations using the
blanchet@55775
  1060
\keyw{simps\_of\_case} command provided by the theory
blanchet@55775
  1061
\verb|~~/src/HOL/Library/Simps_Case_Conv|.
blanchet@55775
  1062
*}
blanchet@55775
  1063
blanchet@55775
  1064
    simps_of_case at_simps: at.simps
blanchet@55775
  1065
blanchet@55775
  1066
text {*
blanchet@55775
  1067
This generates the lemma collection @{thm [source] at_simps}:
blanchet@55775
  1068
%
blanchet@55775
  1069
\[@{thm at_simps(1)[no_vars]}
blanchet@55775
  1070
  \qquad @{thm at_simps(2)[no_vars]}\]
blanchet@55775
  1071
%
blanchet@55636
  1072
The next example is defined using \keyw{fun} to escape the syntactic
blanchet@55636
  1073
restrictions imposed on primitive recursive functions. The
blanchet@55636
  1074
@{command datatype_new_compat} command is needed to register new-style datatypes
blanchet@55636
  1075
for use with \keyw{fun} and \keyw{function}
blanchet@54758
  1076
(Section~\ref{sssec:datatype-new-compat}):
blanchet@54162
  1077
*}
blanchet@53965
  1078
blanchet@54758
  1079
    datatype_new_compat nat
blanchet@54758
  1080
blanchet@54758
  1081
text {* \blankline *}
blanchet@54758
  1082
blanchet@54758
  1083
    fun at_least_two :: "nat \<Rightarrow> bool" where
blanchet@54758
  1084
      "at_least_two (Suc (Suc _)) \<longleftrightarrow> True" |
blanchet@54758
  1085
      "at_least_two _ \<longleftrightarrow> False"
blanchet@54758
  1086
blanchet@54758
  1087
blanchet@54758
  1088
subsubsection {* Mutual Recursion
blanchet@54758
  1089
  \label{sssec:primrec-mutual-recursion} *}
blanchet@53965
  1090
blanchet@53978
  1091
text {*
blanchet@54758
  1092
The syntax for mutually recursive functions over mutually recursive datatypes
blanchet@54758
  1093
is straightforward:
blanchet@53978
  1094
*}
blanchet@53978
  1095
blanchet@53978
  1096
    primrec_new
blanchet@54760
  1097
      nat_of_even_nat :: "even_nat \<Rightarrow> nat" and
blanchet@54760
  1098
      nat_of_odd_nat :: "odd_nat \<Rightarrow> nat"
blanchet@53978
  1099
    where
blanchet@54760
  1100
      "nat_of_even_nat Even_Zero = Zero" |
blanchet@54760
  1101
      "nat_of_even_nat (Even_Suc n) = Suc (nat_of_odd_nat n)" |
blanchet@54760
  1102
      "nat_of_odd_nat (Odd_Suc n) = Suc (nat_of_even_nat n)"
blanchet@53978
  1103
blanchet@54889
  1104
text {* \blankline *}
blanchet@54889
  1105
blanchet@53978
  1106
    primrec_new
blanchet@54467
  1107
      eval\<^sub>e :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) exp \<Rightarrow> int" and
blanchet@54467
  1108
      eval\<^sub>t :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) trm \<Rightarrow> int" and
blanchet@54467
  1109
      eval\<^sub>f :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) fct \<Rightarrow> int"
blanchet@53978
  1110
    where
blanchet@53978
  1111
      "eval\<^sub>e \<gamma> \<xi> (Term t) = eval\<^sub>t \<gamma> \<xi> t" |
blanchet@53978
  1112
      "eval\<^sub>e \<gamma> \<xi> (Sum t e) = eval\<^sub>t \<gamma> \<xi> t + eval\<^sub>e \<gamma> \<xi> e" |
blanchet@54467
  1113
      "eval\<^sub>t \<gamma> \<xi> (Factor f) = eval\<^sub>f \<gamma> \<xi> f" |
blanchet@53978
  1114
      "eval\<^sub>t \<gamma> \<xi> (Prod f t) = eval\<^sub>f \<gamma> \<xi> f + eval\<^sub>t \<gamma> \<xi> t" |
blanchet@53978
  1115
      "eval\<^sub>f \<gamma> _ (Const a) = \<gamma> a" |
blanchet@53978
  1116
      "eval\<^sub>f _ \<xi> (Var b) = \<xi> b" |
blanchet@53978
  1117
      "eval\<^sub>f \<gamma> \<xi> (Expr e) = eval\<^sub>e \<gamma> \<xi> e"
blanchet@53978
  1118
blanchet@54758
  1119
text {*
blanchet@54758
  1120
\noindent
blanchet@54784
  1121
Mutual recursion is possible within a single type, using \keyw{fun}:
blanchet@54758
  1122
*}
blanchet@53965
  1123
blanchet@54758
  1124
    fun
blanchet@54758
  1125
      even :: "nat \<Rightarrow> bool" and
blanchet@54758
  1126
      odd :: "nat \<Rightarrow> bool"
blanchet@54758
  1127
    where
blanchet@54758
  1128
      "even Zero = True" |
blanchet@54758
  1129
      "even (Suc n) = odd n" |
blanchet@54758
  1130
      "odd Zero = False" |
blanchet@54758
  1131
      "odd (Suc n) = even n"
blanchet@54758
  1132
blanchet@54758
  1133
blanchet@54758
  1134
subsubsection {* Nested Recursion
blanchet@54758
  1135
  \label{sssec:primrec-nested-recursion} *}
blanchet@54758
  1136
blanchet@54758
  1137
text {*
blanchet@54758
  1138
In a departure from the old datatype package, nested recursion is normally
blanchet@54758
  1139
handled via the map functions of the nesting type constructors. For example,
blanchet@54758
  1140
recursive calls are lifted to lists using @{const map}:
blanchet@54758
  1141
*}
blanchet@53965
  1142
blanchet@53980
  1143
(*<*)
blanchet@54781
  1144
    datatype_new 'a tree\<^sub>f\<^sub>f = Node\<^sub>f\<^sub>f (lbl\<^sub>f\<^sub>f: 'a) (sub\<^sub>f\<^sub>f: "'a tree\<^sub>f\<^sub>f list")
blanchet@53980
  1145
(*>*)
blanchet@54165
  1146
    primrec_new at\<^sub>f\<^sub>f :: "'a tree\<^sub>f\<^sub>f \<Rightarrow> nat list \<Rightarrow> 'a" where
blanchet@54165
  1147
      "at\<^sub>f\<^sub>f (Node\<^sub>f\<^sub>f a ts) js =
blanchet@53980
  1148
         (case js of
blanchet@53980
  1149
            [] \<Rightarrow> a
blanchet@54165
  1150
          | j # js' \<Rightarrow> at (map (\<lambda>t. at\<^sub>f\<^sub>f t js') ts) j)"
blanchet@53980
  1151
blanchet@54162
  1152
text {*
blanchet@54784
  1153
\noindent
blanchet@54758
  1154
The next example features recursion through the @{text option} type. Although
blanchet@54760
  1155
@{text option} is not a new-style datatype, it is registered as a BNF with the
blanchet@55864
  1156
map function @{const map_option}:
blanchet@54162
  1157
*}
blanchet@53980
  1158
blanchet@54886
  1159
    primrec_new (*<*)(in early) (*>*)sum_btree :: "('a\<Colon>{zero,plus}) btree \<Rightarrow> 'a" where
blanchet@53980
  1160
      "sum_btree (BNode a lt rt) =
blanchet@55864
  1161
         a + the_default 0 (map_option sum_btree lt) +
blanchet@55864
  1162
           the_default 0 (map_option sum_btree rt)"
blanchet@53980
  1163
blanchet@54273
  1164
text {*
blanchet@54758
  1165
\noindent
blanchet@54758
  1166
The same principle applies for arbitrary type constructors through which
blanchet@54758
  1167
recursion is possible. Notably, the map function for the function type
blanchet@54758
  1168
(@{text \<Rightarrow>}) is simply composition (@{text "op \<circ>"}):
blanchet@54273
  1169
*}
blanchet@53965
  1170
blanchet@55634
  1171
    primrec_new (*<*)(in early) (*>*)relabel_ft :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where
blanchet@55634
  1172
      "relabel_ft f (FTLeaf x) = FTLeaf (f x)" |
blanchet@55634
  1173
      "relabel_ft f (FTNode g) = FTNode (relabel_ft f \<circ> g)"
blanchet@53965
  1174
blanchet@53980
  1175
text {*
blanchet@54758
  1176
\noindent
blanchet@55633
  1177
For convenience, recursion through functions can also be expressed using
blanchet@55634
  1178
$\lambda$-abstractions and function application rather than through composition.
blanchet@55633
  1179
For example:
blanchet@54758
  1180
*}
blanchet@54758
  1181
blanchet@55634
  1182
    primrec_new relabel_ft :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where
blanchet@55634
  1183
      "relabel_ft f (FTLeaf x) = FTLeaf (f x)" |
blanchet@55634
  1184
      "relabel_ft f (FTNode g) = FTNode (\<lambda>x. relabel_ft f (g x))"
blanchet@55634
  1185
blanchet@55635
  1186
text {* \blankline *}
blanchet@55635
  1187
blanchet@55635
  1188
    primrec_new subtree_ft :: "'a \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where
blanchet@55635
  1189
      "subtree_ft x (FTNode g) = g x"
blanchet@55635
  1190
blanchet@55634
  1191
text {*
blanchet@55634
  1192
\noindent
blanchet@55634
  1193
For recursion through curried $n$-ary functions, $n$ applications of
blanchet@55634
  1194
@{term "op \<circ>"} are necessary. The examples below illustrate the case where
blanchet@55634
  1195
$n = 2$:
blanchet@55634
  1196
*}
blanchet@55634
  1197
blanchet@55634
  1198
    datatype_new 'a ftree2 = FTLeaf2 'a | FTNode2 "'a \<Rightarrow> 'a \<Rightarrow> 'a ftree2"
blanchet@55634
  1199
blanchet@55634
  1200
text {* \blankline *}
blanchet@55634
  1201
blanchet@55634
  1202
    primrec_new (*<*)(in early) (*>*)relabel_ft2 :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where
blanchet@55634
  1203
      "relabel_ft2 f (FTLeaf2 x) = FTLeaf2 (f x)" |
blanchet@55634
  1204
      "relabel_ft2 f (FTNode2 g) = FTNode2 (op \<circ> (op \<circ> (relabel_ft2 f)) g)"
blanchet@55634
  1205
blanchet@55634
  1206
text {* \blankline *}
blanchet@55634
  1207
blanchet@55634
  1208
    primrec_new relabel_ft2 :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where
blanchet@55634
  1209
      "relabel_ft2 f (FTLeaf2 x) = FTLeaf2 (f x)" |
blanchet@55634
  1210
      "relabel_ft2 f (FTNode2 g) = FTNode2 (\<lambda>x y. relabel_ft2 f (g x y))"
blanchet@55168
  1211
blanchet@55635
  1212
text {* \blankline *}
blanchet@55635
  1213
blanchet@55635
  1214
    primrec_new subtree_ft2 :: "'a \<Rightarrow> 'a \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where
blanchet@55635
  1215
      "subtree_ft2 x y (FTNode2 g) = g x y"
blanchet@55635
  1216
blanchet@54758
  1217
blanchet@54758
  1218
subsubsection {* Nested-as-Mutual Recursion
blanchet@54781
  1219
  \label{sssec:primrec-nested-as-mutual-recursion} *}
blanchet@54758
  1220
blanchet@54886
  1221
(*<*)
blanchet@54886
  1222
    locale n2m begin
blanchet@54886
  1223
(*>*)
blanchet@54886
  1224
blanchet@54758
  1225
text {*
blanchet@54758
  1226
For compatibility with the old package, but also because it is sometimes
blanchet@54758
  1227
convenient in its own right, it is possible to treat nested recursive datatypes
blanchet@54758
  1228
as mutually recursive ones if the recursion takes place though new-style
blanchet@54758
  1229
datatypes. For example:
blanchet@53980
  1230
*}
blanchet@53980
  1231
traytel@54468
  1232
    primrec_new
blanchet@54784
  1233
      at\<^sub>f\<^sub>f :: "'a tree\<^sub>f\<^sub>f \<Rightarrow> nat list \<Rightarrow> 'a" and
blanchet@54784
  1234
      ats\<^sub>f\<^sub>f :: "'a tree\<^sub>f\<^sub>f list \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> 'a"
blanchet@53980
  1235
    where
blanchet@54784
  1236
      "at\<^sub>f\<^sub>f (Node\<^sub>f\<^sub>f a ts) js =
blanchet@53980
  1237
         (case js of
blanchet@53980
  1238
            [] \<Rightarrow> a
blanchet@54784
  1239
          | j # js' \<Rightarrow> ats\<^sub>f\<^sub>f ts j js')" |
blanchet@54784
  1240
      "ats\<^sub>f\<^sub>f (t # ts) j =
blanchet@53980
  1241
         (case j of
blanchet@54784
  1242
            Zero \<Rightarrow> at\<^sub>f\<^sub>f t
blanchet@54784
  1243
          | Suc j' \<Rightarrow> ats\<^sub>f\<^sub>f ts j')"
blanchet@53980
  1244
blanchet@54784
  1245
text {*
blanchet@54784
  1246
\noindent
blanchet@55739
  1247
Appropriate induction rules are generated as
blanchet@55168
  1248
@{thm [source] at\<^sub>f\<^sub>f.induct},
blanchet@55168
  1249
@{thm [source] ats\<^sub>f\<^sub>f.induct}, and
blanchet@55739
  1250
@{thm [source] at\<^sub>f\<^sub>f_ats\<^sub>f\<^sub>f.induct}. The
blanchet@55739
  1251
induction rules and the underlying recursors are generated on a per-need basis
blanchet@55739
  1252
and are kept in a cache to speed up subsequent definitions.
blanchet@54784
  1253
blanchet@54784
  1254
Here is a second example:
blanchet@54784
  1255
*}
blanchet@54758
  1256
traytel@54468
  1257
    primrec_new
blanchet@54467
  1258
      sum_btree :: "('a\<Colon>{zero,plus}) btree \<Rightarrow> 'a" and
blanchet@54467
  1259
      sum_btree_option :: "'a btree option \<Rightarrow> 'a"
blanchet@53980
  1260
    where
blanchet@53980
  1261
      "sum_btree (BNode a lt rt) =
blanchet@54162
  1262
         a + sum_btree_option lt + sum_btree_option rt" |
blanchet@54467
  1263
      "sum_btree_option None = 0" |
blanchet@54162
  1264
      "sum_btree_option (Some t) = sum_btree t"
blanchet@53980
  1265
blanchet@53980
  1266
text {*
blanchet@54758
  1267
%  * can pretend a nested type is mutually recursive (if purely inductive)
blanchet@54758
  1268
%  * avoids the higher-order map
blanchet@54758
  1269
%  * e.g.
blanchet@54758
  1270
blanchet@54754
  1271
%  * this can always be avoided;
blanchet@54754
  1272
%     * e.g. in our previous example, we first mapped the recursive
blanchet@54754
  1273
%       calls, then we used a generic at function to retrieve the result
blanchet@54754
  1274
%
blanchet@54754
  1275
%  * there's no hard-and-fast rule of when to use one or the other,
blanchet@54754
  1276
%    just like there's no rule when to use fold and when to use
blanchet@54754
  1277
%    primrec_new
blanchet@54754
  1278
%
blanchet@54754
  1279
%  * higher-order approach, considering nesting as nesting, is more
blanchet@54754
  1280
%    compositional -- e.g. we saw how we could reuse an existing polymorphic
blanchet@54784
  1281
%    at or the_default, whereas @{const ats\<^sub>f\<^sub>f} is much more specific
blanchet@54754
  1282
%
blanchet@54754
  1283
%  * but:
blanchet@54754
  1284
%     * is perhaps less intuitive, because it requires higher-order thinking
blanchet@54754
  1285
%     * may seem inefficient, and indeed with the code generator the
blanchet@54754
  1286
%       mutually recursive version might be nicer
blanchet@54754
  1287
%     * is somewhat indirect -- must apply a map first, then compute a result
blanchet@54754
  1288
%       (cannot mix)
blanchet@54784
  1289
%     * the auxiliary functions like @{const ats\<^sub>f\<^sub>f} are sometimes useful in own right
blanchet@54754
  1290
%
blanchet@54754
  1291
%  * impact on automation unclear
blanchet@54754
  1292
%
blanchet@53980
  1293
*}
blanchet@54886
  1294
(*<*)
blanchet@54886
  1295
    end
blanchet@54886
  1296
(*>*)
blanchet@53980
  1297
blanchet@53961
  1298
blanchet@54754
  1299
subsection {* Command Syntax
blanchet@54754
  1300
  \label{ssec:primrec-command-syntax} *}
blanchet@54754
  1301
blanchet@54754
  1302
blanchet@54758
  1303
subsubsection {* \keyw{primrec\_new}
blanchet@54758
  1304
  \label{sssec:primrec-new} *}
blanchet@53931
  1305
blanchet@53965
  1306
text {*
blanchet@54966
  1307
\begin{matharray}{rcl}
blanchet@54966
  1308
  @{command_def "primrec_new"} & : & @{text "local_theory \<rightarrow> local_theory"}
blanchet@54966
  1309
\end{matharray}
blanchet@53961
  1310
blanchet@53977
  1311
@{rail "
blanchet@54966
  1312
  @@{command primrec_new} target? fixes \\ @'where' (@{syntax pr_equation} + '|')
blanchet@53977
  1313
  ;
blanchet@54966
  1314
  @{syntax_def pr_equation}: thmdecl? prop
blanchet@53977
  1315
"}
blanchet@53965
  1316
*}
blanchet@53931
  1317
blanchet@53977
  1318
blanchet@54756
  1319
(*
blanchet@53977
  1320
subsection {* Generated Theorems
blanchet@53977
  1321
  \label{ssec:primrec-generated-theorems} *}
blanchet@53965
  1322
blanchet@53965
  1323
text {*
blanchet@54754
  1324
%  * synthesized nonrecursive definition
blanchet@54754
  1325
%  * user specification is rederived from it, exactly as entered
blanchet@54754
  1326
%
blanchet@54754
  1327
%  * induct
blanchet@54754
  1328
%    * mutualized
blanchet@54754
  1329
%    * without some needless induction hypotheses if not used
blanchet@54754
  1330
%  * fold, rec
blanchet@54754
  1331
%    * mutualized
blanchet@53965
  1332
*}
blanchet@54756
  1333
*)
blanchet@54756
  1334
blanchet@53961
  1335
blanchet@53977
  1336
subsection {* Recursive Default Values for Selectors
blanchet@54760
  1337
  \label{ssec:primrec-recursive-default-values-for-selectors} *}
blanchet@53964
  1338
blanchet@53964
  1339
text {*
blanchet@53964
  1340
A datatype selector @{text un_D} can have a default value for each constructor
blanchet@53964
  1341
on which it is not otherwise specified. Occasionally, it is useful to have the
blanchet@53964
  1342
default value be defined recursively. This produces a chicken-and-egg situation
blanchet@54758
  1343
that may seem unsolvable, because the datatype is not introduced yet at the
blanchet@53964
  1344
moment when the selectors are introduced. Of course, we can always define the
blanchet@53964
  1345
selectors manually afterward, but we then have to state and prove all the
blanchet@53964
  1346
characteristic theorems ourselves instead of letting the package do it.
blanchet@53964
  1347
blanchet@53964
  1348
Fortunately, there is a fairly elegant workaround that relies on overloading and
blanchet@53964
  1349
that avoids the tedium of manual derivations:
blanchet@53964
  1350
blanchet@53964
  1351
\begin{enumerate}
blanchet@53964
  1352
\setlength{\itemsep}{0pt}
blanchet@53964
  1353
blanchet@53964
  1354
\item
blanchet@53964
  1355
Introduce a fully unspecified constant @{text "un_D\<^sub>0 \<Colon> 'a"} using
blanchet@53964
  1356
@{keyword consts}.
blanchet@53964
  1357
blanchet@53964
  1358
\item
blanchet@54672
  1359
Define the datatype, specifying @{text "un_D\<^sub>0"} as the selector's default
blanchet@54672
  1360
value.
blanchet@53964
  1361
blanchet@53964
  1362
\item
blanchet@54672
  1363
Define the behavior of @{text "un_D\<^sub>0"} on values of the newly introduced
blanchet@54672
  1364
datatype using the \keyw{overloading} command.
blanchet@53964
  1365
blanchet@53964
  1366
\item
blanchet@53964
  1367
Derive the desired equation on @{text un_D} from the characteristic equations
blanchet@53964
  1368
for @{text "un_D\<^sub>0"}.
blanchet@53964
  1369
\end{enumerate}
blanchet@53964
  1370
blanchet@54756
  1371
\noindent
blanchet@53964
  1372
The following example illustrates this procedure:
blanchet@53964
  1373
*}
blanchet@53964
  1374
blanchet@53964
  1375
    consts termi\<^sub>0 :: 'a
blanchet@53964
  1376
blanchet@54756
  1377
text {* \blankline *}
blanchet@54756
  1378
blanchet@54628
  1379
    datatype_new ('a, 'b) tlist =
blanchet@53964
  1380
      TNil (termi: 'b) (defaults ttl: TNil)
blanchet@54628
  1381
    | TCons (thd: 'a) (ttl : "('a, 'b) tlist") (defaults termi: "\<lambda>_ xs. termi\<^sub>0 xs")
blanchet@53964
  1382
blanchet@54756
  1383
text {* \blankline *}
blanchet@54756
  1384
blanchet@53964
  1385
    overloading
blanchet@54628
  1386
      termi\<^sub>0 \<equiv> "termi\<^sub>0 \<Colon> ('a, 'b) tlist \<Rightarrow> 'b"
blanchet@53964
  1387
    begin
blanchet@54628
  1388
    primrec_new termi\<^sub>0 :: "('a, 'b) tlist \<Rightarrow> 'b" where
blanchet@54758
  1389
      "termi\<^sub>0 (TNil y) = y" |
blanchet@54758
  1390
      "termi\<^sub>0 (TCons x xs) = termi\<^sub>0 xs"
blanchet@53964
  1391
    end
blanchet@53964
  1392
blanchet@54756
  1393
text {* \blankline *}
blanchet@54756
  1394
blanchet@53964
  1395
    lemma terminal_TCons[simp]: "termi (TCons x xs) = termi xs"
blanchet@53964
  1396
    by (cases xs) auto
blanchet@53964
  1397
blanchet@53964
  1398
blanchet@53965
  1399
subsection {* Compatibility Issues
blanchet@54754
  1400
  \label{ssec:primrec-compatibility-issues} *}
blanchet@53965
  1401
blanchet@53965
  1402
text {*
blanchet@55134
  1403
The command @{command primrec_new} has been designed to be highly compatible
blanchet@55134
  1404
with the old \keyw{primrec}, to ease migration. There is nonetheless at least
blanchet@55134
  1405
one incompatibility that may arise when porting to the new package:
blanchet@55134
  1406
blanchet@55134
  1407
\begin{itemize}
blanchet@55134
  1408
\setlength{\itemsep}{0pt}
blanchet@55134
  1409
blanchet@55637
  1410
\item \emph{Some theorems have different names.}
blanchet@55134
  1411
For $m > 1$ mutually recursive functions,
blanchet@55160
  1412
@{text "f\<^sub>1_\<dots>_f\<^sub>m.simps"} has been broken down into separate
blanchet@55160
  1413
subcollections @{text "f\<^sub>i.simps"}.
blanchet@55134
  1414
\end{itemize}
blanchet@53965
  1415
*}
blanchet@53931
  1416
blanchet@53931
  1417
blanchet@53964
  1418
section {* Defining Codatatypes
blanchet@53942
  1419
  \label{sec:defining-codatatypes} *}
blanchet@53942
  1420
blanchet@53942
  1421
text {*
blanchet@54966
  1422
Codatatypes can be specified using the @{command codatatype} command. The
blanchet@54760
  1423
command is first illustrated through concrete examples featuring different
blanchet@54760
  1424
flavors of corecursion. More examples can be found in the directory
blanchet@55134
  1425
\verb|~~/src/HOL/|\allowbreak\verb|BNF/Examples|. The
blanchet@55134
  1426
\emph{Archive of Formal Proofs} also includes some useful codatatypes, notably
blanchet@55134
  1427
for lazy lists \cite{lochbihler-2010}.
blanchet@53942
  1428
*}
blanchet@53929
  1429
blanchet@53929
  1430
blanchet@54754
  1431
subsection {* Introductory Examples
blanchet@54754
  1432
  \label{ssec:codatatype-introductory-examples} *}
blanchet@53931
  1433
blanchet@54760
  1434
blanchet@54760
  1435
subsubsection {* Simple Corecursion
blanchet@54760
  1436
  \label{sssec:codatatype-simple-corecursion} *}
blanchet@54760
  1437
blanchet@53942
  1438
text {*
blanchet@55000
  1439
Noncorecursive codatatypes coincide with the corresponding datatypes, so they
blanchet@55000
  1440
are useless in practice. \emph{Corecursive codatatypes} have the same syntax
blanchet@54760
  1441
as recursive datatypes, except for the command name. For example, here is the
blanchet@54760
  1442
definition of lazy lists:
blanchet@53942
  1443
*}
blanchet@54760
  1444
blanchet@54760
  1445
    codatatype (lset: 'a) llist (map: lmap rel: llist_all2) =
blanchet@54760
  1446
      lnull: LNil (defaults ltl: LNil)
blanchet@54760
  1447
    | LCons (lhd: 'a) (ltl: "'a llist")
blanchet@54760
  1448
blanchet@54760
  1449
text {*
blanchet@54760
  1450
\noindent
blanchet@54760
  1451
Lazy lists can be infinite, such as @{text "LCons 0 (LCons 0 (\<dots>))"} and
blanchet@54784
  1452
@{text "LCons 0 (LCons 1 (LCons 2 (\<dots>)))"}. Here is a related type, that of
blanchet@54784
  1453
infinite streams:
blanchet@54784
  1454
*}
blanchet@54784
  1455
blanchet@54784
  1456
    codatatype (sset: 'a) stream (map: smap rel: stream_all2) =
blanchet@54784
  1457
      SCons (shd: 'a) (stl: "'a stream")
blanchet@54784
  1458
blanchet@54784
  1459
text {*
blanchet@54784
  1460
\noindent
blanchet@54784
  1461
Another interesting type that can
blanchet@54760
  1462
be defined as a codatatype is that of the extended natural numbers:
blanchet@54760
  1463
*}
blanchet@54760
  1464
blanchet@54781
  1465
    codatatype enat = EZero | ESuc enat
blanchet@54760
  1466
blanchet@54760
  1467
text {*
blanchet@54760
  1468
\noindent
blanchet@54760
  1469
This type has exactly one infinite element, @{text "ESuc (ESuc (ESuc (\<dots>)))"},
blanchet@54760
  1470
that represents $\infty$. In addition, it has finite values of the form
blanchet@54760
  1471
@{text "ESuc (\<dots> (ESuc EZero)\<dots>)"}.
blanchet@54812
  1472
blanchet@54812
  1473
Here is an example with many constructors:
blanchet@54760
  1474
*}
blanchet@54760
  1475
blanchet@54812
  1476
    codatatype 'a process =
blanchet@54812
  1477
      Fail
blanchet@54812
  1478
    | Skip (cont: "'a process")
blanchet@54812
  1479
    | Action (prefix: 'a) (cont: "'a process")
blanchet@54812
  1480
    | Choice (left: "'a process") (right: "'a process")
blanchet@54812
  1481
blanchet@54887
  1482
text {*
blanchet@54966
  1483
\noindent
blanchet@54887
  1484
Notice that the @{const cont} selector is associated with both @{const Skip}
blanchet@55598
  1485
and @{const Action}.
blanchet@54887
  1486
*}
blanchet@54887
  1487
blanchet@54760
  1488
blanchet@54760
  1489
subsubsection {* Mutual Corecursion
blanchet@54760
  1490
  \label{sssec:codatatype-mutual-corecursion} *}
blanchet@54760
  1491
blanchet@54760
  1492
text {*
blanchet@54760
  1493
\noindent
blanchet@54760
  1494
The example below introduces a pair of \emph{mutually corecursive} types:
blanchet@54760
  1495
*}
blanchet@54760
  1496
blanchet@54760
  1497
    codatatype even_enat = Even_EZero | Even_ESuc odd_enat
blanchet@54760
  1498
    and odd_enat = Odd_ESuc even_enat
blanchet@54760
  1499
blanchet@54760
  1500
blanchet@54760
  1501
subsubsection {* Nested Corecursion
blanchet@54760
  1502
  \label{sssec:codatatype-nested-corecursion} *}
blanchet@54760
  1503
blanchet@54760
  1504
text {*
blanchet@54760
  1505
\noindent
blanchet@54812
  1506
The next examples feature \emph{nested corecursion}:
blanchet@54760
  1507
*}
blanchet@54760
  1508
blanchet@54781
  1509
    codatatype 'a tree\<^sub>i\<^sub>i = Node\<^sub>i\<^sub>i (lbl\<^sub>i\<^sub>i: 'a) (sub\<^sub>i\<^sub>i: "'a tree\<^sub>i\<^sub>i llist")
blanchet@54812
  1510
blanchet@54889
  1511
text {* \blankline *}
blanchet@54889
  1512
blanchet@54781
  1513
    codatatype 'a tree\<^sub>i\<^sub>s = Node\<^sub>i\<^sub>s (lbl\<^sub>i\<^sub>s: 'a) (sub\<^sub>i\<^sub>s: "'a tree\<^sub>i\<^sub>s fset")
blanchet@53942
  1514
blanchet@54889
  1515
text {* \blankline *}
blanchet@54889
  1516
blanchet@54812
  1517
    codatatype 'a state_machine =
blanchet@54888
  1518
      State_Machine (accept: bool) (trans: "'a \<Rightarrow> 'a state_machine")
blanchet@54812
  1519
blanchet@53961
  1520
blanchet@54754
  1521
subsection {* Command Syntax
blanchet@54754
  1522
  \label{ssec:codatatype-command-syntax} *}
blanchet@53931
  1523
blanchet@54756
  1524
blanchet@54758
  1525
subsubsection {* \keyw{codatatype}
blanchet@54758
  1526
  \label{sssec:codatatype} *}
blanchet@54756
  1527
blanchet@53961
  1528
text {*
blanchet@54966
  1529
\begin{matharray}{rcl}
blanchet@54966
  1530
  @{command_def "codatatype"} & : & @{text "local_theory \<rightarrow> local_theory"}
blanchet@54966
  1531
\end{matharray}
blanchet@54966
  1532
blanchet@54966
  1533
@{rail "
blanchet@54966
  1534
  @@{command codatatype} target? \\
blanchet@54966
  1535
    (@{syntax dt_name} '=' (@{syntax ctor} + '|') + @'and')
blanchet@54966
  1536
"}
blanchet@54966
  1537
blanchet@54966
  1538
\noindent
blanchet@53964
  1539
Definitions of codatatypes have almost exactly the same syntax as for datatypes
blanchet@54966
  1540
(Section~\ref{ssec:datatype-command-syntax}). The @{text "no_discs_sels"} option
blanchet@54966
  1541
is not available, because destructors are a crucial notion for codatatypes.
blanchet@53961
  1542
*}
blanchet@53961
  1543
blanchet@54754
  1544
blanchet@54754
  1545
subsection {* Generated Constants
blanchet@54754
  1546
  \label{ssec:codatatype-generated-constants} *}
blanchet@54754
  1547
blanchet@54760
  1548
text {*
blanchet@54760
  1549
Given a codatatype @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"}
blanchet@54760
  1550
with $m > 0$ live type variables and $n$ constructors @{text "t.C\<^sub>1"},
blanchet@54760
  1551
\ldots, @{text "t.C\<^sub>n"}, the same auxiliary constants are generated as for
blanchet@54760
  1552
datatypes (Section~\ref{ssec:datatype-generated-constants}), except that the
blanchet@54760
  1553
iterator and the recursor are replaced by dual concepts:
blanchet@54754
  1554
blanchet@54760
  1555
\begin{itemize}
blanchet@54760
  1556
\setlength{\itemsep}{0pt}
blanchet@54760
  1557
blanchet@55867
  1558
\item \relax{Coiterator}: @{text unfold_t}
blanchet@55867
  1559
blanchet@55867
  1560
\item \relax{Corecursor}: @{text corec_t}
blanchet@54760
  1561
blanchet@54760
  1562
\end{itemize}
blanchet@54760
  1563
*}
blanchet@54760
  1564
blanchet@54760
  1565
blanchet@53977
  1566
subsection {* Generated Theorems
blanchet@53977
  1567
  \label{ssec:codatatype-generated-theorems} *}
blanchet@54760
  1568
blanchet@54760
  1569
text {*
blanchet@54966
  1570
The characteristic theorems generated by @{command codatatype} are grouped in
blanchet@54760
  1571
three broad categories:
blanchet@54760
  1572
blanchet@54760
  1573
\begin{itemize}
blanchet@54886
  1574
\setlength{\itemsep}{0pt}
blanchet@54886
  1575
blanchet@54760
  1576
\item The \emph{free constructor theorems} are properties about the constructors
blanchet@54760
  1577
and destructors that can be derived for any freely generated type.
blanchet@54760
  1578
blanchet@54760
  1579
\item The \emph{functorial theorems} are properties of datatypes related to
blanchet@54760
  1580
their BNF nature.
blanchet@54760
  1581
blanchet@54760
  1582
\item The \emph{coinductive theorems} are properties of datatypes related to
blanchet@54760
  1583
their coinductive nature.
blanchet@54760
  1584
\end{itemize}
blanchet@54760
  1585
blanchet@54760
  1586
\noindent
blanchet@54760
  1587
The first two categories are exactly as for datatypes and are described in
blanchet@54779
  1588
Sections
blanchet@54779
  1589
\ref{sssec:free-constructor-theorems}~and~\ref{sssec:functorial-theorems}.
blanchet@54760
  1590
*}
blanchet@54760
  1591
blanchet@54760
  1592
blanchet@54760
  1593
subsubsection {* Coinductive Theorems
blanchet@54760
  1594
  \label{sssec:coinductive-theorems} *}
blanchet@54760
  1595
blanchet@54760
  1596
text {*
blanchet@55168
  1597
The coinductive theorems are listed below for @{typ "'a llist"}:
blanchet@54760
  1598
blanchet@54760
  1599
\begin{indentblock}
blanchet@54760
  1600
\begin{description}
blanchet@54760
  1601
blanchet@54780
  1602
\item[\begin{tabular}{@ {}l@ {}}
blanchet@54780
  1603
  @{text "t."}\hthm{coinduct} @{text "[coinduct t, consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
blanchet@54780
  1604
  \phantom{@{text "t."}\hthm{coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"}\rm:
blanchet@54780
  1605
\end{tabular}] ~ \\
blanchet@54760
  1606
@{thm llist.coinduct[no_vars]}
blanchet@54760
  1607
blanchet@54780
  1608
\item[\begin{tabular}{@ {}l@ {}}
blanchet@54780
  1609
  @{text "t."}\hthm{strong\_coinduct} @{text "[consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
blanchet@54780
  1610
  \phantom{@{text "t."}\hthm{strong\_coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"}\rm:
blanchet@54780
  1611
\end{tabular}] ~ \\
blanchet@54780
  1612
@{thm llist.strong_coinduct[no_vars]}
blanchet@54760
  1613
blanchet@54780
  1614
\item[\begin{tabular}{@ {}l@ {}}
blanchet@54780
  1615
  @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{coinduct} @{text "[case_names t\<^sub>1 \<dots> t\<^sub>m, case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"} \\
blanchet@54780
  1616
  @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{strong\_coinduct} @{text "[case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
blanchet@54780
  1617
  \phantom{@{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{strong\_coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"}\rm:
blanchet@54780
  1618
\end{tabular}] ~ \\
blanchet@54780
  1619
Given $m > 1$ mutually corecursive codatatypes, these coinduction rules can be
blanchet@54780
  1620
used to prove $m$ properties simultaneously.
blanchet@54780
  1621
blanchet@55168
  1622
\item[@{text "t."}\hthm{unfold}\rm:] ~ \\
blanchet@54760
  1623
@{thm llist.unfold(1)[no_vars]} \\
blanchet@54760
  1624
@{thm llist.unfold(2)[no_vars]}
blanchet@54760
  1625
blanchet@55168
  1626
\item[@{text "t."}\hthm{corec}\rm:] ~ \\
blanchet@54760
  1627
@{thm llist.corec(1)[no_vars]} \\
blanchet@54760
  1628
@{thm llist.corec(2)[no_vars]}
blanchet@54760
  1629
blanchet@54840
  1630
\item[@{text "t."}\hthm{disc\_unfold}\rm:] ~ \\
blanchet@54780
  1631
@{thm llist.disc_unfold(1)[no_vars]} \\
blanchet@54780
  1632
@{thm llist.disc_unfold(2)[no_vars]}
blanchet@54780
  1633
blanchet@54840
  1634
\item[@{text "t."}\hthm{disc\_corec}\rm:] ~ \\
blanchet@54780
  1635
@{thm llist.disc_corec(1)[no_vars]} \\
blanchet@54780
  1636
@{thm llist.disc_corec(2)[no_vars]}
blanchet@54780
  1637
blanchet@54780
  1638
\item[@{text "t."}\hthm{disc\_unfold\_iff} @{text "[simp]"}\rm:] ~ \\
blanchet@54780
  1639
@{thm llist.disc_unfold_iff(1)[no_vars]} \\
blanchet@54780
  1640
@{thm llist.disc_unfold_iff(2)[no_vars]}
blanchet@54780
  1641
blanchet@54780
  1642
\item[@{text "t."}\hthm{disc\_corec\_iff} @{text "[simp]"}\rm:] ~ \\
blanchet@54780
  1643
@{thm llist.disc_corec_iff(1)[no_vars]} \\
blanchet@54780
  1644
@{thm llist.disc_corec_iff(2)[no_vars]}
blanchet@54780
  1645
blanchet@54780
  1646
\item[@{text "t."}\hthm{sel\_unfold} @{text "[simp]"}\rm:] ~ \\
blanchet@54780
  1647
@{thm llist.sel_unfold(1)[no_vars]} \\
blanchet@54780
  1648
@{thm llist.sel_unfold(2)[no_vars]}
blanchet@54780
  1649
blanchet@54780
  1650
\item[@{text "t."}\hthm{sel\_corec} @{text "[simp]"}\rm:] ~ \\
blanchet@54780
  1651
@{thm llist.sel_corec(1)[no_vars]} \\
blanchet@54780
  1652
@{thm llist.sel_corec(2)[no_vars]}
blanchet@54780
  1653
blanchet@54760
  1654
\end{description}
blanchet@54760
  1655
\end{indentblock}
blanchet@54760
  1656
blanchet@54760
  1657
\noindent
blanchet@54966
  1658
For convenience, @{command codatatype} also provides the following collection:
blanchet@54760
  1659
blanchet@54760
  1660
\begin{indentblock}
blanchet@54760
  1661
\begin{description}
blanchet@54760
  1662
blanchet@55168
  1663
\item[@{text "t."}\hthm{simps} = @{text t.inject} @{text t.distinct} @{text t.case} @{text t.disc_corec} @{text t.disc_corec_iff}] ~ \\
blanchet@55168
  1664
@{text t.sel_corec} @{text t.disc_unfold} @{text t.disc_unfold_iff} @{text t.sel_unfold} @{text t.map} \\
blanchet@55168
  1665
@{text t.rel_inject} @{text t.rel_distinct} @{text t.set}
blanchet@54760
  1666
blanchet@54760
  1667
\end{description}
blanchet@54760
  1668
\end{indentblock}
blanchet@54760
  1669
*}
blanchet@53961
  1670
blanchet@53961
  1671
blanchet@53964
  1672
section {* Defining Corecursive Functions
blanchet@53961
  1673
  \label{sec:defining-corecursive-functions} *}
blanchet@53961
  1674
blanchet@53961
  1675
text {*
blanchet@55635
  1676
Corecursive functions can be specified using the @{command primcorec} and
blanchet@55635
  1677
\keyw{prim\-corec\-ursive} commands, which support primitive corecursion, or
blanchet@55635
  1678
using the more general \keyw{partial\_function} command. Here, the focus is on
blanchet@55635
  1679
the first two. More examples can be found in the directory
blanchet@54890
  1680
\verb|~~/src/HOL/BNF/Examples|.
blanchet@54781
  1681
blanchet@54783
  1682
Whereas recursive functions consume datatypes one constructor at a time,
blanchet@54783
  1683
corecursive functions construct codatatypes one constructor at a time.
blanchet@54889
  1684
Partly reflecting a lack of agreement among proponents of coalgebraic methods,
blanchet@54889
  1685
Isabelle supports three competing syntaxes for specifying a function $f$:
blanchet@54780
  1686
blanchet@54780
  1687
\begin{itemize}
blanchet@54886
  1688
\setlength{\itemsep}{0pt}
blanchet@54886
  1689
blanchet@54781
  1690
\abovedisplayskip=.5\abovedisplayskip
blanchet@54781
  1691
\belowdisplayskip=.5\belowdisplayskip
blanchet@54781
  1692
blanchet@54781
  1693
\item The \emph{destructor view} specifies $f$ by implications of the form
blanchet@54780
  1694
\[@{text "\<dots> \<Longrightarrow> is_C\<^sub>j (f x\<^sub>1 \<dots> x\<^sub>n)"}\] and
blanchet@54780
  1695
equations of the form
blanchet@54784
  1696
\[@{text "un_C\<^sub>ji (f x\<^sub>1 \<dots> x\<^sub>n) = \<dots>"}\]
blanchet@54784
  1697
This style is popular in the coalgebraic literature.
blanchet@54886
  1698
blanchet@54886
  1699
\item The \emph{constructor view} specifies $f$ by equations of the form
blanchet@55635
  1700
\[@{text "\<dots> \<Longrightarrow> f x\<^sub>1 \<dots> x\<^sub>n = C\<^sub>j \<dots>"}\]
blanchet@54889
  1701
This style is often more concise than the previous one.
blanchet@54886
  1702
blanchet@54886
  1703
\item The \emph{code view} specifies $f$ by a single equation of the form
blanchet@54886
  1704
\[@{text "f x\<^sub>1 \<dots> x\<^sub>n = \<dots>"}\]
blanchet@54886
  1705
with restrictions on the format of the right-hand side. Lazy functional
blanchet@54886
  1706
programming languages such as Haskell support a generalized version of this
blanchet@54886
  1707
style.
blanchet@54780
  1708
\end{itemize}
blanchet@54780
  1709
blanchet@54890
  1710
All three styles are available as input syntax. Whichever syntax is chosen,
blanchet@54890
  1711
characteristic theorems for all three styles are generated.
blanchet@54886
  1712
blanchet@54886
  1713
%%% TODO: partial_function? E.g. for defining tail recursive function on lazy
blanchet@54886
  1714
%%% lists (cf. terminal0 in TLList.thy)
blanchet@54886
  1715
*}
blanchet@54886
  1716
blanchet@54886
  1717
blanchet@54886
  1718
subsection {* Introductory Examples
blanchet@54886
  1719
  \label{ssec:primcorec-introductory-examples} *}
blanchet@54886
  1720
blanchet@54886
  1721
text {*
blanchet@54886
  1722
Primitive corecursion is illustrated through concrete examples based on the
blanchet@54886
  1723
codatatypes defined in Section~\ref{ssec:codatatype-introductory-examples}. More
blanchet@54886
  1724
examples can be found in the directory \verb|~~/src/HOL/BNF/Examples|. The code
blanchet@54886
  1725
view is favored in the examples below. Sections
blanchet@54886
  1726
\ref{ssec:primrec-constructor-view} and \ref{ssec:primrec-destructor-view}
blanchet@54886
  1727
present the same examples expressed using the constructor and destructor views.
blanchet@54886
  1728
*}
blanchet@54886
  1729
blanchet@54886
  1730
subsubsection {* Simple Corecursion
blanchet@54886
  1731
  \label{sssec:primcorec-simple-corecursion} *}
blanchet@54886
  1732
blanchet@54886
  1733
text {*
blanchet@54889
  1734
Following the code view, corecursive calls are allowed on the right-hand side as
blanchet@54889
  1735
long as they occur under a constructor, which itself appears either directly to
blanchet@54889
  1736
the right of the equal sign or in a conditional expression:
blanchet@53961
  1737
*}
blanchet@53961
  1738
blanchet@54963
  1739
    primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where
blanchet@55524
  1740
      "literate g x = LCons x (literate g (g x))"
blanchet@54784
  1741
blanchet@54814
  1742
text {* \blankline *}
blanchet@54814
  1743
blanchet@54963
  1744
    primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where
blanchet@55524
  1745
      "siterate g x = SCons x (siterate g (g x))"
blanchet@54781
  1746
blanchet@54783
  1747
text {*
blanchet@54783
  1748
\noindent
blanchet@54783
  1749
The constructor ensures that progress is made---i.e., the function is
blanchet@54886
  1750
\emph{productive}. The above functions compute the infinite lazy list or stream
blanchet@55524
  1751
@{text "[x, g x, g (g x), \<dots>]"}. Productivity guarantees that prefixes
blanchet@55524
  1752
@{text "[x, g x, g (g x), \<dots>, (g ^^ k) x]"} of arbitrary finite length
blanchet@54886
  1753
@{text k} can be computed by unfolding the code equation a finite number of
blanchet@55000
  1754
times.
blanchet@54783
  1755
blanchet@54889
  1756
Corecursive functions construct codatatype values, but nothing prevents them
blanchet@55000
  1757
from also consuming such values. The following function drops every second
blanchet@54812
  1758
element in a stream:
blanchet@54812
  1759
*}
blanchet@54812
  1760
blanchet@54963
  1761
    primcorec every_snd :: "'a stream \<Rightarrow> 'a stream" where
blanchet@54812
  1762
      "every_snd s = SCons (shd s) (stl (stl s))"
blanchet@54812
  1763
blanchet@54812
  1764
text {*
blanchet@54889
  1765
\noindent
blanchet@54886
  1766
Constructs such as @{text "let"}---@{text "in"}, @{text
blanchet@54783
  1767
"if"}---@{text "then"}---@{text "else"}, and @{text "case"}---@{text "of"} may
blanchet@54783
  1768
appear around constructors that guard corecursive calls:
blanchet@54783
  1769
*}
blanchet@54783
  1770
blanchet@55524
  1771
    primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where
blanchet@54781
  1772
      "lappend xs ys =
blanchet@54781
  1773
         (case xs of
blanchet@54781
  1774
            LNil \<Rightarrow> ys
blanchet@54781
  1775
          | LCons x xs' \<Rightarrow> LCons x (lappend xs' ys))"
blanchet@54781
  1776
blanchet@54783
  1777
text {*
blanchet@54889
  1778
\noindent
blanchet@55775
  1779
Pattern matching is not supported by @{command primcorec}. Fortunately, it is
blanchet@55775
  1780
easy to generate pattern-maching equations using the \keyw{simps\_of\_case}
blanchet@55775
  1781
command provided by the theory \verb|~~/src/HOL/Library/Simps_Case_Conv|.
blanchet@55775
  1782
*}
blanchet@55775
  1783
blanchet@55775
  1784
    simps_of_case lappend_simps: lappend.code
blanchet@55775
  1785
blanchet@55775
  1786
text {*
blanchet@55775
  1787
This generates the lemma collection @{thm [source] lappend_simps}:
blanchet@55775
  1788
%
blanchet@55775
  1789
\[@{thm lappend_simps(1)[no_vars]}
blanchet@55775
  1790
  \qquad @{thm lappend_simps(2)[no_vars]}\]
blanchet@55775
  1791
%
blanchet@54783
  1792
Corecursion is useful to specify not only functions but also infinite objects:
blanchet@54783
  1793
*}
blanchet@54783
  1794
blanchet@54963
  1795
    primcorec infty :: enat where
blanchet@54781
  1796
      "infty = ESuc infty"
blanchet@54781
  1797
blanchet@54783
  1798
text {*
blanchet@54889
  1799
\noindent
blanchet@54889
  1800
The example below constructs a pseudorandom process value. It takes a stream of
blanchet@54812
  1801
actions (@{text s}), a pseudorandom function generator (@{text f}), and a
blanchet@54812
  1802
pseudorandom seed (@{text n}):
blanchet@54812
  1803
*}
blanchet@54812
  1804
blanchet@55524
  1805
    primcorec
blanchet@54889
  1806
      random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process"
blanchet@54889
  1807
    where
blanchet@54812
  1808
      "random_process s f n =
blanchet@54812
  1809
         (if n mod 4 = 0 then
blanchet@54812
  1810
            Fail
blanchet@54812
  1811
          else if n mod 4 = 1 then
blanchet@54812
  1812
            Skip (random_process s f (f n))
blanchet@54812
  1813
          else if n mod 4 = 2 then
blanchet@54812
  1814
            Action (shd s) (random_process (stl s) f (f n))
blanchet@54812
  1815
          else
blanchet@54812
  1816
            Choice (random_process (every_snd s) (f \<circ> f) (f n))
blanchet@54812
  1817
              (random_process (every_snd (stl s)) (f \<circ> f) (f (f n))))"
blanchet@54812
  1818
blanchet@54812
  1819
text {*
blanchet@54812
  1820
\noindent
blanchet@54886
  1821
The main disadvantage of the code view is that the conditions are tested
blanchet@54886
  1822
sequentially. This is visible in the generated theorems. The constructor and
blanchet@54889
  1823
destructor views offer nonsequential alternatives.
blanchet@54812
  1824
*}
blanchet@54812
  1825
blanchet@54886
  1826
blanchet@54886
  1827
subsubsection {* Mutual Corecursion
blanchet@54886
  1828
  \label{sssec:primcorec-mutual-corecursion} *}
blanchet@54886
  1829
blanchet@54886
  1830
text {*
blanchet@54886
  1831
The syntax for mutually corecursive functions over mutually corecursive
blanchet@54886
  1832
datatypes is unsurprising:
blanchet@54886
  1833
*}
blanchet@54886
  1834
blanchet@54963
  1835
    primcorec
blanchet@54886
  1836
      even_infty :: even_enat and
blanchet@54886
  1837
      odd_infty :: odd_enat
blanchet@54886
  1838
    where
blanchet@54886
  1839
      "even_infty = Even_ESuc odd_infty" |
blanchet@54886
  1840
      "odd_infty = Odd_ESuc even_infty"
blanchet@54886
  1841
blanchet@54886
  1842
blanchet@54886
  1843
subsubsection {* Nested Corecursion
blanchet@54886
  1844
  \label{sssec:primcorec-nested-corecursion} *}
blanchet@54886
  1845
blanchet@54886
  1846
text {*
blanchet@54886
  1847
The next pair of examples generalize the @{const literate} and @{const siterate}
blanchet@54886
  1848
functions (Section~\ref{sssec:primcorec-nested-corecursion}) to possibly
blanchet@54886
  1849
infinite trees in which subnodes are organized either as a lazy list (@{text
blanchet@55524
  1850
tree\<^sub>i\<^sub>i}) or as a finite set (@{text tree\<^sub>i\<^sub>s}). They rely on the map functions of
blanchet@55524
  1851
the nesting type constructors to lift the corecursive calls:
blanchet@54886
  1852
*}
blanchet@54886
  1853
blanchet@54963
  1854
    primcorec iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where
blanchet@55524
  1855
      "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (lmap (iterate\<^sub>i\<^sub>i g) (g x))"
blanchet@54886
  1856
blanchet@54886
  1857
text {* \blankline *}
blanchet@54886
  1858
blanchet@54963
  1859
    primcorec iterate\<^sub>i\<^sub>s :: "('a \<Rightarrow> 'a fset) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>s" where
blanchet@55524
  1860
      "iterate\<^sub>i\<^sub>s g x = Node\<^sub>i\<^sub>s x (fimage (iterate\<^sub>i\<^sub>s g) (g x))"
blanchet@54886
  1861
blanchet@54886
  1862
text {*
blanchet@54889
  1863
\noindent
blanchet@55524
  1864
Both examples follow the usual format for constructor arguments associated
blanchet@55524
  1865
with nested recursive occurrences of the datatype. Consider
blanchet@55524
  1866
@{const iterate\<^sub>i\<^sub>i}. The term @{term "g x"} constructs an @{typ "'a llist"}
blanchet@55524
  1867
value, which is turned into an @{typ "'a tree\<^sub>i\<^sub>i llist"} value using
blanchet@55524
  1868
@{const lmap}.
blanchet@55524
  1869
blanchet@55524
  1870
This format may sometimes feel artificial. The following function constructs
blanchet@55524
  1871
a tree with a single, infinite branch from a stream:
blanchet@55524
  1872
*}
blanchet@55524
  1873
blanchet@55524
  1874
    primcorec tree\<^sub>i\<^sub>i_of_stream :: "'a stream \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where
blanchet@55524
  1875
      "tree\<^sub>i\<^sub>i_of_stream s =
blanchet@55524
  1876
         Node\<^sub>i\<^sub>i (shd s) (lmap tree\<^sub>i\<^sub>i_of_stream (LCons (stl s) LNil))"
blanchet@55524
  1877
blanchet@55524
  1878
text {*
blanchet@55524
  1879
\noindent
blanchet@55730
  1880
Fortunately, it is easy to prove the following lemma, where the corecursive call
blanchet@55730
  1881
is moved inside the lazy list constructor, thereby eliminating the need for
blanchet@55730
  1882
@{const lmap}:
blanchet@55524
  1883
*}
blanchet@55524
  1884
blanchet@55730
  1885
    lemma tree\<^sub>i\<^sub>i_of_stream_alt:
blanchet@55524
  1886
      "tree\<^sub>i\<^sub>i_of_stream s = Node\<^sub>i\<^sub>i (shd s) (LCons (tree\<^sub>i\<^sub>i_of_stream (stl s)) LNil)"
blanchet@55730
  1887
    by (subst tree\<^sub>i\<^sub>i_of_stream.code) simp
blanchet@55524
  1888
blanchet@55524
  1889
text {*
blanchet@55524
  1890
The next example illustrates corecursion through functions, which is a bit
blanchet@55524
  1891
special. Deterministic finite automata (DFAs) are traditionally defined as
blanchet@55524
  1892
5-tuples @{text "(Q, \<Sigma>, \<delta>, q\<^sub>0, F)"}, where @{text Q} is a finite set of states,
blanchet@54886
  1893
@{text \<Sigma>} is a finite alphabet, @{text \<delta>} is a transition function, @{text q\<^sub>0}
blanchet@54886
  1894
is an initial state, and @{text F} is a set of final states. The following
blanchet@54886
  1895
function translates a DFA into a @{type state_machine}:
blanchet@54886
  1896
*}
blanchet@54886
  1897
blanchet@55523
  1898
    primcorec
blanchet@55523
  1899
      (*<*)(in early) (*>*)sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a state_machine"
blanchet@54889
  1900
    where
blanchet@55634
  1901
      "sm_of_dfa \<delta> F q = State_Machine (q \<in> F) (sm_of_dfa \<delta> F \<circ> \<delta> q)"
blanchet@54886
  1902
blanchet@54888
  1903
text {*
blanchet@54888
  1904
\noindent
blanchet@54888
  1905
The map function for the function type (@{text \<Rightarrow>}) is composition
blanchet@55633
  1906
(@{text "op \<circ>"}). For convenience, corecursion through functions can
blanchet@55634
  1907
also be expressed using $\lambda$-abstractions and function application rather
blanchet@55168
  1908
than through composition. For example:
blanchet@54888
  1909
*}
blanchet@54888
  1910
blanchet@54963
  1911
    primcorec
blanchet@54889
  1912
      sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a state_machine"
blanchet@54889
  1913
    where
blanchet@55634
  1914
      "sm_of_dfa \<delta> F q = State_Machine (q \<in> F) (\<lambda>a. sm_of_dfa \<delta> F (\<delta> q a))"
blanchet@54888
  1915
blanchet@54889
  1916
text {* \blankline *}
blanchet@54889
  1917
blanchet@54963
  1918
    primcorec empty_sm :: "'a state_machine" where
blanchet@54889
  1919
      "empty_sm = State_Machine False (\<lambda>_. empty_sm)"
blanchet@54888
  1920
blanchet@54889
  1921
text {* \blankline *}
blanchet@54889
  1922
blanchet@54963
  1923
    primcorec not_sm :: "'a state_machine \<Rightarrow> 'a state_machine" where
blanchet@54889
  1924
      "not_sm M = State_Machine (\<not> accept M) (\<lambda>a. not_sm (trans M a))"
blanchet@54889
  1925
blanchet@54889
  1926
text {* \blankline *}
blanchet@54889
  1927
blanchet@54963
  1928
    primcorec
blanchet@54889
  1929
      or_sm :: "'a state_machine \<Rightarrow> 'a state_machine \<Rightarrow> 'a state_machine"
blanchet@54889
  1930
    where
blanchet@55524
  1931
      "or_sm M N = State_Machine (accept M \<or> accept N)
blanchet@55524
  1932
         (\<lambda>a. or_sm (trans M a) (trans N a))"
blanchet@54888
  1933
blanchet@55634
  1934
text {*
blanchet@55634
  1935
\noindent
blanchet@55634
  1936
For recursion through curried $n$-ary functions, $n$ applications of
blanchet@55634
  1937
@{term "op \<circ>"} are necessary. The examples below illustrate the case where
blanchet@55634
  1938
$n = 2$:
blanchet@55634
  1939
*}
blanchet@55634
  1940
blanchet@55634
  1941
    codatatype ('a, 'b) state_machine2 =
blanchet@55634
  1942
      State_Machine2 (accept2: bool) (trans2: "'a \<Rightarrow> 'b \<Rightarrow> ('a, 'b) state_machine2")
blanchet@55634
  1943
blanchet@55634
  1944
text {* \blankline *}
blanchet@55634
  1945
blanchet@55634
  1946
    primcorec
blanchet@55634
  1947
      (*<*)(in early) (*>*)sm2_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> ('a, 'b) state_machine2"
blanchet@55634
  1948
    where
blanchet@55634
  1949
      "sm2_of_dfa \<delta> F q = State_Machine2 (q \<in> F) (op \<circ> (op \<circ> (sm2_of_dfa \<delta> F)) (\<delta> q))"
blanchet@55634
  1950
blanchet@55634
  1951
text {* \blankline *}
blanchet@55634
  1952
blanchet@55634
  1953
    primcorec
blanchet@55634
  1954
      sm2_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> ('a, 'b) state_machine2"
blanchet@55634
  1955
    where
blanchet@55634
  1956
      "sm2_of_dfa \<delta> F q = State_Machine2 (q \<in> F) (\<lambda>a b. sm2_of_dfa \<delta> F (\<delta> q a b))"
blanchet@55634
  1957
blanchet@54886
  1958
blanchet@54886
  1959
subsubsection {* Nested-as-Mutual Corecursion
blanchet@54886
  1960
  \label{sssec:primcorec-nested-as-mutual-corecursion} *}
blanchet@54886
  1961
blanchet@54886
  1962
text {*
blanchet@54886
  1963
Just as it is possible to recurse over nested recursive datatypes as if they
blanchet@54886
  1964
were mutually recursive
blanchet@54886
  1965
(Section~\ref{sssec:primrec-nested-as-mutual-recursion}), it is possible to
blanchet@54889
  1966
pretend that nested codatatypes are mutually corecursive. For example:
blanchet@54886
  1967
*}
blanchet@54886
  1968
blanchet@55739
  1969
(*<*)
blanchet@55739
  1970
    context late
blanchet@55739
  1971
    begin
blanchet@55739
  1972
(*>*)
blanchet@55524
  1973
    primcorec
blanchet@55739
  1974
      iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" and
blanchet@54886
  1975
      iterates\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a llist \<Rightarrow> 'a tree\<^sub>i\<^sub>i llist"
blanchet@54886
  1976
    where
blanchet@55524
  1977
      "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (iterates\<^sub>i\<^sub>i g (g x))" |
blanchet@55524
  1978
      "iterates\<^sub>i\<^sub>i g xs =
blanchet@54886
  1979
         (case xs of
blanchet@54886
  1980
            LNil \<Rightarrow> LNil
blanchet@55524
  1981
          | LCons x xs' \<Rightarrow> LCons (iterate\<^sub>i\<^sub>i g x) (iterates\<^sub>i\<^sub>i g xs'))"
blanchet@54886
  1982
blanchet@55739
  1983
text {*
blanchet@55739
  1984
\noindent
blanchet@55739
  1985
Coinduction rules are generated as
blanchet@55739
  1986
@{thm [source] iterate\<^sub>i\<^sub>i.coinduct},
blanchet@55739
  1987
@{thm [source] iterates\<^sub>i\<^sub>i.coinduct}, and
blanchet@55739
  1988
@{thm [source] iterate\<^sub>i\<^sub>i_iterates\<^sub>i\<^sub>i.coinduct}
blanchet@55739
  1989
and analogously for @{text strong_coinduct}. These rules and the
blanchet@55739
  1990
underlying corecursors are generated on a per-need basis and are kept in a cache
blanchet@55739
  1991
to speed up subsequent definitions.
blanchet@55739
  1992
*}
blanchet@55739
  1993
blanchet@55739
  1994
(*<*)
blanchet@55739
  1995
    end
blanchet@55739
  1996
(*>*)
blanchet@55739
  1997
blanchet@54886
  1998
blanchet@54886
  1999
subsubsection {* Constructor View
blanchet@54886
  2000
  \label{ssec:primrec-constructor-view} *}
blanchet@54886
  2001
blanchet@54886
  2002
(*<*)
blanchet@55634
  2003
    locale ctr_view
blanchet@54812
  2004
    begin
blanchet@54812
  2005
(*>*)
blanchet@54886
  2006
blanchet@54886
  2007
text {*
blanchet@54887
  2008
The constructor view is similar to the code view, but there is one separate
blanchet@54887
  2009
conditional equation per constructor rather than a single unconditional
blanchet@54887
  2010
equation. Examples that rely on a single constructor, such as @{const literate}
blanchet@54887
  2011
and @{const siterate}, are identical in both styles.
blanchet@54887
  2012
blanchet@54887
  2013
Here is an example where there is a difference:
blanchet@54886
  2014
*}
blanchet@54886
  2015
blanchet@54963
  2016
    primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where
blanchet@54886
  2017
      "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lappend xs ys = LNil" |
blanchet@54886
  2018
      "_ \<Longrightarrow> lappend xs ys = LCons (lhd (if lnull xs then ys else xs))
blanchet@54886
  2019
         (if xs = LNil then ltl ys else lappend (ltl xs) ys)"
blanchet@54886
  2020
blanchet@54886
  2021
text {*
blanchet@54886
  2022
\noindent
blanchet@54889
  2023
With the constructor view, we must distinguish between the @{const LNil} and
blanchet@54889
  2024
the @{const LCons} case. The condition for @{const LCons} is
blanchet@54889
  2025
left implicit, as the negation of that for @{const LNil}.
blanchet@54887
  2026
blanchet@54887
  2027
For this example, the constructor view is slighlty more involved than the
blanchet@54887
  2028
code equation. Recall the code view version presented in
blanchet@54886
  2029
Section~\ref{sssec:primcorec-simple-corecursion}.
blanchet@54886
  2030
% TODO: \[{thm code_view.lappend.code}\]
blanchet@54886
  2031
The constructor view requires us to analyze the second argument (@{term ys}).
blanchet@54889
  2032
The code equation generated from the constructor view also suffers from this.
blanchet@54886
  2033
% TODO: \[{thm lappend.code}\]
blanchet@54887
  2034
blanchet@54889
  2035
In contrast, the next example is arguably more naturally expressed in the
blanchet@54889
  2036
constructor view:
blanchet@54886
  2037
*}
blanchet@54886
  2038
panny@54968
  2039
    primcorec
blanchet@54889
  2040
      random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process"
blanchet@54889
  2041
    where
blanchet@54886
  2042
      "n mod 4 = 0 \<Longrightarrow> random_process s f n = Fail" |
blanchet@54889
  2043
      "n mod 4 = 1 \<Longrightarrow>
blanchet@54889
  2044
         random_process s f n = Skip (random_process s f (f n))" |
blanchet@54889
  2045
      "n mod 4 = 2 \<Longrightarrow>
blanchet@54889
  2046
         random_process s f n = Action (shd s) (random_process (stl s) f (f n))" |
blanchet@54889
  2047
      "n mod 4 = 3 \<Longrightarrow>
blanchet@54889
  2048
         random_process s f n = Choice (random_process (every_snd s) f (f n))
blanchet@54963
  2049
           (random_process (every_snd (stl s)) f (f n))"
blanchet@54963
  2050
(*<*)
blanchet@54886
  2051
    end
blanchet@54886
  2052
(*>*)
blanchet@54886
  2053
blanchet@54887
  2054
text {*
blanchet@54889
  2055
\noindent
blanchet@54887
  2056
Since there is no sequentiality, we can apply the equation for @{const Choice}
blanchet@54889
  2057
without having first to discharge @{term "n mod (4\<Colon>int) \<noteq> 0"},
blanchet@54889
  2058
@{term "n mod (4\<Colon>int) \<noteq> 1"}, and
blanchet@54889
  2059
@{term "n mod (4\<Colon>int) \<noteq> 2"}.
blanchet@54887
  2060
The price to pay for this elegance is that we must discharge exclusivity proof
blanchet@54887
  2061
obligations, one for each pair of conditions
blanchet@54889
  2062
@{term "(n mod (4\<Colon>int) = i, n mod (4\<Colon>int) = j)"}
blanchet@54889
  2063
with @{term "i < j"}. If we prefer not to discharge any obligations, we can
blanchet@54889
  2064
enable the @{text "sequential"} option. This pushes the problem to the users of
blanchet@54889
  2065
the generated properties.
blanchet@54887
  2066
%Here are more examples to conclude:
blanchet@54887
  2067
*}
blanchet@54887
  2068
blanchet@54886
  2069
blanchet@54886
  2070
subsubsection {* Destructor View
blanchet@54889
  2071
  \label{ssec:primrec-destructor-view} *}
blanchet@54889
  2072
blanchet@54889
  2073
(*<*)
blanchet@55634
  2074
    locale dtr_view
blanchet@54889
  2075
    begin
blanchet@54889
  2076
(*>*)
blanchet@54886
  2077
blanchet@54886
  2078
text {*
blanchet@54886
  2079
The destructor view is in many respects dual to the constructor view. Conditions
blanchet@54886
  2080
determine which constructor to choose, and these conditions are interpreted
blanchet@54886
  2081
sequentially or not depending on the @{text "sequential"} option.
blanchet@54886
  2082
Consider the following examples:
blanchet@54886
  2083
*}
blanchet@54886
  2084
blanchet@54963
  2085
    primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where
blanchet@54886
  2086
      "\<not> lnull (literate _ x)" |
blanchet@54886
  2087
      "lhd (literate _ x) = x" |
blanchet@55524
  2088
      "ltl (literate g x) = literate g (g x)"
blanchet@54886
  2089
blanchet@54889
  2090
text {* \blankline *}
blanchet@54889
  2091
blanchet@54963
  2092
    primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where
blanchet@54886
  2093
      "shd (siterate _ x) = x" |
blanchet@55524
  2094
      "stl (siterate g x) = siterate g (g x)"
blanchet@54886
  2095
blanchet@54889
  2096
text {* \blankline *}
blanchet@54889
  2097
blanchet@54963
  2098
    primcorec every_snd :: "'a stream \<Rightarrow> 'a stream" where
blanchet@54886
  2099
      "shd (every_snd s) = shd s" |
blanchet@54886
  2100
      "stl (every_snd s) = stl (stl s)"
blanchet@54886
  2101
blanchet@54886
  2102
text {*
blanchet@54886
  2103
\noindent
blanchet@54886
  2104
The first formula in the @{const literate} specification indicates which
blanchet@54886
  2105
constructor to choose. For @{const siterate} and @{const every_snd}, no such
blanchet@54886
  2106
formula is necessary, since the type has only one constructor. The last two
blanchet@54886
  2107
formulas are equations specifying the value of the result for the relevant
blanchet@54886
  2108
selectors. Corecursive calls appear directly to the right of the equal sign.
blanchet@54886
  2109
Their arguments are unrestricted.
blanchet@54887
  2110
blanchet@54887
  2111
The next example shows how to specify functions that rely on more than one
blanchet@54887
  2112
constructor:
blanchet@54887
  2113
*}
blanchet@54887
  2114
blanchet@54963
  2115
    primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where
blanchet@54887
  2116
      "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lnull (lappend xs ys)" |
blanchet@54887
  2117
      "lhd (lappend xs ys) = lhd (if lnull xs then ys else xs)" |
blanchet@54887
  2118
      "ltl (lappend xs ys) = (if xs = LNil then ltl ys else lappend (ltl xs) ys)"
blanchet@54887
  2119
blanchet@54887
  2120
text {*
blanchet@54887
  2121
\noindent
blanchet@54887
  2122
For a codatatype with $n$ constructors, it is sufficient to specify $n - 1$
blanchet@54887
  2123
discriminator formulas. The command will then assume that the remaining
blanchet@54887
  2124
constructor should be taken otherwise. This can be made explicit by adding
blanchet@54887
  2125
*}
blanchet@54887
  2126
blanchet@54887
  2127
(*<*)
blanchet@54887
  2128
    end
blanchet@54887
  2129
blanchet@55634
  2130
    locale dtr_view2
blanchet@55634
  2131
    begin
blanchet@55634
  2132
blanchet@54963
  2133
    primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where
blanchet@54887
  2134
      "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lnull (lappend xs ys)" |
blanchet@54887
  2135
(*>*)
blanchet@54889
  2136
      "_ \<Longrightarrow> \<not> lnull (lappend xs ys)"
blanchet@54889
  2137
(*<*) |
blanchet@54887
  2138
      "lhd (lappend xs ys) = lhd (if lnull xs then ys else xs)" |
blanchet@54887
  2139
      "ltl (lappend xs ys) = (if xs = LNil then ltl ys else lappend (ltl xs) ys)"
blanchet@54887
  2140
(*>*)
blanchet@54887
  2141
blanchet@54887
  2142
text {*
blanchet@54887
  2143
\noindent
blanchet@54889
  2144
to the specification. The generated selector theorems are conditional.
blanchet@54889
  2145
blanchet@54889
  2146
The next example illustrates how to cope with selectors defined for several
blanchet@54887
  2147
constructors:
blanchet@54886
  2148
*}
blanchet@54886
  2149
panny@54968
  2150
    primcorec
blanchet@54889
  2151
      random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process"
blanchet@54889
  2152
    where
blanchet@54812
  2153
      "n mod 4 = 0 \<Longrightarrow> is_Fail (random_process s f n)" |
blanchet@54812
  2154
      "n mod 4 = 1 \<Longrightarrow> is_Skip (random_process s f n)" |
blanchet@54812
  2155
      "n mod 4 = 2 \<Longrightarrow> is_Action (random_process s f n)" |
blanchet@54812
  2156
      "n mod 4 = 3 \<Longrightarrow> is_Choice (random_process s f n)" |
panny@54968
  2157
      "cont (random_process s f n) = random_process s f (f n)" of Skip |
blanchet@54812
  2158
      "prefix (random_process s f n) = shd s" |
panny@54968
  2159
      "cont (random_process s f n) = random_process (stl s) f (f n)" of Action |
blanchet@54812
  2160
      "left (random_process s f n) = random_process (every_snd s) f (f n)" |
panny@54968
  2161
      "right (random_process s f n) = random_process (every_snd (stl s)) f (f n)"
blanchet@54812
  2162
blanchet@54812
  2163
text {*
blanchet@54887
  2164
\noindent
blanchet@54887
  2165
Using the @{text "of"} keyword, different equations are specified for @{const
blanchet@54887
  2166
cont} depending on which constructor is selected.
blanchet@54887
  2167
blanchet@54887
  2168
Here are more examples to conclude:
blanchet@54812
  2169
*}
blanchet@54812
  2170
blanchet@54963
  2171
    primcorec
blanchet@54781
  2172
      even_infty :: even_enat and
blanchet@54781
  2173
      odd_infty :: odd_enat
blanchet@54781
  2174
    where
blanchet@54781
  2175
      "\<not> is_Even_EZero even_infty" |
blanchet@54781
  2176
      "un_Even_ESuc even_infty = odd_infty" |
blanchet@54781
  2177
      "un_Odd_ESuc odd_infty = even_infty"
blanchet@54886
  2178
blanchet@54889
  2179
text {* \blankline *}
blanchet@54889
  2180
blanchet@54963
  2181
    primcorec iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where
blanchet@55524
  2182
      "lbl\<^sub>i\<^sub>i (iterate\<^sub>i\<^sub>i g x) = x" |
blanchet@55524
  2183
      "sub\<^sub>i\<^sub>i (iterate\<^sub>i\<^sub>i g x) = lmap (iterate\<^sub>i\<^sub>i g) (g x)"
blanchet@54781
  2184
(*<*)
blanchet@54781
  2185
    end
blanchet@54781
  2186
(*>*)
blanchet@54781
  2187
blanchet@54887
  2188
blanchet@54754
  2189
subsection {* Command Syntax
blanchet@54754
  2190
  \label{ssec:primcorec-command-syntax} *}
blanchet@54754
  2191
blanchet@54754
  2192
blanchet@54963
  2193
subsubsection {* \keyw{primcorec} and \keyw{primcorecursive}
blanchet@54890
  2194
  \label{sssec:primcorecursive-and-primcorec} *}
blanchet@53961
  2195
blanchet@53977
  2196
text {*
blanchet@54966
  2197
\begin{matharray}{rcl}
blanchet@54966
  2198
  @{command_def "primcorec"} & : & @{text "local_theory \<rightarrow> local_theory"} \\
blanchet@54966
  2199
  @{command_def "primcorecursive"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
blanchet@54966
  2200
\end{matharray}
blanchet@53961
  2201
blanchet@53977
  2202
@{rail "
blanchet@54966
  2203
  (@@{command primcorec} | @@{command primcorecursive}) target? \\ @{syntax pcr_option}? fixes @'where'
blanchet@54886
  2204
    (@{syntax pcr_formula} + '|')
blanchet@53977
  2205
  ;
blanchet@54965
  2206
  @{syntax_def pcr_option}: '(' ('sequential' | 'exhaustive') ')'
blanchet@54886
  2207
  ;
blanchet@54886
  2208
  @{syntax_def pcr_formula}: thmdecl? prop (@'of' (term * ))?
blanchet@53977
  2209
"}
blanchet@54886
  2210
blanchet@54886
  2211
The optional target is optionally followed by a corecursion-specific option:
blanchet@54886
  2212
blanchet@54886
  2213
\begin{itemize}
blanchet@54886
  2214
\setlength{\itemsep}{0pt}
blanchet@54886
  2215
blanchet@54886
  2216
\item
blanchet@54886
  2217
The @{text "sequential"} option indicates that the conditions in specifications
blanchet@54886
  2218
expressed using the constructor or destructor view are to be interpreted
blanchet@54886
  2219
sequentially.
blanchet@54963
  2220
blanchet@54963
  2221
\item
blanchet@54963
  2222
The @{text "exhaustive"} option indicates that the conditions in specifications
blanchet@54963
  2223
expressed using the constructor or destructor view cover all possible cases.
blanchet@54886
  2224
\end{itemize}
blanchet@54886
  2225
blanchet@54963
  2226
\noindent
blanchet@54963
  2227
The @{command primcorec} command is an abbreviation for @{command primcorecursive} with
blanchet@54963
  2228
@{text "by auto?"} to discharge any emerging proof obligations.
blanchet@53977
  2229
*}
blanchet@53977
  2230
blanchet@53977
  2231
blanchet@54756
  2232
(*
blanchet@53977
  2233
subsection {* Generated Theorems
blanchet@53977
  2234
  \label{ssec:primcorec-generated-theorems} *}
blanchet@54756
  2235
*)
blanchet@53931
  2236
blanchet@53931
  2237
blanchet@54760
  2238
(*
blanchet@54760
  2239
subsection {* Recursive Default Values for Selectors
blanchet@54760
  2240
  \label{ssec:primcorec-recursive-default-values-for-selectors} *}
blanchet@54760
  2241
blanchet@54760
  2242
text {*
blanchet@54760
  2243
partial_function to the rescue
blanchet@54760
  2244
*}
blanchet@54760
  2245
*)
blanchet@54760
  2246
blanchet@54760
  2247
blanchet@53964
  2248
section {* Registering Bounded Natural Functors
blanchet@53942
  2249
  \label{sec:registering-bounded-natural-functors} *}
blanchet@53931
  2250
blanchet@53942
  2251
text {*
blanchet@54784
  2252
The (co)datatype package can be set up to allow nested recursion through
blanchet@54784
  2253
arbitrary type constructors, as long as they adhere to the BNF requirements and
blanchet@54784
  2254
are registered as BNFs.
blanchet@53942
  2255
*}
blanchet@53942
  2256
blanchet@53961
  2257
blanchet@54756
  2258
(*
blanchet@54754
  2259
subsection {* Introductory Example
blanchet@54754
  2260
  \label{ssec:bnf-introductory-example} *}
blanchet@53942
  2261
blanchet@53942
  2262
text {*
blanchet@53942
  2263
More examples in \verb|~~/src/HOL/BNF/Basic_BNFs.thy| and
blanchet@53942
  2264
\verb|~~/src/HOL/BNF/More_BNFs.thy|.
blanchet@53943
  2265
blanchet@54754
  2266
%Mention distinction between live and dead type arguments;
blanchet@54754
  2267
%  * and existence of map, set for those
blanchet@54754
  2268
%mention =>.
blanchet@53942
  2269
*}
blanchet@54756
  2270
*)
blanchet@53942
  2271
blanchet@53961
  2272
blanchet@54754
  2273
subsection {* Command Syntax
blanchet@54754
  2274
  \label{ssec:bnf-command-syntax} *}
blanchet@54754
  2275
blanchet@54754
  2276
blanchet@54758
  2277
subsubsection {* \keyw{bnf}
blanchet@54758
  2278
  \label{sssec:bnf} *}
blanchet@53942
  2279
blanchet@54165
  2280
text {*
blanchet@54966
  2281
\begin{matharray}{rcl}
blanchet@54966
  2282
  @{command_def "bnf"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
blanchet@54966
  2283
\end{matharray}
blanchet@54966
  2284
blanchet@54165
  2285
@{rail "
traytel@55794
  2286
  @@{command bnf} target? (name ':')? typ \\
traytel@55794
  2287
    'map:' term ('sets:' (term +))? 'bd:' term \\
traytel@55794
  2288
    ('wits:' (term +))? ('rel:' term)?
blanchet@54165
  2289
"}
blanchet@54165
  2290
*}
blanchet@53942
  2291
blanchet@54754
  2292
blanchet@55639
  2293
subsubsection {* \keyw{bnf\_decl}
blanchet@55639
  2294
  \label{sssec:bnf-decl} *}
blanchet@55639
  2295
blanchet@55639
  2296
text {*
blanchet@55639
  2297
%%% TODO: use command_def once the command is available
blanchet@55639
  2298
\begin{matharray}{rcl}
blanchet@55639
  2299
  @{text "bnf_decl"} & : & @{text "local_theory \<rightarrow> local_theory"}
blanchet@55639
  2300
\end{matharray}
blanchet@55639
  2301
blanchet@55639
  2302
@{rail "
traytel@55975
  2303
  @@{command bnf_decl} target? @{syntax dt_name}
traytel@55975
  2304
  ;
traytel@55975
  2305
  @{syntax_def dt_name}: @{syntax tyargs}? name @{syntax map_rel}? mixfix?
traytel@55975
  2306
  ;
traytel@55975
  2307
  @{syntax_def tyargs}: typefree | '(' (((name | '-') ':')? typefree + ',') ')'
traytel@55975
  2308
  ;
traytel@55975
  2309
  @{syntax_def map_rel}: '(' ((('map' | 'rel') ':' name) +) ')'
blanchet@55639
  2310
"}
traytel@55975
  2311
traytel@55975
  2312
Declares a fresh type and fresh constants (map, set, relator, cardinal bound)
traytel@55975
  2313
and asserts the bnf properties for these constants as axioms. Additionally,
traytel@55975
  2314
type arguments may be marked as dead (by using @{syntax "-"} instead of a name for the
traytel@55975
  2315
set function)---this is the only difference of @{syntax dt_name} compared to
traytel@55975
  2316
the syntax used by the @{command datatype_new}/@{command codatatype} commands.
traytel@55975
  2317
traytel@55975
  2318
The axioms are sound, since one there exists a bnf of any given arity.
blanchet@55639
  2319
*}
blanchet@55639
  2320
blanchet@55639
  2321
blanchet@54758
  2322
subsubsection {* \keyw{print\_bnfs}
blanchet@54758
  2323
  \label{sssec:print-bnfs} *}
blanchet@54754
  2324
blanchet@54754
  2325
text {*
blanchet@54966
  2326
\begin{matharray}{rcl}
blanchet@54966
  2327
  @{command_def "print_bnfs"} & : & @{text "local_theory \<rightarrow>"}
blanchet@54966
  2328
\end{matharray}
blanchet@54966
  2329
blanchet@54784
  2330
@{rail "
blanchet@54966
  2331
  @@{command print_bnfs}
blanchet@54784
  2332
"}
blanchet@54754
  2333
*}
blanchet@54754
  2334
blanchet@54754
  2335
blanchet@54754
  2336
section {* Deriving Destructors and Theorems for Free Constructors
blanchet@54754
  2337
  \label{sec:deriving-destructors-and-theorems-for-free-constructors} *}
blanchet@53942
  2338
blanchet@53942
  2339
text {*
blanchet@54760
  2340
The derivation of convenience theorems for types equipped with free constructors,
blanchet@54966
  2341
as performed internally by @{command datatype_new} and @{command codatatype},
blanchet@54760
  2342
is available as a stand-alone command called @{command wrap_free_constructors}.
blanchet@53942
  2343
blanchet@54754
  2344
%  * need for this is rare but may arise if you want e.g. to add destructors to
blanchet@54754
  2345
%    a type not introduced by ...
blanchet@54754
  2346
%
blanchet@54754
  2347
%  * also useful for compatibility with old package, e.g. add destructors to
blanchet@54754
  2348
%    old \keyw{datatype}
blanchet@54754
  2349
%
blanchet@54754
  2350
%  * @{command wrap_free_constructors}
blanchet@54760
  2351
%    * @{text "no_discs_sels"}, @{text "rep_compat"}
blanchet@54754
  2352
%    * hack to have both co and nonco view via locale (cf. ext nats)
blanchet@55989
  2353
%  * code generator
blanchet@55989
  2354
%     * eq, refl, simps
blanchet@53942
  2355
*}
blanchet@53929
  2356
blanchet@53961
  2357
blanchet@54756
  2358
(*
blanchet@54754
  2359
subsection {* Introductory Example
blanchet@54754
  2360
  \label{ssec:ctors-introductory-example} *}
blanchet@54756
  2361
*)
blanchet@53931
  2362
blanchet@53961
  2363
blanchet@54754
  2364
subsection {* Command Syntax
blanchet@54754
  2365
  \label{ssec:ctors-command-syntax} *}
blanchet@54754
  2366
blanchet@54754
  2367
blanchet@54758
  2368
subsubsection {* \keyw{wrap\_free\_constructors}
blanchet@54812
  2369
  \label{sssec:wrap-free-constructors} *}
blanchet@53965
  2370
blanchet@54155
  2371
text {*
blanchet@54966
  2372
\begin{matharray}{rcl}
blanchet@54966
  2373
  @{command_def "wrap_free_constructors"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
blanchet@54966
  2374
\end{matharray}
blanchet@54155
  2375
blanchet@54155
  2376
@{rail "
blanchet@54966
  2377
  @@{command wrap_free_constructors} target? @{syntax dt_options} \\
blanchet@55000
  2378
    term_list name @{syntax wfc_discs_sels}?
blanchet@54155
  2379
  ;
blanchet@55000
  2380
  @{syntax_def wfc_discs_sels}: name_list (name_list_list name_term_list_list? )?
blanchet@54155
  2381
  ;
blanchet@54671
  2382
  @{syntax_def name_term}: (name ':' term)
traytel@55794
  2383
  ;
traytel@55794
  2384
  X_list: '[' (X + ',') ']'
blanchet@54155
  2385
"}
blanchet@54155
  2386
blanchet@54754
  2387
% options: no_discs_sels rep_compat
blanchet@54165
  2388
blanchet@54966
  2389
\noindent
blanchet@54679
  2390
Section~\ref{ssec:datatype-generated-theorems} lists the generated theorems.
blanchet@54155
  2391
*}
blanchet@53965
  2392
blanchet@53931
  2393
blanchet@54754
  2394
(*
blanchet@53964
  2395
section {* Standard ML Interface
blanchet@53942
  2396
  \label{sec:standard-ml-interface} *}
blanchet@53929
  2397
blanchet@53942
  2398
text {*
blanchet@54760
  2399
The package's programmatic interface.
blanchet@53942
  2400
*}
blanchet@54754
  2401
*)
blanchet@53931
  2402
blanchet@53931
  2403
blanchet@54754
  2404
(*
blanchet@53964
  2405
section {* Interoperability
blanchet@53942
  2406
  \label{sec:interoperability} *}
blanchet@53931
  2407
blanchet@53942
  2408
text {*
blanchet@54760
  2409
The package's interaction with other Isabelle packages and tools, such as the
blanchet@54760
  2410
code generator and the counterexample generators.
blanchet@53942
  2411
*}
blanchet@53931
  2412
blanchet@53961
  2413
blanchet@53965
  2414
subsection {* Transfer and Lifting
blanchet@53965
  2415
  \label{ssec:transfer-and-lifting} *}
blanchet@53931
  2416
blanchet@53961
  2417
blanchet@53965
  2418
subsection {* Code Generator
blanchet@53965
  2419
  \label{ssec:code-generator} *}
blanchet@53931
  2420
blanchet@53961
  2421
blanchet@53965
  2422
subsection {* Quickcheck
blanchet@53965
  2423
  \label{ssec:quickcheck} *}
blanchet@53931
  2424
blanchet@53961
  2425
blanchet@53965
  2426
subsection {* Nitpick
blanchet@53965
  2427
  \label{ssec:nitpick} *}
blanchet@53931
  2428
blanchet@53961
  2429
blanchet@53965
  2430
subsection {* Nominal Isabelle
blanchet@53965
  2431
  \label{ssec:nominal-isabelle} *}
blanchet@54754
  2432
*)
blanchet@53931
  2433
blanchet@53942
  2434
blanchet@54754
  2435
(*
blanchet@53964
  2436
section {* Known Bugs and Limitations
blanchet@53942
  2437
  \label{sec:known-bugs-and-limitations} *}
blanchet@53942
  2438
blanchet@53942
  2439
text {*
blanchet@54760
  2440
Known open issues of the package.
blanchet@53942
  2441
*}
blanchet@53931
  2442
blanchet@53931
  2443
text {*
blanchet@54890
  2444
%* primcorecursive and primcorec is unfinished
blanchet@54754
  2445
%
blanchet@54754
  2446
%* slow n-ary mutual (co)datatype, avoid as much as possible (e.g. using nesting)
blanchet@54754
  2447
%
blanchet@54754
  2448
%* issues with HOL-Proofs?
blanchet@54754
  2449
%
blanchet@54754
  2450
%* partial documentation
blanchet@54754
  2451
%
blanchet@54754
  2452
%* no way to register "sum" and "prod" as (co)datatypes to enable N2M reduction for them
blanchet@54754
  2453
%  (for @{command datatype_new_compat} and prim(co)rec)
blanchet@54754
  2454
%
blanchet@54756
  2455
%    * a fortiori, no way to register same type as both data- and codatatype
blanchet@54754
  2456
%
blanchet@54754
  2457
%* no recursion through unused arguments (unlike with the old package)
blanchet@54754
  2458
%
blanchet@54754
  2459
%* in a locale, cannot use locally fixed types (because of limitation in typedef)?
blanchet@54756
  2460
%
blanchet@54756
  2461
% *names of variables suboptimal
blanchet@53959
  2462
*}
blanchet@54812
  2463
*)
blanchet@53959
  2464
blanchet@53959
  2465
blanchet@53959
  2466
text {*
blanchet@55000
  2467
\section*{Acknowledgment}
blanchet@55000
  2468
blanchet@54886
  2469
Tobias Nipkow and Makarius Wenzel encouraged us to implement the new
blanchet@54754
  2470
(co)datatype package. Andreas Lochbihler provided lots of comments on earlier
blanchet@54754
  2471
versions of the package, especially for the coinductive part. Brian Huffman
blanchet@54754
  2472
suggested major simplifications to the internal constructions, much of which has
blanchet@54754
  2473
yet to be implemented. Florian Haftmann and Christian Urban provided general
blanchet@54812
  2474
advice on Isabelle and package writing. Stefan Milius and Lutz Schr\"oder
blanchet@55598
  2475
found an elegant proof to eliminate one of the BNF assumptions. Andreas
blanchet@55598
  2476
Lochbihler and Christian Sternagel suggested many textual improvements to this
blanchet@55598
  2477
tutorial.
blanchet@53931
  2478
*}
blanchet@54754
  2479
blanchet@53929
  2480
end