| author | wenzelm | 
| Mon, 15 Feb 2016 14:55:44 +0100 | |
| changeset 62337 | d3996d5873dd | 
| parent 62093 | bd73a2279fcd | 
| child 62317 | e1698a9578ea | 
| permissions | -rw-r--r-- | 
| 52792 | 1 | (* Title: Doc/Datatypes/Datatypes.thy | 
| 61303 | 2 | Author: Julian Biendarra, TU Muenchen | 
| 52792 | 3 | Author: Jasmin Blanchette, TU Muenchen | 
| 57079 | 4 | Author: Martin Desharnais, Ecole de technologie superieure | 
| 53617 | 5 | Author: Lorenz Panny, TU Muenchen | 
| 6 | Author: Andrei Popescu, TU Muenchen | |
| 7 | Author: Dmitriy Traytel, TU Muenchen | |
| 52792 | 8 | |
| 58305 
57752a91eec4
renamed 'datatype' to 'old_datatype'; 'datatype' is now alias for 'datatype_new'
 blanchet parents: 
58298diff
changeset | 9 | Tutorial for (co)datatype definitions. | 
| 52792 | 10 | *) | 
| 11 | ||
| 12 | theory Datatypes | |
| 55073 | 13 | imports | 
| 14 | Setup | |
| 56942 | 15 | "~~/src/HOL/Library/BNF_Axiomatization" | 
| 55350 | 16 | "~~/src/HOL/Library/Cardinal_Notations" | 
| 62081 | 17 | "~~/src/HOL/Library/Countable" | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
55114diff
changeset | 18 | "~~/src/HOL/Library/FSet" | 
| 55073 | 19 | "~~/src/HOL/Library/Simps_Case_Conv" | 
| 52792 | 20 | begin | 
| 21 | ||
| 62081 | 22 | section \<open> Introduction | 
| 23 |   \label{sec:introduction} \<close>
 | |
| 24 | ||
| 25 | text \<open> | |
| 58305 
57752a91eec4
renamed 'datatype' to 'old_datatype'; 'datatype' is now alias for 'datatype_new'
 blanchet parents: 
58298diff
changeset | 26 | The 2013 edition of Isabelle introduced a definitional package for freely | 
| 
57752a91eec4
renamed 'datatype' to 'old_datatype'; 'datatype' is now alias for 'datatype_new'
 blanchet parents: 
58298diff
changeset | 27 | generated datatypes and codatatypes. This package replaces the earlier | 
| 58620 | 28 | implementation due to Berghofer and Wenzel @{cite "Berghofer-Wenzel:1999:TPHOL"}.
 | 
| 52841 | 29 | Perhaps the main advantage of the new package is that it supports recursion | 
| 53619 | 30 | through a large class of non-datatypes, such as finite sets: | 
| 62081 | 31 | \<close> | 
| 52792 | 32 | |
| 58310 | 33 | datatype '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") | 
| 52792 | 34 | |
| 62081 | 35 | text \<open> | 
| 52794 | 36 | \noindent | 
| 53025 | 37 | Another strong point is the support for local definitions: | 
| 62081 | 38 | \<close> | 
| 52792 | 39 | |
| 52805 | 40 | context linorder | 
| 41 | begin | |
| 58310 | 42 | datatype flag = Less | Eq | Greater | 
| 52805 | 43 | end | 
| 52792 | 44 | |
| 62081 | 45 | text \<open> | 
| 52794 | 46 | \noindent | 
| 54187 | 47 | Furthermore, the package provides a lot of convenience, including automatically | 
| 48 | generated discriminators, selectors, and relators as well as a wealth of | |
| 49 | properties about them. | |
| 50 | ||
| 58305 
57752a91eec4
renamed 'datatype' to 'old_datatype'; 'datatype' is now alias for 'datatype_new'
 blanchet parents: 
58298diff
changeset | 51 | In addition to inductive datatypes, the package supports coinductive | 
| 54187 | 52 | datatypes, or \emph{codatatypes}, which allow infinite values. For example, the
 | 
| 53 | following command introduces the type of lazy lists, which comprises both finite | |
| 54 | and infinite values: | |
| 62081 | 55 | \<close> | 
| 52794 | 56 | |
| 53623 | 57 | (*<*) | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 58 | locale early | 
| 54072 | 59 | locale late | 
| 53623 | 60 | (*>*) | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 61 | codatatype (*<*)(in early) (*>*)'a llist = LNil | LCons 'a "'a llist" | 
| 52794 | 62 | |
| 62081 | 63 | text \<open> | 
| 52794 | 64 | \noindent | 
| 52840 | 65 | Mixed inductive--coinductive recursion is possible via nesting. Compare the | 
| 53028 | 66 | following four Rose tree examples: | 
| 62081 | 67 | \<close> | 
| 52794 | 68 | |
| 58310 | 69 | datatype (*<*)(in early) (*>*)'a tree\<^sub>f\<^sub>f = Node\<^sub>f\<^sub>f 'a "'a tree\<^sub>f\<^sub>f list" | 
| 70 | datatype (*<*)(in early) (*>*)'a tree\<^sub>f\<^sub>i = Node\<^sub>f\<^sub>i 'a "'a tree\<^sub>f\<^sub>i llist" | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 71 | codatatype (*<*)(in early) (*>*)'a tree\<^sub>i\<^sub>f = Node\<^sub>i\<^sub>f 'a "'a tree\<^sub>i\<^sub>f list" | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 72 | codatatype (*<*)(in early) (*>*)'a tree\<^sub>i\<^sub>i = Node\<^sub>i\<^sub>i 'a "'a tree\<^sub>i\<^sub>i llist" | 
| 52792 | 73 | |
| 62081 | 74 | text \<open> | 
| 54187 | 75 | The first two tree types allow only paths of finite length, whereas the last two | 
| 76 | allow infinite paths. Orthogonally, the nodes in the first and third types have | |
| 77 | finitely many direct subtrees, whereas those of the second and fourth may have | |
| 78 | infinite branching. | |
| 52840 | 79 | |
| 55073 | 80 | The package is part of @{theory Main}. Additional functionality is provided by
 | 
| 61304 | 81 | the theory @{file "~~/src/HOL/Library/BNF_Axiomatization.thy"}.
 | 
| 55073 | 82 | |
| 52805 | 83 | The package, like its predecessor, fully adheres to the LCF philosophy | 
| 58620 | 84 | @{cite mgordon79}: The characteristic theorems associated with the specified
 | 
| 52805 | 85 | (co)datatypes are derived rather than introduced axiomatically.% | 
| 57542 | 86 | \footnote{However, some of the
 | 
| 58298 | 87 | internal constructions and most of the internal proof obligations are omitted | 
| 57542 | 88 | if the @{text quick_and_dirty} option is enabled.}
 | 
| 57575 | 89 | The package is described in a number of papers | 
| 60146 | 90 | @{cite "traytel-et-al-2012" and "blanchette-et-al-2014-impl" and
 | 
| 91 | "panny-et-al-2014" and "blanchette-et-al-2015-wit"}. | |
| 57542 | 92 | The central notion is that of a \emph{bounded natural functor} (BNF)---a
 | 
| 93 | well-behaved type constructor for which nested (co)recursion is supported. | |
| 52792 | 94 | |
| 52794 | 95 | This tutorial is organized as follows: | 
| 96 | ||
| 52805 | 97 | \begin{itemize}
 | 
| 52822 | 98 | \setlength{\itemsep}{0pt}
 | 
| 99 | ||
| 52805 | 100 | \item Section \ref{sec:defining-datatypes}, ``Defining Datatypes,''
 | 
| 58310 | 101 | describes how to specify datatypes using the @{command datatype} command.
 | 
| 52805 | 102 | |
| 59861 | 103 | \item Section \ref{sec:defining-primitively-recursive-functions}, ``Defining
 | 
| 60192 | 104 | Primitively Recursive Functions,'' describes how to specify functions | 
| 59861 | 105 | using @{command primrec}. (A separate tutorial @{cite "isabelle-function"}
 | 
| 106 | describes the more general \keyw{fun} and \keyw{function} commands.)
 | |
| 52805 | 107 | |
| 108 | \item Section \ref{sec:defining-codatatypes}, ``Defining Codatatypes,''
 | |
| 53829 | 109 | describes how to specify codatatypes using the @{command codatatype} command.
 | 
| 52805 | 110 | |
| 59861 | 111 | \item Section \ref{sec:defining-primitively-corecursive-functions},
 | 
| 112 | ``Defining Primitively Corecursive Functions,'' describes how to specify | |
| 60192 | 113 | functions using the @{command primcorec} and
 | 
| 59861 | 114 | @{command primcorecursive} commands.
 | 
| 52794 | 115 | |
| 59298 | 116 | \item Section \ref{sec:registering-bounded-natural-functors}, ``Registering
 | 
| 53552 | 117 | Bounded Natural Functors,'' explains how to use the @{command bnf} command
 | 
| 118 | to register arbitrary type constructors as BNFs. | |
| 52805 | 119 | |
| 53552 | 120 | \item Section | 
| 53617 | 121 | \ref{sec:deriving-destructors-and-theorems-for-free-constructors},
 | 
| 122 | ``Deriving Destructors and Theorems for Free Constructors,'' explains how to | |
| 55468 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 123 | use the command @{command free_constructors} to derive destructor constants
 | 
| 58311 | 124 | and theorems for freely generated types, as performed internally by | 
| 125 | @{command datatype} and @{command codatatype}.
 | |
| 52794 | 126 | |
| 58245 | 127 | %\item Section \ref{sec:using-the-standard-ml-interface}, ``Using the Standard
 | 
| 60192 | 128 | %ML Interface,'' describes the package's programmatic interface. | 
| 58245 | 129 | |
| 59282 | 130 | \item Section \ref{sec:selecting-plugins}, ``Selecting Plugins,'' is concerned
 | 
| 131 | with the package's interoperability with other Isabelle packages and tools, such | |
| 132 | as the code generator, Transfer, Lifting, and Quickcheck. | |
| 52805 | 133 | |
| 58395 | 134 | \item Section \ref{sec:known-bugs-and-limitations}, ``Known Bugs and
 | 
| 135 | Limitations,'' concludes with known open issues at the time of writing. | |
| 52805 | 136 | \end{itemize}
 | 
| 52822 | 137 | |
| 138 | \newbox\boxA | |
| 54185 | 139 | \setbox\boxA=\hbox{\texttt{NOSPAM}}
 | 
| 140 | ||
| 141 | \newcommand\authoremaili{\texttt{blan{\color{white}NOSPAM}\kern-\wd\boxA{}chette@\allowbreak
 | |
| 52822 | 142 | in.\allowbreak tum.\allowbreak de}} | 
| 143 | ||
| 58305 
57752a91eec4
renamed 'datatype' to 'old_datatype'; 'datatype' is now alias for 'datatype_new'
 blanchet parents: 
58298diff
changeset | 144 | Comments and bug reports concerning either the package or this tutorial should | 
| 61788 | 145 | be directed to the first author at \authoremaili{} or to the
 | 
| 60146 | 146 | \texttt{cl-isabelle-users} mailing list.
 | 
| 62081 | 147 | \<close> | 
| 148 | ||
| 149 | ||
| 150 | section \<open> Defining Datatypes | |
| 151 |   \label{sec:defining-datatypes} \<close>
 | |
| 152 | ||
| 153 | text \<open> | |
| 58310 | 154 | Datatypes can be specified using the @{command datatype} command.
 | 
| 62081 | 155 | \<close> | 
| 156 | ||
| 157 | ||
| 158 | subsection \<open> Introductory Examples | |
| 159 |   \label{ssec:datatype-introductory-examples} \<close>
 | |
| 160 | ||
| 161 | text \<open> | |
| 53646 | 162 | Datatypes are illustrated through concrete examples featuring different flavors | 
| 163 | of recursion. More examples can be found in the directory | |
| 61304 | 164 | @{file "~~/src/HOL/Datatype_Examples"}
 | 
| 62081 | 165 | \<close> | 
| 166 | ||
| 167 | ||
| 168 | subsubsection \<open> Nonrecursive Types | |
| 169 |   \label{sssec:datatype-nonrecursive-types} \<close>
 | |
| 170 | ||
| 171 | text \<open> | |
| 53028 | 172 | Datatypes are introduced by specifying the desired names and argument types for | 
| 53491 | 173 | their constructors. \emph{Enumeration} types are the simplest form of datatype.
 | 
| 53028 | 174 | All their constructors are nullary: | 
| 62081 | 175 | \<close> | 
| 52805 | 176 | |
| 58310 | 177 | datatype trool = Truue | Faalse | Perhaaps | 
| 52805 | 178 | |
| 62081 | 179 | text \<open> | 
| 53028 | 180 | \noindent | 
| 59282 | 181 | @{const Truue}, @{const Faalse}, and @{const Perhaaps} have the type @{typ trool}.
 | 
| 53028 | 182 | |
| 183 | Polymorphic types are possible, such as the following option type, modeled after | |
| 184 | its homologue from the @{theory Option} theory:
 | |
| 62081 | 185 | \<close> | 
| 52805 | 186 | |
| 53025 | 187 | (*<*) | 
| 56995 | 188 | hide_const None Some map_option | 
| 54958 
4933165fd112
do not use wrong constructor in auto-generated proof goal
 panny parents: 
54955diff
changeset | 189 | hide_type option | 
| 53025 | 190 | (*>*) | 
| 58310 | 191 | datatype 'a option = None | Some 'a | 
| 52805 | 192 | |
| 62081 | 193 | text \<open> | 
| 53028 | 194 | \noindent | 
| 61076 | 195 | The constructors are @{text "None :: 'a option"} and
 | 
| 196 | @{text "Some :: 'a \<Rightarrow> 'a option"}.
 | |
| 53028 | 197 | |
| 198 | The next example has three type parameters: | |
| 62081 | 199 | \<close> | 
| 52805 | 200 | |
| 58310 | 201 |     datatype ('a, 'b, 'c) triple = Triple 'a 'b 'c
 | 
| 52805 | 202 | |
| 62081 | 203 | text \<open> | 
| 53028 | 204 | \noindent | 
| 205 | The constructor is | |
| 61076 | 206 | @{text "Triple :: 'a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> ('a, 'b, 'c) triple"}.
 | 
| 53028 | 207 | Unlike in Standard ML, curried constructors are supported. The uncurried variant | 
| 208 | is also possible: | |
| 62081 | 209 | \<close> | 
| 53028 | 210 | |
| 58310 | 211 |     datatype ('a, 'b, 'c) triple\<^sub>u = Triple\<^sub>u "'a * 'b * 'c"
 | 
| 53028 | 212 | |
| 62081 | 213 | text \<open> | 
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 214 | \noindent | 
| 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 215 | Occurrences of nonatomic types on the right-hand side of the equal sign must be | 
| 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 216 | enclosed in double quotes, as is customary in Isabelle. | 
| 62081 | 217 | \<close> | 
| 218 | ||
| 219 | ||
| 220 | subsubsection \<open> Simple Recursion | |
| 221 |   \label{sssec:datatype-simple-recursion} \<close>
 | |
| 222 | ||
| 223 | text \<open> | |
| 53491 | 224 | Natural numbers are the simplest example of a recursive type: | 
| 62081 | 225 | \<close> | 
| 52805 | 226 | |
| 58310 | 227 | datatype nat = Zero | Succ nat | 
| 52805 | 228 | |
| 62081 | 229 | text \<open> | 
| 53491 | 230 | \noindent | 
| 54187 | 231 | Lists were shown in the introduction. Terminated lists are a variant that | 
| 232 | stores a value of type @{typ 'b} at the very end:
 | |
| 62081 | 233 | \<close> | 
| 52805 | 234 | |
| 58310 | 235 |     datatype (*<*)(in early) (*>*)('a, 'b) tlist = TNil 'b | TCons 'a "('a, 'b) tlist"
 | 
| 52805 | 236 | |
| 52824 | 237 | |
| 62081 | 238 | subsubsection \<open> Mutual Recursion | 
| 239 |   \label{sssec:datatype-mutual-recursion} \<close>
 | |
| 240 | ||
| 241 | text \<open> | |
| 53552 | 242 | \emph{Mutually recursive} types are introduced simultaneously and may refer to
 | 
| 243 | each other. The example below introduces a pair of types for even and odd | |
| 244 | natural numbers: | |
| 62081 | 245 | \<close> | 
| 52805 | 246 | |
| 58310 | 247 | datatype even_nat = Even_Zero | Even_Succ odd_nat | 
| 58245 | 248 | and odd_nat = Odd_Succ even_nat | 
| 52805 | 249 | |
| 62081 | 250 | text \<open> | 
| 53491 | 251 | \noindent | 
| 252 | Arithmetic expressions are defined via terms, terms via factors, and factors via | |
| 253 | expressions: | |
| 62081 | 254 | \<close> | 
| 52805 | 255 | |
| 58310 | 256 |     datatype ('a, 'b) exp =
 | 
| 52841 | 257 |       Term "('a, 'b) trm" | Sum "('a, 'b) trm" "('a, 'b) exp"
 | 
| 52805 | 258 |     and ('a, 'b) trm =
 | 
| 52841 | 259 |       Factor "('a, 'b) fct" | Prod "('a, 'b) fct" "('a, 'b) trm"
 | 
| 260 |     and ('a, 'b) fct =
 | |
| 261 |       Const 'a | Var 'b | Expr "('a, 'b) exp"
 | |
| 52805 | 262 | |
| 52824 | 263 | |
| 62081 | 264 | subsubsection \<open> Nested Recursion | 
| 265 |   \label{sssec:datatype-nested-recursion} \<close>
 | |
| 266 | ||
| 267 | text \<open> | |
| 53491 | 268 | \emph{Nested recursion} occurs when recursive occurrences of a type appear under
 | 
| 269 | a type constructor. The introduction showed some examples of trees with nesting | |
| 53675 | 270 | through lists. A more complex example, that reuses our @{type option} type,
 | 
| 53491 | 271 | follows: | 
| 62081 | 272 | \<close> | 
| 52805 | 273 | |
| 58310 | 274 | datatype 'a btree = | 
| 53025 | 275 | BNode 'a "'a btree option" "'a btree option" | 
| 52805 | 276 | |
| 62081 | 277 | text \<open> | 
| 53491 | 278 | \noindent | 
| 279 | Not all nestings are admissible. For example, this command will fail: | |
| 62081 | 280 | \<close> | 
| 52805 | 281 | |
| 58310 | 282 | datatype 'a wrong = W1 | W2 (*<*)'a | 
| 53542 | 283 | typ (*>*)"'a wrong \<Rightarrow> 'a" | 
| 52806 | 284 | |
| 62081 | 285 | text \<open> | 
| 53491 | 286 | \noindent | 
| 287 | The issue is that the function arrow @{text "\<Rightarrow>"} allows recursion
 | |
| 288 | only through its right-hand side. This issue is inherited by polymorphic | |
| 289 | datatypes defined in terms of~@{text "\<Rightarrow>"}:
 | |
| 62081 | 290 | \<close> | 
| 53491 | 291 | |
| 58310 | 292 |     datatype ('a, 'b) fun_copy = Fun "'a \<Rightarrow> 'b"
 | 
| 293 | datatype 'a also_wrong = W1 | W2 (*<*)'a | |
| 55350 | 294 |     typ (*>*)"('a also_wrong, 'a) fun_copy"
 | 
| 53491 | 295 | |
| 62081 | 296 | text \<open> | 
| 53491 | 297 | \noindent | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
55114diff
changeset | 298 | The following definition of @{typ 'a}-branching trees is legal:
 | 
| 62081 | 299 | \<close> | 
| 53621 | 300 | |
| 58310 | 301 | datatype 'a ftree = FTLeaf 'a | FTNode "'a \<Rightarrow> 'a ftree" | 
| 53621 | 302 | |
| 62081 | 303 | text \<open> | 
| 53621 | 304 | \noindent | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
55114diff
changeset | 305 | And so is the definition of hereditarily finite sets: | 
| 62081 | 306 | \<close> | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
55114diff
changeset | 307 | |
| 58310 | 308 | datatype hfset = HFSet "hfset fset" | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
55114diff
changeset | 309 | |
| 62081 | 310 | text \<open> | 
| 55129 
26bd1cba3ab5
killed 'More_BNFs' by moving its various bits where they (now) belong
 blanchet parents: 
55114diff
changeset | 311 | \noindent | 
| 53491 | 312 | In general, type constructors @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"}
 | 
| 313 | allow recursion on a subset of their type arguments @{text 'a\<^sub>1}, \ldots,
 | |
| 314 | @{text 'a\<^sub>m}. These type arguments are called \emph{live}; the remaining
 | |
| 315 | type arguments are called \emph{dead}. In @{typ "'a \<Rightarrow> 'b"} and
 | |
| 55350 | 316 | @{typ "('a, 'b) fun_copy"}, the type variable @{typ 'a} is dead and
 | 
| 317 | @{typ 'b} is live.
 | |
| 53552 | 318 | |
| 53647 | 319 | Type constructors must be registered as BNFs to have live arguments. This is | 
| 58311 | 320 | done automatically for datatypes and codatatypes introduced by the | 
| 321 | @{command datatype} and @{command codatatype} commands.
 | |
| 59298 | 322 | Section~\ref{sec:registering-bounded-natural-functors} explains how to
 | 
| 55351 | 323 | register arbitrary type constructors as BNFs. | 
| 54187 | 324 | |
| 325 | Here is another example that fails: | |
| 62081 | 326 | \<close> | 
| 52806 | 327 | |
| 58310 | 328 | datatype 'a pow_list = PNil 'a (*<*)'a | 
| 329 |     datatype 'a pow_list' = PNil' 'a (*>*)| PCons "('a * 'a) pow_list"
 | |
| 54187 | 330 | |
| 62081 | 331 | text \<open> | 
| 54187 | 332 | \noindent | 
| 55351 | 333 | This attempted definition features a different flavor of nesting, where the | 
| 334 | recursive call in the type specification occurs around (rather than inside) | |
| 335 | another type constructor. | |
| 62081 | 336 | \<close> | 
| 337 | ||
| 338 | ||
| 339 | subsubsection \<open> Auxiliary Constants | |
| 340 |   \label{sssec:datatype-auxiliary-constants} \<close>
 | |
| 341 | ||
| 342 | text \<open> | |
| 58310 | 343 | The @{command datatype} command introduces various constants in addition to
 | 
| 53617 | 344 | the constructors. With each datatype are associated set functions, a map | 
| 345 | function, a relator, discriminators, and selectors, all of which can be given | |
| 54187 | 346 | custom names. In the example below, the familiar names @{text null}, @{text hd},
 | 
| 59284 | 347 | @{text tl}, @{text set}, @{text map}, and @{text list_all2} override the
 | 
| 54187 | 348 | default names @{text is_Nil}, @{text un_Cons1}, @{text un_Cons2},
 | 
| 54491 | 349 | @{text set_list}, @{text map_list}, and @{text rel_list}:
 | 
| 62081 | 350 | \<close> | 
| 52822 | 351 | |
| 52841 | 352 | (*<*) | 
| 353 | no_translations | |
| 354 | "[x, xs]" == "x # [xs]" | |
| 355 | "[x]" == "x # []" | |
| 356 | ||
| 357 | no_notation | |
| 358 |       Nil ("[]") and
 | |
| 359 | Cons (infixr "#" 65) | |
| 360 | ||
| 53543 | 361 | hide_type list | 
| 58245 | 362 | hide_const Nil Cons case_list hd tl set map list_all2 rec_list size_list pred_list | 
| 53025 | 363 | |
| 59284 | 364 | context early | 
| 365 | begin | |
| 52841 | 366 | (*>*) | 
| 58310 | 367 | datatype (set: 'a) list = | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 368 | null: Nil | 
| 53025 | 369 | | Cons (hd: 'a) (tl: "'a list") | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 370 | for | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 371 | map: map | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 372 | rel: list_all2 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 373 | where | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 374 | "tl Nil = Nil" | 
| 52822 | 375 | |
| 62081 | 376 | text \<open> | 
| 52822 | 377 | \noindent | 
| 55353 | 378 | The types of the constants that appear in the specification are listed below. | 
| 55351 | 379 | |
| 380 | \medskip | |
| 54187 | 381 | |
| 382 | \begin{tabular}{@ {}ll@ {}}
 | |
| 383 | Constructors: & | |
| 61076 | 384 |   @{text "Nil :: 'a list"} \\
 | 
| 54187 | 385 | & | 
| 61076 | 386 |   @{text "Cons :: 'a \<Rightarrow> 'a list \<Rightarrow> 'a list"} \\
 | 
| 54187 | 387 | Discriminator: & | 
| 61076 | 388 |   @{text "null :: 'a list \<Rightarrow> bool"} \\
 | 
| 54187 | 389 | Selectors: & | 
| 61076 | 390 |   @{text "hd :: 'a list \<Rightarrow> 'a"} \\
 | 
| 54187 | 391 | & | 
| 61076 | 392 |   @{text "tl :: 'a list \<Rightarrow> 'a list"} \\
 | 
| 54187 | 393 | Set function: & | 
| 61076 | 394 |   @{text "set :: 'a list \<Rightarrow> 'a set"} \\
 | 
| 54187 | 395 | Map function: & | 
| 61076 | 396 |   @{text "map :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a list \<Rightarrow> 'b list"} \\
 | 
| 54187 | 397 | Relator: & | 
| 61076 | 398 |   @{text "list_all2 :: ('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> bool"}
 | 
| 54187 | 399 | \end{tabular}
 | 
| 400 | ||
| 55351 | 401 | \medskip | 
| 402 | ||
| 54187 | 403 | The discriminator @{const null} and the selectors @{const hd} and @{const tl}
 | 
| 55351 | 404 | are characterized by the following conditional equations: | 
| 52822 | 405 | % | 
| 53025 | 406 | \[@{thm list.collapse(1)[of xs, no_vars]}
 | 
| 407 |   \qquad @{thm list.collapse(2)[of xs, no_vars]}\]
 | |
| 52822 | 408 | % | 
| 54187 | 409 | For two-constructor datatypes, a single discriminator constant is sufficient. | 
| 410 | The discriminator associated with @{const Cons} is simply
 | |
| 53491 | 411 | @{term "\<lambda>xs. \<not> null xs"}.
 | 
| 52822 | 412 | |
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 413 | The \keyw{where} clause at the end of the command specifies a default value for
 | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 414 | selectors applied to constructors on which they are not a priori specified. | 
| 59282 | 415 | In the example, it is used to ensure that the tail of the empty list is itself | 
| 416 | (instead of being left unspecified). | |
| 52822 | 417 | |
| 53617 | 418 | Because @{const Nil} is nullary, it is also possible to use
 | 
| 57091 | 419 | @{term "\<lambda>xs. xs = Nil"} as a discriminator. This is the default behavior
 | 
| 420 | if we omit the identifier @{const null} and the associated colon. Some users
 | |
| 421 | argue against this, because the mixture of constructors and selectors in the | |
| 422 | characteristic theorems can lead Isabelle's automation to switch between the | |
| 423 | constructor and the destructor view in surprising ways. | |
| 52822 | 424 | |
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 425 | The usual mixfix syntax annotations are available for both types and | 
| 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 426 | constructors. For example: | 
| 62081 | 427 | \<close> | 
| 52794 | 428 | |
| 53025 | 429 | (*<*) | 
| 430 | end | |
| 431 | (*>*) | |
| 58310 | 432 |     datatype ('a, 'b) prod (infixr "*" 20) = Pair 'a 'b
 | 
| 53552 | 433 | |
| 62081 | 434 | text \<open> \blankline \<close> | 
| 52822 | 435 | |
| 58310 | 436 | datatype (set: 'a) list = | 
| 52822 | 437 |       null: Nil ("[]")
 | 
| 52841 | 438 | | Cons (hd: 'a) (tl: "'a list") (infixr "#" 65) | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 439 | for | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 440 | map: map | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 441 | rel: list_all2 | 
| 52841 | 442 | |
| 62081 | 443 | text \<open> | 
| 53535 | 444 | \noindent | 
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 445 | Incidentally, this is how the traditional syntax can be set up: | 
| 62081 | 446 | \<close> | 
| 52841 | 447 | |
| 448 |     syntax "_list" :: "args \<Rightarrow> 'a list" ("[(_)]")
 | |
| 449 | ||
| 62081 | 450 | text \<open> \blankline \<close> | 
| 53552 | 451 | |
| 52841 | 452 | translations | 
| 453 | "[x, xs]" == "x # [xs]" | |
| 454 | "[x]" == "x # []" | |
| 52822 | 455 | |
| 52824 | 456 | |
| 62081 | 457 | subsection \<open> Command Syntax | 
| 458 |   \label{ssec:datatype-command-syntax} \<close>
 | |
| 459 | ||
| 460 | subsubsection \<open> \keyw{datatype}
 | |
| 461 |   \label{sssec:datatype-new} \<close>
 | |
| 462 | ||
| 463 | text \<open> | |
| 53829 | 464 | \begin{matharray}{rcl}
 | 
| 58310 | 465 |   @{command_def "datatype"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | 
| 53829 | 466 | \end{matharray}
 | 
| 52822 | 467 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 468 | @{rail \<open>
 | 
| 59282 | 469 |   @@{command datatype} target? @{syntax dt_options}? @{syntax dt_spec}
 | 
| 52828 | 470 | ; | 
| 59280 | 471 |   @{syntax_def dt_options}: '(' ((@{syntax plugins} | 'discs_sels') + ',') ')'
 | 
| 58190 | 472 | ; | 
| 59280 | 473 |   @{syntax_def plugins}: 'plugins' ('only' | 'del') ':' (name +)
 | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 474 | ; | 
| 59282 | 475 |   @{syntax_def dt_spec}: (@{syntax dt_name} '=' (@{syntax dt_ctor} + '|') \<newline>
 | 
| 476 |      @{syntax map_rel}? (@'where' (prop + '|'))? + @'and')
 | |
| 477 | ; | |
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 478 |   @{syntax_def map_rel}: @'for' ((('map' | 'rel') ':' name) +)
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 479 | \<close>} | 
| 52824 | 480 | |
| 55351 | 481 | \medskip | 
| 482 | ||
| 483 | \noindent | |
| 58310 | 484 | The @{command datatype} command introduces a set of mutually recursive
 | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 485 | datatypes specified by their constructors. | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 486 | |
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 487 | The syntactic entity \synt{target} can be used to specify a local
 | 
| 58620 | 488 | context (e.g., @{text "(in linorder)"} @{cite "isabelle-isar-ref"}),
 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 489 | and \synt{prop} denotes a HOL proposition.
 | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 490 | |
| 58190 | 491 | The optional target is optionally followed by a combination of the following | 
| 56124 | 492 | options: | 
| 52822 | 493 | |
| 52824 | 494 | \begin{itemize}
 | 
| 495 | \setlength{\itemsep}{0pt}
 | |
| 496 | ||
| 497 | \item | |
| 59280 | 498 | The @{text plugins} option indicates which plugins should be enabled
 | 
| 499 | (@{text only}) or disabled (@{text del}). By default, all plugins are enabled.
 | |
| 58190 | 500 | |
| 501 | \item | |
| 57094 
589ec121ce1a
don't generate discriminators and selectors for 'datatype_new' unless the user asked for it
 blanchet parents: 
57092diff
changeset | 502 | The @{text "discs_sels"} option indicates that discriminators and selectors
 | 
| 
589ec121ce1a
don't generate discriminators and selectors for 'datatype_new' unless the user asked for it
 blanchet parents: 
57092diff
changeset | 503 | should be generated. The option is implicitly enabled if names are specified for | 
| 
589ec121ce1a
don't generate discriminators and selectors for 'datatype_new' unless the user asked for it
 blanchet parents: 
57092diff
changeset | 504 | discriminators or selectors. | 
| 52824 | 505 | \end{itemize}
 | 
| 52822 | 506 | |
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 507 | The optional \keyw{where} clause specifies default values for selectors.
 | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 508 | Each proposition must be an equation of the form | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 509 | @{text "un_D (C \<dots>) = \<dots>"}, where @{text C} is a constructor and
 | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 510 | @{text un_D} is a selector.
 | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 511 | |
| 52827 | 512 | The left-hand sides of the datatype equations specify the name of the type to | 
| 53534 | 513 | define, its type parameters, and additional information: | 
| 52822 | 514 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 515 | @{rail \<open>
 | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 516 |   @{syntax_def dt_name}: @{syntax tyargs}? name mixfix?
 | 
| 52824 | 517 | ; | 
| 57092 | 518 |   @{syntax_def tyargs}: typefree | '(' (('dead' | name ':')? typefree + ',') ')'
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 519 | \<close>} | 
| 52822 | 520 | |
| 55351 | 521 | \medskip | 
| 522 | ||
| 52827 | 523 | \noindent | 
| 55474 | 524 | The syntactic entity \synt{name} denotes an identifier, \synt{mixfix} denotes
 | 
| 525 | the usual parenthesized mixfix notation, and \synt{typefree} denotes fixed type
 | |
| 58620 | 526 | variable (@{typ 'a}, @{typ 'b}, \ldots) @{cite "isabelle-isar-ref"}.
 | 
| 52822 | 527 | |
| 52827 | 528 | The optional names preceding the type variables allow to override the default | 
| 57988 | 529 | names of the set functions (@{text set\<^sub>1_t}, \ldots, @{text set\<^sub>m_t}). Type
 | 
| 58190 | 530 | arguments can be marked as dead by entering @{text dead} in front of the
 | 
| 58220 | 531 | type variable (e.g., @{text "(dead 'a)"}); otherwise, they are live or dead
 | 
| 55705 | 532 | (and a set function is generated or not) depending on where they occur in the | 
| 533 | right-hand sides of the definition. Declaring a type argument as dead can speed | |
| 534 | up the type definition but will prevent any later (co)recursion through that | |
| 535 | type argument. | |
| 536 | ||
| 53647 | 537 | Inside a mutually recursive specification, all defined datatypes must | 
| 538 | mention exactly the same type variables in the same order. | |
| 52822 | 539 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 540 | @{rail \<open>
 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 541 |   @{syntax_def dt_ctor}: (name ':')? name (@{syntax dt_ctor_arg} * ) mixfix?
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 542 | \<close>} | 
| 52824 | 543 | |
| 53535 | 544 | \medskip | 
| 545 | ||
| 52827 | 546 | \noindent | 
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 547 | The main constituents of a constructor specification are the name of the | 
| 52827 | 548 | constructor and the list of its argument types. An optional discriminator name | 
| 59722 | 549 | can be supplied at the front. If discriminators are enabled (cf.\ the | 
| 550 | @{text "discs_sels"} option) but no name is supplied, the default is
 | |
| 57091 | 551 | @{text "\<lambda>x. x = C\<^sub>j"} for nullary constructors and
 | 
| 552 | @{text t.is_C\<^sub>j} otherwise.
 | |
| 52822 | 553 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 554 | @{rail \<open>
 | 
| 55472 
990651bfc65b
updated docs to reflect the new 'free_constructors' syntax
 blanchet parents: 
55468diff
changeset | 555 |   @{syntax_def dt_ctor_arg}: type | '(' name ':' type ')'
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 556 | \<close>} | 
| 52827 | 557 | |
| 53535 | 558 | \medskip | 
| 559 | ||
| 52827 | 560 | \noindent | 
| 58620 | 561 | The syntactic entity \synt{type} denotes a HOL type @{cite "isabelle-isar-ref"}.
 | 
| 55474 | 562 | |
| 52827 | 563 | In addition to the type of a constructor argument, it is possible to specify a | 
| 59722 | 564 | name for the corresponding selector. The same selector name can be reused for | 
| 565 | arguments to several constructors as long as the arguments share the same type. | |
| 566 | If selectors are enabled (cf.\ the @{text "discs_sels"} option) but no name is
 | |
| 567 | supplied, the default name is @{text un_C\<^sub>ji}.
 | |
| 62081 | 568 | \<close> | 
| 569 | ||
| 570 | ||
| 571 | subsubsection \<open> \keyw{datatype_compat}
 | |
| 572 |   \label{sssec:datatype-compat} \<close>
 | |
| 573 | ||
| 574 | text \<open> | |
| 53829 | 575 | \begin{matharray}{rcl}
 | 
| 55531 
601ca8efa000
renamed 'datatype_new_compat' to 'datatype_compat'
 blanchet parents: 
55530diff
changeset | 576 |   @{command_def "datatype_compat"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | 
| 53829 | 577 | \end{matharray}
 | 
| 578 | ||
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 579 | @{rail \<open>
 | 
| 55531 
601ca8efa000
renamed 'datatype_new_compat' to 'datatype_compat'
 blanchet parents: 
55530diff
changeset | 580 |   @@{command datatype_compat} (name +)
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 581 | \<close>} | 
| 53829 | 582 | |
| 55351 | 583 | \medskip | 
| 584 | ||
| 53829 | 585 | \noindent | 
| 55531 
601ca8efa000
renamed 'datatype_new_compat' to 'datatype_compat'
 blanchet parents: 
55530diff
changeset | 586 | The @{command datatype_compat} command registers new-style datatypes as
 | 
| 58245 | 587 | old-style datatypes and invokes the old-style plugins. For example: | 
| 62081 | 588 | \<close> | 
| 53621 | 589 | |
| 55531 
601ca8efa000
renamed 'datatype_new_compat' to 'datatype_compat'
 blanchet parents: 
55530diff
changeset | 590 | datatype_compat even_nat odd_nat | 
| 53621 | 591 | |
| 62081 | 592 | text \<open> \blankline \<close> | 
| 593 | ||
| 594 |     ML \<open> Old_Datatype_Data.get_info @{theory} @{type_name even_nat} \<close>
 | |
| 595 | ||
| 596 | text \<open> | |
| 58620 | 597 | The syntactic entity \synt{name} denotes an identifier @{cite "isabelle-isar-ref"}.
 | 
| 55474 | 598 | |
| 60135 
852f7a49ec0c
updated docs, esp. relating to 'datatype_compat'
 blanchet parents: 
60134diff
changeset | 599 | The command is sometimes useful when migrating from the old datatype package to | 
| 
852f7a49ec0c
updated docs, esp. relating to 'datatype_compat'
 blanchet parents: 
60134diff
changeset | 600 | the new one. | 
| 55474 | 601 | |
| 602 | A few remarks concern nested recursive datatypes: | |
| 53748 | 603 | |
| 604 | \begin{itemize}
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 605 | \setlength{\itemsep}{0pt}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 606 | |
| 55871 | 607 | \item The old-style, nested-as-mutual induction rule and recursor theorems are | 
| 608 | generated under their usual names but with ``@{text "compat_"}'' prefixed
 | |
| 58215 | 609 | (e.g., @{text compat_tree.induct}, @{text compat_tree.inducts}, and
 | 
| 61351 | 610 | @{text compat_tree.rec}). These theorems should be identical to the ones
 | 
| 611 | generated by the old datatype package, \emph{up to the order of the
 | |
| 612 | premises}---meaning that the subgoals generated by the @{text induct} or
 | |
| 613 | @{text induction} method may be in a different order than before.
 | |
| 53748 | 614 | |
| 615 | \item All types through which recursion takes place must be new-style datatypes | |
| 59722 | 616 | or the function type. | 
| 53748 | 617 | \end{itemize}
 | 
| 62081 | 618 | \<close> | 
| 619 | ||
| 620 | ||
| 621 | subsection \<open> Generated Constants | |
| 622 |   \label{ssec:datatype-generated-constants} \<close>
 | |
| 623 | ||
| 624 | text \<open> | |
| 59722 | 625 | Given a datatype @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"} with $m$ live type variables
 | 
| 59284 | 626 | and $n$ constructors @{text "t.C\<^sub>1"}, \ldots, @{text "t.C\<^sub>n"}, the following
 | 
| 627 | auxiliary constants are introduced: | |
| 53617 | 628 | |
| 55353 | 629 | \medskip | 
| 630 | ||
| 631 | \begin{tabular}{@ {}ll@ {}}
 | |
| 632 | Case combinator: & | |
| 633 |   @{text t.case_t} (rendered using the familiar @{text case}--@{text of} syntax) \\
 | |
| 634 | Discriminators: & | |
| 57988 | 635 |   @{text t.is_C\<^sub>1}$, \ldots, $@{text t.is_C\<^sub>n} \\
 | 
| 55353 | 636 | Selectors: & | 
| 637 |   @{text t.un_C\<^sub>11}$, \ldots, $@{text t.un_C\<^sub>1k\<^sub>1} \\
 | |
| 638 | & \quad\vdots \\ | |
| 639 | & @{text t.un_C\<^sub>n1}$, \ldots, $@{text t.un_C\<^sub>nk\<^sub>n} \\
 | |
| 640 | Set functions: & | |
| 57988 | 641 |   @{text t.set\<^sub>1_t}, \ldots, @{text t.set\<^sub>m_t} \\
 | 
| 55353 | 642 | Map function: & | 
| 643 |   @{text t.map_t} \\
 | |
| 644 | Relator: & | |
| 645 |   @{text t.rel_t} \\
 | |
| 646 | Recursor: & | |
| 58190 | 647 |   @{text t.rec_t}
 | 
| 55353 | 648 | \end{tabular}
 | 
| 649 | ||
| 650 | \medskip | |
| 53617 | 651 | |
| 652 | \noindent | |
| 59722 | 653 | The discriminators and selectors are generated only if the @{text "discs_sels"}
 | 
| 654 | option is enabled or if names are specified for discriminators or selectors. | |
| 655 | The set functions, map function, and relator are generated only if $m > 0$. | |
| 656 | ||
| 58245 | 657 | In addition, some of the plugins introduce their own constants | 
| 59282 | 658 | (Section~\ref{sec:selecting-plugins}). The case combinator, discriminators,
 | 
| 58508 | 659 | and selectors are collectively called \emph{destructors}. The prefix
 | 
| 660 | ``@{text "t."}'' is an optional component of the names and is normally hidden.
 | |
| 62081 | 661 | \<close> | 
| 662 | ||
| 663 | ||
| 664 | subsection \<open> Generated Theorems | |
| 665 |   \label{ssec:datatype-generated-theorems} \<close>
 | |
| 666 | ||
| 667 | text \<open> | |
| 58310 | 668 | The characteristic theorems generated by @{command datatype} are grouped in
 | 
| 53623 | 669 | three broad categories: | 
| 53535 | 670 | |
| 53543 | 671 | \begin{itemize}
 | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 672 | \setlength{\itemsep}{0pt}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 673 | |
| 56655 | 674 | \item The \emph{free constructor theorems}
 | 
| 675 | (Section~\ref{sssec:free-constructor-theorems}) are properties of the
 | |
| 676 | constructors and destructors that can be derived for any freely generated type. | |
| 677 | Internally, the derivation is performed by @{command free_constructors}.
 | |
| 678 | ||
| 679 | \item The \emph{functorial theorems} (Section~\ref{sssec:functorial-theorems})
 | |
| 680 | are properties of datatypes related to their BNF nature. | |
| 681 | ||
| 682 | \item The \emph{inductive theorems} (Section~\ref{sssec:inductive-theorems})
 | |
| 683 | are properties of datatypes related to their inductive nature. | |
| 53552 | 684 | |
| 53543 | 685 | \end{itemize}
 | 
| 53535 | 686 | |
| 687 | \noindent | |
| 53542 | 688 | The full list of named theorems can be obtained as usual by entering the | 
| 57542 | 689 | command \keyw{print_theorems} immediately after the datatype definition.
 | 
| 58508 | 690 | This list includes theorems produced by plugins | 
| 59282 | 691 | (Section~\ref{sec:selecting-plugins}), but normally excludes low-level
 | 
| 58508 | 692 | theorems that reveal internal constructions. To make these accessible, add | 
| 693 | the line | |
| 62081 | 694 | \<close> | 
| 53535 | 695 | |
| 62093 | 696 | declare [[bnf_internals]] | 
| 53542 | 697 | (*<*) | 
| 62093 | 698 | declare [[bnf_internals = false]] | 
| 53542 | 699 | (*>*) | 
| 53535 | 700 | |
| 62081 | 701 | text \<open> | 
| 53552 | 702 | \noindent | 
| 703 | to the top of the theory file. | |
| 62081 | 704 | \<close> | 
| 705 | ||
| 706 | ||
| 707 | subsubsection \<open> Free Constructor Theorems | |
| 708 |   \label{sssec:free-constructor-theorems} \<close>
 | |
| 53535 | 709 | |
| 53543 | 710 | (*<*) | 
| 53837 | 711 | consts nonnull :: 'a | 
| 53543 | 712 | (*>*) | 
| 713 | ||
| 62081 | 714 | text \<open> | 
| 54621 | 715 | The free constructor theorems are partitioned in three subgroups. The first | 
| 716 | subgroup of properties is concerned with the constructors. They are listed below | |
| 717 | for @{typ "'a list"}:
 | |
| 53543 | 718 | |
| 53552 | 719 | \begin{indentblock}
 | 
| 53543 | 720 | \begin{description}
 | 
| 53544 | 721 | |
| 53642 | 722 | \item[@{text "t."}\hthm{inject} @{text "[iff, induct_simp]"}\rm:] ~ \\
 | 
| 53544 | 723 | @{thm list.inject[no_vars]}
 | 
| 724 | ||
| 53642 | 725 | \item[@{text "t."}\hthm{distinct} @{text "[simp, induct_simp]"}\rm:] ~ \\
 | 
| 53543 | 726 | @{thm list.distinct(1)[no_vars]} \\
 | 
| 727 | @{thm list.distinct(2)[no_vars]}
 | |
| 728 | ||
| 53642 | 729 | \item[@{text "t."}\hthm{exhaust} @{text "[cases t, case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
 | 
| 53543 | 730 | @{thm list.exhaust[no_vars]}
 | 
| 731 | ||
| 53642 | 732 | \item[@{text "t."}\hthm{nchotomy}\rm:] ~ \\
 | 
| 53543 | 733 | @{thm list.nchotomy[no_vars]}
 | 
| 734 | ||
| 735 | \end{description}
 | |
| 53552 | 736 | \end{indentblock}
 | 
| 53543 | 737 | |
| 738 | \noindent | |
| 53621 | 739 | In addition, these nameless theorems are registered as safe elimination rules: | 
| 740 | ||
| 741 | \begin{indentblock}
 | |
| 742 | \begin{description}
 | |
| 743 | ||
| 54386 | 744 | \item[@{text "t."}\hthm{distinct {\upshape[}THEN notE}@{text ", elim!"}\hthm{\upshape]}\rm:] ~ \\
 | 
| 53621 | 745 | @{thm list.distinct(1)[THEN notE, elim!, no_vars]} \\
 | 
| 746 | @{thm list.distinct(2)[THEN notE, elim!, no_vars]}
 | |
| 747 | ||
| 748 | \end{description}
 | |
| 749 | \end{indentblock}
 | |
| 750 | ||
| 751 | \noindent | |
| 53543 | 752 | The next subgroup is concerned with the case combinator: | 
| 753 | ||
| 53552 | 754 | \begin{indentblock}
 | 
| 53543 | 755 | \begin{description}
 | 
| 53544 | 756 | |
| 53798 | 757 | \item[@{text "t."}\hthm{case} @{text "[simp, code]"}\rm:] ~ \\
 | 
| 53543 | 758 | @{thm list.case(1)[no_vars]} \\
 | 
| 58335 
a5a3b576fcfb
generate 'code' attribute only if 'code' plugin is enabled
 blanchet parents: 
58311diff
changeset | 759 | @{thm list.case(2)[no_vars]} \\
 | 
| 59284 | 760 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | 
| 761 | (Section~\ref{ssec:code-generator}).
 | |
| 53543 | 762 | |
| 57542 | 763 | \item[@{text "t."}\hthm{case_cong} @{text "[fundef_cong]"}\rm:] ~ \\
 | 
| 53543 | 764 | @{thm list.case_cong[no_vars]}
 | 
| 765 | ||
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 766 | \item[@{text "t."}\hthm{case_cong_weak} @{text "[cong]"}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 767 | @{thm list.case_cong_weak[no_vars]}
 | 
| 53543 | 768 | |
| 59268 | 769 | \item[@{text "t."}\hthm{case_distrib}\rm:] ~ \\
 | 
| 770 | @{thm list.case_distrib[no_vars]}
 | |
| 771 | ||
| 53642 | 772 | \item[@{text "t."}\hthm{split}\rm:] ~ \\
 | 
| 53543 | 773 | @{thm list.split[no_vars]}
 | 
| 774 | ||
| 57542 | 775 | \item[@{text "t."}\hthm{split_asm}\rm:] ~ \\
 | 
| 53543 | 776 | @{thm list.split_asm[no_vars]}
 | 
| 777 | ||
| 53544 | 778 | \item[@{text "t."}\hthm{splits} = @{text "split split_asm"}]
 | 
| 53543 | 779 | |
| 780 | \end{description}
 | |
| 53552 | 781 | \end{indentblock}
 | 
| 53543 | 782 | |
| 783 | \noindent | |
| 54621 | 784 | The third subgroup revolves around discriminators and selectors: | 
| 53543 | 785 | |
| 53552 | 786 | \begin{indentblock}
 | 
| 53543 | 787 | \begin{description}
 | 
| 53544 | 788 | |
| 53694 | 789 | \item[@{text "t."}\hthm{disc} @{text "[simp]"}\rm:] ~ \\
 | 
| 790 | @{thm list.disc(1)[no_vars]} \\
 | |
| 791 | @{thm list.disc(2)[no_vars]}
 | |
| 792 | ||
| 53703 | 793 | \item[@{text "t."}\hthm{discI}\rm:] ~ \\
 | 
| 794 | @{thm list.discI(1)[no_vars]} \\
 | |
| 795 | @{thm list.discI(2)[no_vars]}
 | |
| 796 | ||
| 53805 | 797 | \item[@{text "t."}\hthm{sel} @{text "[simp, code]"}\rm:] ~ \\
 | 
| 53694 | 798 | @{thm list.sel(1)[no_vars]} \\
 | 
| 58335 
a5a3b576fcfb
generate 'code' attribute only if 'code' plugin is enabled
 blanchet parents: 
58311diff
changeset | 799 | @{thm list.sel(2)[no_vars]} \\
 | 
| 59284 | 800 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | 
| 801 | (Section~\ref{ssec:code-generator}).
 | |
| 53543 | 802 | |
| 53642 | 803 | \item[@{text "t."}\hthm{collapse} @{text "[simp]"}\rm:] ~ \\
 | 
| 53543 | 804 | @{thm list.collapse(1)[no_vars]} \\
 | 
| 58151 
414deb2ef328
take out 'x = C' of the simplifier for unit types
 blanchet parents: 
58121diff
changeset | 805 | @{thm list.collapse(2)[no_vars]} \\
 | 
| 59284 | 806 | The @{text "[simp]"} attribute is exceptionally omitted for datatypes equipped
 | 
| 58151 
414deb2ef328
take out 'x = C' of the simplifier for unit types
 blanchet parents: 
58121diff
changeset | 807 | with a single nullary constructor, because a property of the form | 
| 59284 | 808 | @{prop "x = C"} is not suitable as a simplification rule.
 | 
| 53543 | 809 | |
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 810 | \item[@{text "t."}\hthm{distinct_disc} @{text "[dest]"}\rm:] ~ \\
 | 
| 53543 | 811 | These properties are missing for @{typ "'a list"} because there is only one
 | 
| 59284 | 812 | proper discriminator. If the datatype had been introduced with a second | 
| 53837 | 813 | discriminator called @{const nonnull}, they would have read thusly: \\[\jot]
 | 
| 814 | @{prop "null list \<Longrightarrow> \<not> nonnull list"} \\
 | |
| 815 | @{prop "nonnull list \<Longrightarrow> \<not> null list"}
 | |
| 53543 | 816 | |
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 817 | \item[@{text "t."}\hthm{exhaust_disc} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 818 | @{thm list.exhaust_disc[no_vars]}
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 819 | |
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 820 | \item[@{text "t."}\hthm{exhaust_sel} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 821 | @{thm list.exhaust_sel[no_vars]}
 | 
| 53916 | 822 | |
| 53642 | 823 | \item[@{text "t."}\hthm{expand}\rm:] ~ \\
 | 
| 53543 | 824 | @{thm list.expand[no_vars]}
 | 
| 825 | ||
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 826 | \item[@{text "t."}\hthm{split_sel}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 827 | @{thm list.split_sel[no_vars]}
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 828 | |
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 829 | \item[@{text "t."}\hthm{split_sel_asm}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 830 | @{thm list.split_sel_asm[no_vars]}
 | 
| 53917 | 831 | |
| 57984 
cbe9a16f8e11
added collection theorem for consistency and convenience
 blanchet parents: 
57983diff
changeset | 832 | \item[@{text "t."}\hthm{split_sels} = @{text "split_sel split_sel_asm"}]
 | 
| 
cbe9a16f8e11
added collection theorem for consistency and convenience
 blanchet parents: 
57983diff
changeset | 833 | |
| 57542 | 834 | \item[@{text "t."}\hthm{case_eq_if}\rm:] ~ \\
 | 
| 54491 | 835 | @{thm list.case_eq_if[no_vars]}
 | 
| 53543 | 836 | |
| 59273 | 837 | \item[@{text "t."}\hthm{disc_eq_case}\rm:] ~ \\
 | 
| 838 | @{thm list.disc_eq_case(1)[no_vars]} \\
 | |
| 839 | @{thm list.disc_eq_case(2)[no_vars]}
 | |
| 840 | ||
| 53543 | 841 | \end{description}
 | 
| 53552 | 842 | \end{indentblock}
 | 
| 54152 | 843 | |
| 844 | \noindent | |
| 58151 
414deb2ef328
take out 'x = C' of the simplifier for unit types
 blanchet parents: 
58121diff
changeset | 845 | In addition, equational versions of @{text t.disc} are registered with the
 | 
| 59284 | 846 | @{text "[code]"} attribute. The @{text "[code]"} attribute is set by the
 | 
| 847 | @{text code} plugin (Section~\ref{ssec:code-generator}).
 | |
| 62081 | 848 | \<close> | 
| 849 | ||
| 850 | ||
| 851 | subsubsection \<open> Functorial Theorems | |
| 852 |   \label{sssec:functorial-theorems} \<close>
 | |
| 853 | ||
| 854 | text \<open> | |
| 61349 | 855 | The functorial theorems are generated for type constructors with at least | 
| 856 | one live type argument (e.g., @{typ "'a list"}). They are partitioned in two
 | |
| 857 | subgroups. The first subgroup consists of properties involving the | |
| 858 | constructors or the destructors and either a set function, the map function, | |
| 859 | or the relator: | |
| 53552 | 860 | |
| 861 | \begin{indentblock}
 | |
| 862 | \begin{description}
 | |
| 863 | ||
| 58915 | 864 | \item[@{text "t."}\hthm{case_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 865 | @{thm list.case_transfer[no_vars]} \\
 | |
| 61350 | 866 | This property is generated by the @{text transfer} plugin
 | 
| 61349 | 867 | (Section~\ref{ssec:transfer}).
 | 
| 61350 | 868 | %The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 869 | %(Section~\ref{ssec:transfer}).
 | |
| 58915 | 870 | |
| 871 | \item[@{text "t."}\hthm{sel_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | |
| 58677 | 872 | This property is missing for @{typ "'a list"} because there is no common
 | 
| 58915 | 873 | selector to all constructors. \\ | 
| 59284 | 874 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 61349 | 875 | (Section~\ref{ssec:transfer}).
 | 
| 58915 | 876 | |
| 877 | \item[@{text "t."}\hthm{ctr_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | |
| 58000 | 878 | @{thm list.ctr_transfer(1)[no_vars]} \\
 | 
| 58915 | 879 | @{thm list.ctr_transfer(2)[no_vars]} \\
 | 
| 59284 | 880 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 61349 | 881 | (Section~\ref{ssec:transfer}) .
 | 
| 58915 | 882 | |
| 883 | \item[@{text "t."}\hthm{disc_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | |
| 58096 | 884 | @{thm list.disc_transfer(1)[no_vars]} \\
 | 
| 58915 | 885 | @{thm list.disc_transfer(2)[no_vars]} \\
 | 
| 59284 | 886 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 61349 | 887 | (Section~\ref{ssec:transfer}).
 | 
| 58096 | 888 | |
| 53798 | 889 | \item[@{text "t."}\hthm{set} @{text "[simp, code]"}\rm:] ~ \\
 | 
| 53694 | 890 | @{thm list.set(1)[no_vars]} \\
 | 
| 58335 
a5a3b576fcfb
generate 'code' attribute only if 'code' plugin is enabled
 blanchet parents: 
58311diff
changeset | 891 | @{thm list.set(2)[no_vars]} \\
 | 
| 59284 | 892 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | 
| 893 | (Section~\ref{ssec:code-generator}).
 | |
| 53552 | 894 | |
| 57988 | 895 | \item[@{text "t."}\hthm{set_cases} @{text "[consumes 1, cases set: set\<^sub>i_t]"}\rm:] ~ \\
 | 
| 57894 | 896 | @{thm list.set_cases[no_vars]}
 | 
| 897 | ||
| 57892 | 898 | \item[@{text "t."}\hthm{set_intros}\rm:] ~ \\
 | 
| 899 | @{thm list.set_intros(1)[no_vars]} \\
 | |
| 900 | @{thm list.set_intros(2)[no_vars]}
 | |
| 901 | ||
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 902 | \item[@{text "t."}\hthm{set_sel}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 903 | @{thm list.set_sel[no_vars]}
 | 
| 57153 | 904 | |
| 53798 | 905 | \item[@{text "t."}\hthm{map} @{text "[simp, code]"}\rm:] ~ \\
 | 
| 53552 | 906 | @{thm list.map(1)[no_vars]} \\
 | 
| 58335 
a5a3b576fcfb
generate 'code' attribute only if 'code' plugin is enabled
 blanchet parents: 
58311diff
changeset | 907 | @{thm list.map(2)[no_vars]} \\
 | 
| 59284 | 908 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | 
| 909 | (Section~\ref{ssec:code-generator}).
 | |
| 53552 | 910 | |
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 911 | \item[@{text "t."}\hthm{map_disc_iff} @{text "[simp]"}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 912 | @{thm list.map_disc_iff[no_vars]}
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 913 | |
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 914 | \item[@{text "t."}\hthm{map_sel}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 915 | @{thm list.map_sel[no_vars]}
 | 
| 57047 | 916 | |
| 57542 | 917 | \item[@{text "t."}\hthm{rel_inject} @{text "[simp]"}\rm:] ~ \\
 | 
| 53552 | 918 | @{thm list.rel_inject(1)[no_vars]} \\
 | 
| 919 | @{thm list.rel_inject(2)[no_vars]}
 | |
| 920 | ||
| 57542 | 921 | \item[@{text "t."}\hthm{rel_distinct} @{text "[simp]"}\rm:] ~ \\
 | 
| 57526 | 922 | @{thm list.rel_distinct(1)[no_vars]} \\
 | 
| 923 | @{thm list.rel_distinct(2)[no_vars]}
 | |
| 924 | ||
| 57542 | 925 | \item[@{text "t."}\hthm{rel_intros}\rm:] ~ \\
 | 
| 57494 | 926 | @{thm list.rel_intros(1)[no_vars]} \\
 | 
| 927 | @{thm list.rel_intros(2)[no_vars]}
 | |
| 928 | ||
| 58474 | 929 | \item[@{text "t."}\hthm{rel_cases} @{text "[consumes 1, case_names t\<^sub>1 \<dots> t\<^sub>m, cases pred]"}\rm:] ~ \\
 | 
| 930 | @{thm list.rel_cases[no_vars]}
 | |
| 53552 | 931 | |
| 57564 | 932 | \item[@{text "t."}\hthm{rel_sel}\rm:] ~ \\
 | 
| 933 | @{thm list.rel_sel[no_vars]}
 | |
| 934 | ||
| 53552 | 935 | \end{description}
 | 
| 936 | \end{indentblock}
 | |
| 54146 | 937 | |
| 938 | \noindent | |
| 939 | In addition, equational versions of @{text t.rel_inject} and @{text
 | |
| 59284 | 940 | rel_distinct} are registered with the @{text "[code]"} attribute. The
 | 
| 941 | @{text "[code]"} attribute is set by the @{text code} plugin
 | |
| 942 | (Section~\ref{ssec:code-generator}).
 | |
| 54621 | 943 | |
| 944 | The second subgroup consists of more abstract properties of the set functions, | |
| 945 | the map function, and the relator: | |
| 946 | ||
| 947 | \begin{indentblock}
 | |
| 948 | \begin{description}
 | |
| 949 | ||
| 57969 | 950 | \item[@{text "t."}\hthm{inj_map}\rm:] ~ \\
 | 
| 951 | @{thm list.inj_map[no_vars]}
 | |
| 952 | ||
| 57971 | 953 | \item[@{text "t."}\hthm{inj_map_strong}\rm:] ~ \\
 | 
| 954 | @{thm list.inj_map_strong[no_vars]}
 | |
| 955 | ||
| 57542 | 956 | \item[@{text "t."}\hthm{set_map}\rm:] ~ \\
 | 
| 56992 | 957 | @{thm list.set_map[no_vars]}
 | 
| 958 | ||
| 58915 | 959 | \item[@{text "t."}\hthm{set_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 960 | @{thm list.set_transfer[no_vars]} \\
 | |
| 59284 | 961 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 59824 | 962 | (Section~\ref{ssec:transfer}) for type constructors with no dead type arguments.
 | 
| 58107 | 963 | |
| 58245 | 964 | \item[@{text "t."}\hthm{map_cong0}\rm:] ~ \\
 | 
| 54621 | 965 | @{thm list.map_cong0[no_vars]}
 | 
| 966 | ||
| 57542 | 967 | \item[@{text "t."}\hthm{map_cong} @{text "[fundef_cong]"}\rm:] ~ \\
 | 
| 54621 | 968 | @{thm list.map_cong[no_vars]}
 | 
| 969 | ||
| 57982 | 970 | \item[@{text "t."}\hthm{map_cong_simp}\rm:] ~ \\
 | 
| 971 | @{thm list.map_cong_simp[no_vars]}
 | |
| 972 | ||
| 59793 | 973 | \item[@{text "t."}\hthm{map_id0}\rm:] ~ \\
 | 
| 974 | @{thm list.map_id0[no_vars]}
 | |
| 975 | ||
| 57542 | 976 | \item[@{text "t."}\hthm{map_id}\rm:] ~ \\
 | 
| 54621 | 977 | @{thm list.map_id[no_vars]}
 | 
| 978 | ||
| 57542 | 979 | \item[@{text "t."}\hthm{map_ident}\rm:] ~ \\
 | 
| 56904 | 980 | @{thm list.map_ident[no_vars]}
 | 
| 981 | ||
| 58915 | 982 | \item[@{text "t."}\hthm{map_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 983 | @{thm list.map_transfer[no_vars]} \\
 | |
| 59284 | 984 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 59824 | 985 | (Section~\ref{ssec:transfer}) for type constructors with no dead type arguments.
 | 
| 58103 | 986 | |
| 58244 | 987 | \item[@{text "t."}\hthm{rel_compp} @{text "[relator_distr]"}\rm:] ~ \\
 | 
| 58245 | 988 | @{thm list.rel_compp[no_vars]} \\
 | 
| 59284 | 989 | The @{text "[relator_distr]"} attribute is set by the @{text lifting} plugin
 | 
| 990 | (Section~\ref{ssec:lifting}).
 | |
| 54621 | 991 | |
| 57542 | 992 | \item[@{text "t."}\hthm{rel_conversep}\rm:] ~ \\
 | 
| 54621 | 993 | @{thm list.rel_conversep[no_vars]}
 | 
| 994 | ||
| 57542 | 995 | \item[@{text "t."}\hthm{rel_eq}\rm:] ~ \\
 | 
| 54621 | 996 | @{thm list.rel_eq[no_vars]}
 | 
| 997 | ||
| 57542 | 998 | \item[@{text "t."}\hthm{rel_flip}\rm:] ~ \\
 | 
| 54621 | 999 | @{thm list.rel_flip[no_vars]}
 | 
| 1000 | ||
| 57933 | 1001 | \item[@{text "t."}\hthm{rel_map}\rm:] ~ \\
 | 
| 1002 | @{thm list.rel_map(1)[no_vars]} \\
 | |
| 1003 | @{thm list.rel_map(2)[no_vars]}
 | |
| 1004 | ||
| 58344 | 1005 | \item[@{text "t."}\hthm{rel_mono} @{text "[mono, relator_mono]"}\rm:] ~ \\
 | 
| 58245 | 1006 | @{thm list.rel_mono[no_vars]} \\
 | 
| 59284 | 1007 | The @{text "[relator_mono]"} attribute is set by the @{text lifting} plugin
 | 
| 1008 | (Section~\ref{ssec:lifting}).
 | |
| 54621 | 1009 | |
| 61242 | 1010 | \item[@{text "t."}\hthm{rel_mono_strong}\rm:] ~ \\
 | 
| 1011 | @{thm list.rel_mono_strong[no_vars]}
 | |
| 1012 | ||
| 1013 | \item[@{text "t."}\hthm{rel_cong} @{text "[fundef_cong]"}\rm:] ~ \\
 | |
| 1014 | @{thm list.rel_cong[no_vars]}
 | |
| 1015 | ||
| 1016 | \item[@{text "t."}\hthm{rel_cong_simp}\rm:] ~ \\
 | |
| 1017 | @{thm list.rel_cong_simp[no_vars]}
 | |
| 1018 | ||
| 59793 | 1019 | \item[@{text "t."}\hthm{rel_refl}\rm:] ~ \\
 | 
| 1020 | @{thm list.rel_refl[no_vars]}
 | |
| 1021 | ||
| 61240 | 1022 | \item[@{text "t."}\hthm{rel_refl_strong}\rm:] ~ \\
 | 
| 1023 | @{thm list.rel_refl_strong[no_vars]}
 | |
| 1024 | ||
| 1025 | \item[@{text "t."}\hthm{rel_reflp}\rm:] ~ \\
 | |
| 1026 | @{thm list.rel_reflp[no_vars]}
 | |
| 1027 | ||
| 1028 | \item[@{text "t."}\hthm{rel_symp}\rm:] ~ \\
 | |
| 1029 | @{thm list.rel_symp[no_vars]}
 | |
| 1030 | ||
| 1031 | \item[@{text "t."}\hthm{rel_transp}\rm:] ~ \\
 | |
| 1032 | @{thm list.rel_transp[no_vars]}
 | |
| 1033 | ||
| 58915 | 1034 | \item[@{text "t."}\hthm{rel_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 1035 | @{thm list.rel_transfer[no_vars]} \\
 | |
| 59284 | 1036 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 59824 | 1037 | (Section~\ref{ssec:transfer}) for type constructors with no dead type arguments.
 | 
| 58105 | 1038 | |
| 54621 | 1039 | \end{description}
 | 
| 1040 | \end{indentblock}
 | |
| 62081 | 1041 | \<close> | 
| 1042 | ||
| 1043 | ||
| 1044 | subsubsection \<open> Inductive Theorems | |
| 1045 |   \label{sssec:inductive-theorems} \<close>
 | |
| 1046 | ||
| 1047 | text \<open> | |
| 53623 | 1048 | The inductive theorems are as follows: | 
| 53544 | 1049 | |
| 53552 | 1050 | \begin{indentblock}
 | 
| 53544 | 1051 | \begin{description}
 | 
| 1052 | ||
| 57304 | 1053 | \item[@{text "t."}\hthm{induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n, induct t]"}\rm:] ~ \\
 | 
| 53544 | 1054 | @{thm list.induct[no_vars]}
 | 
| 1055 | ||
| 57542 | 1056 | \item[@{text "t."}\hthm{rel_induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n, induct pred]"}\rm:] ~ \\
 | 
| 57472 | 1057 | @{thm list.rel_induct[no_vars]}
 | 
| 1058 | ||
| 57701 | 1059 | \item[\begin{tabular}{@ {}l@ {}}
 | 
| 1060 |   @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm: \\
 | |
| 1061 |   @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{rel_induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm: \\
 | |
| 1062 | \end{tabular}] ~ \\
 | |
| 57472 | 1063 | Given $m > 1$ mutually recursive datatypes, this induction rule can be used to | 
| 1064 | prove $m$ properties simultaneously. | |
| 1065 | ||
| 53798 | 1066 | \item[@{text "t."}\hthm{rec} @{text "[simp, code]"}\rm:] ~ \\
 | 
| 53544 | 1067 | @{thm list.rec(1)[no_vars]} \\
 | 
| 58335 
a5a3b576fcfb
generate 'code' attribute only if 'code' plugin is enabled
 blanchet parents: 
58311diff
changeset | 1068 | @{thm list.rec(2)[no_vars]} \\
 | 
| 59284 | 1069 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | 
| 1070 | (Section~\ref{ssec:code-generator}).
 | |
| 53544 | 1071 | |
| 58733 | 1072 | \item[@{text "t."}\hthm{rec_o_map}\rm:] ~ \\
 | 
| 1073 | @{thm list.rec_o_map[no_vars]}
 | |
| 1074 | ||
| 58915 | 1075 | \item[@{text "t."}\hthm{rec_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 1076 | @{thm list.rec_transfer[no_vars]} \\
 | |
| 59284 | 1077 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 59824 | 1078 | (Section~\ref{ssec:transfer}) for type constructors with no dead type arguments.
 | 
| 58447 | 1079 | |
| 53544 | 1080 | \end{description}
 | 
| 53552 | 1081 | \end{indentblock}
 | 
| 53544 | 1082 | |
| 1083 | \noindent | |
| 58310 | 1084 | For convenience, @{command datatype} also provides the following collection:
 | 
| 53544 | 1085 | |
| 53552 | 1086 | \begin{indentblock}
 | 
| 53544 | 1087 | \begin{description}
 | 
| 1088 | ||
| 59284 | 1089 | \item[@{text "t."}\hthm{simps}] = @{text t.inject} @{text t.distinct} @{text t.case} @{text t.rec} @{text t.map} @{text t.rel_inject} \\
 | 
| 53694 | 1090 | @{text t.rel_distinct} @{text t.set}
 | 
| 53544 | 1091 | |
| 1092 | \end{description}
 | |
| 53552 | 1093 | \end{indentblock}
 | 
| 62081 | 1094 | \<close> | 
| 1095 | ||
| 1096 | ||
| 1097 | subsection \<open> Proof Method | |
| 1098 |   \label{ssec:datatype-proof-method} \<close>
 | |
| 1099 | ||
| 1100 | subsubsection \<open> \textit{countable_datatype}
 | |
| 1101 |   \label{sssec:datatype-compat} \<close>
 | |
| 1102 | ||
| 1103 | text \<open> | |
| 1104 | The theory @{file "~~/src/HOL/Library/Countable.thy"} provides a
 | |
| 1105 | proof method called @{text countable_datatype} that can be used to prove the
 | |
| 1106 | countability of many datatypes, building on the countability of the types | |
| 1107 | appearing in their definitions and of any type arguments. For example: | |
| 1108 | \<close> | |
| 1109 | ||
| 1110 | instance list :: (countable) countable | |
| 1111 | by countable_datatype | |
| 1112 | ||
| 1113 | ||
| 1114 | subsection \<open> Compatibility Issues | |
| 1115 |   \label{ssec:datatype-compatibility-issues} \<close>
 | |
| 1116 | ||
| 1117 | text \<open> | |
| 1118 | The command @{command datatype} has been designed to be highly compatible with
 | |
| 1119 | the old command, to ease migration. There are nonetheless a few | |
| 1120 | incompatibilities that may arise when porting: | |
| 53647 | 1121 | |
| 1122 | \begin{itemize}
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1123 | \setlength{\itemsep}{0pt}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1124 | |
| 53647 | 1125 | \item \emph{The Standard ML interfaces are different.} Tools and extensions
 | 
| 1126 | written to call the old ML interfaces will need to be adapted to the new | |
| 60135 
852f7a49ec0c
updated docs, esp. relating to 'datatype_compat'
 blanchet parents: 
60134diff
changeset | 1127 | interfaces. The @{text BNF_LFP_Compat} structure provides convenience functions
 | 
| 
852f7a49ec0c
updated docs, esp. relating to 'datatype_compat'
 blanchet parents: 
60134diff
changeset | 1128 | that simulate the old interfaces in terms of the new ones. | 
| 54537 | 1129 | |
| 1130 | \item \emph{The recursor @{text rec_t} has a different signature for nested
 | |
| 54185 | 1131 | recursive datatypes.} In the old package, nested recursion through non-functions | 
| 1132 | was internally reduced to mutual recursion. This reduction was visible in the | |
| 1133 | type of the recursor, used by \keyw{primrec}. Recursion through functions was
 | |
| 1134 | handled specially. In the new package, nested recursion (for functions and | |
| 1135 | non-functions) is handled in a more modular fashion. The old-style recursor can | |
| 56655 | 1136 | be generated on demand using @{command primrec} if the recursion is via
 | 
| 1137 | new-style datatypes, as explained in | |
| 61351 | 1138 | Section~\ref{sssec:primrec-nested-as-mutual-recursion}, or using
 | 
| 1139 | @{command datatype_compat}.
 | |
| 53647 | 1140 | |
| 54287 | 1141 | \item \emph{Accordingly, the induction rule is different for nested recursive
 | 
| 61351 | 1142 | datatypes.} Again, the old-style induction rule can be generated on demand | 
| 1143 | using @{command primrec} if the recursion is via new-style datatypes, as
 | |
| 1144 | explained in Section~\ref{sssec:primrec-nested-as-mutual-recursion}, or using
 | |
| 1145 | @{command datatype_compat}. For recursion through functions, the old-style
 | |
| 1146 | induction rule can be obtained by applying the @{text "[unfolded
 | |
| 1147 | all_mem_range]"} attribute on @{text t.induct}.
 | |
| 52828 | 1148 | |
| 58336 | 1149 | \item \emph{The @{const size} function has a slightly different definition.}
 | 
| 1150 | The new function returns @{text 1} instead of @{text 0} for some nonrecursive
 | |
| 1151 | constructors. This departure from the old behavior made it possible to implement | |
| 62081 | 1152 | @{const size} in terms of the generic function @{text "t.size_t"}. Moreover,
 | 
| 1153 | the new function considers nested occurrences of a value, in the nested | |
| 58339 | 1154 | recursive case. The old behavior can be obtained by disabling the @{text size}
 | 
| 59282 | 1155 | plugin (Section~\ref{sec:selecting-plugins}) and instantiating the
 | 
| 58339 | 1156 | @{text size} type class manually.
 | 
| 58336 | 1157 | |
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 1158 | \item \emph{The internal constructions are completely different.} Proof texts
 | 
| 62081 | 1159 | that unfold the definition of constants introduced by the old command will | 
| 58305 
57752a91eec4
renamed 'datatype' to 'old_datatype'; 'datatype' is now alias for 'datatype_new'
 blanchet parents: 
58298diff
changeset | 1160 | be difficult to port. | 
| 53647 | 1161 | |
| 58207 | 1162 | \item \emph{Some constants and theorems have different names.}
 | 
| 55641 
5b466efedd2c
renamed 'recs' and 'cases' theorems 'rec' and 'case' in old datatype package, for consistency with new package
 blanchet parents: 
55531diff
changeset | 1163 | For non-mutually recursive datatypes, | 
| 
5b466efedd2c
renamed 'recs' and 'cases' theorems 'rec' and 'case' in old datatype package, for consistency with new package
 blanchet parents: 
55531diff
changeset | 1164 | the alias @{text t.inducts} for @{text t.induct} is no longer generated.
 | 
| 53647 | 1165 | For $m > 1$ mutually recursive datatypes, | 
| 58207 | 1166 | @{text "rec_t\<^sub>1_\<dots>_t\<^sub>m_i"} has been renamed
 | 
| 62081 | 1167 | @{text "rec_t\<^sub>i"} for each @{text "i \<in> {1, \<dots>, m}"},
 | 
| 53997 | 1168 | @{text "t\<^sub>1_\<dots>_t\<^sub>m.inducts(i)"} has been renamed
 | 
| 62081 | 1169 | @{text "t\<^sub>i.induct"} for each @{text "i \<in> {1, \<dots>, m}"}, and the
 | 
| 58207 | 1170 | collection @{text "t\<^sub>1_\<dots>_t\<^sub>m.size"} (generated by the
 | 
| 1171 | @{text size} plugin, Section~\ref{ssec:size}) has been divided into
 | |
| 1172 | @{text "t\<^sub>1.size"}, \ldots, @{text "t\<^sub>m.size"}.
 | |
| 53647 | 1173 | |
| 1174 | \item \emph{The @{text t.simps} collection has been extended.}
 | |
| 58207 | 1175 | Previously available theorems are available at the same index as before. | 
| 53647 | 1176 | |
| 1177 | \item \emph{Variables in generated properties have different names.} This is
 | |
| 1178 | rarely an issue, except in proof texts that refer to variable names in the | |
| 1179 | @{text "[where \<dots>]"} attribute. The solution is to use the more robust
 | |
| 1180 | @{text "[of \<dots>]"} syntax.
 | |
| 1181 | \end{itemize}
 | |
| 1182 | ||
| 62081 | 1183 | The old command is still available as \keyw{old_datatype} in theory
 | 
| 1184 | @{file "~~/src/HOL/Library/Old_Datatype.thy"}. However, there is no general
 | |
| 1185 | way to register old-style datatypes as new-style datatypes. If the objective | |
| 1186 | is to define new-style datatypes with nested recursion through old-style | |
| 1187 | datatypes, the old-style datatypes can be registered as a BNF | |
| 1188 | (Section~\ref{sec:registering-bounded-natural-functors}). If the objective is
 | |
| 55468 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 1189 | to derive discriminators and selectors, this can be achieved using | 
| 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 1190 | @{command free_constructors}
 | 
| 53647 | 1191 | (Section~\ref{sec:deriving-destructors-and-theorems-for-free-constructors}).
 | 
| 62081 | 1192 | \<close> | 
| 1193 | ||
| 1194 | ||
| 1195 | section \<open> Defining Primitively Recursive Functions | |
| 1196 |   \label{sec:defining-primitively-recursive-functions} \<close>
 | |
| 1197 | ||
| 1198 | text \<open> | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1199 | Recursive functions over datatypes can be specified using the @{command primrec}
 | 
| 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1200 | command, which supports primitive recursion, or using the more general | 
| 59861 | 1201 | \keyw{fun}, \keyw{function}, and \keyw{partial_function} commands. In this
 | 
| 1202 | tutorial, the focus is on @{command primrec}; \keyw{fun} and \keyw{function} are
 | |
| 1203 | described in a separate tutorial @{cite "isabelle-function"}.
 | |
| 62081 | 1204 | \<close> | 
| 1205 | ||
| 1206 | ||
| 1207 | subsection \<open> Introductory Examples | |
| 1208 |   \label{ssec:primrec-introductory-examples} \<close>
 | |
| 1209 | ||
| 1210 | text \<open> | |
| 53646 | 1211 | Primitive recursion is illustrated through concrete examples based on the | 
| 1212 | datatypes defined in Section~\ref{ssec:datatype-introductory-examples}. More
 | |
| 61304 | 1213 | examples can be found in the directory @{file "~~/src/HOL/Datatype_Examples"}.
 | 
| 62081 | 1214 | \<close> | 
| 1215 | ||
| 1216 | ||
| 1217 | subsubsection \<open> Nonrecursive Types | |
| 1218 |   \label{sssec:primrec-nonrecursive-types} \<close>
 | |
| 1219 | ||
| 1220 | text \<open> | |
| 53621 | 1221 | Primitive recursion removes one layer of constructors on the left-hand side in | 
| 1222 | each equation. For example: | |
| 62081 | 1223 | \<close> | 
| 52841 | 1224 | |
| 60136 | 1225 | primrec (nonexhaustive) bool_of_trool :: "trool \<Rightarrow> bool" where | 
| 62081 | 1226 | "bool_of_trool Faalse \<longleftrightarrow> False" | 
| 1227 | | "bool_of_trool Truue \<longleftrightarrow> True" | |
| 1228 | ||
| 1229 | text \<open> \blankline \<close> | |
| 52841 | 1230 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1231 | primrec the_list :: "'a option \<Rightarrow> 'a list" where | 
| 62081 | 1232 | "the_list None = []" | 
| 1233 | | "the_list (Some a) = [a]" | |
| 1234 | ||
| 1235 | text \<open> \blankline \<close> | |
| 53621 | 1236 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1237 | primrec the_default :: "'a \<Rightarrow> 'a option \<Rightarrow> 'a" where | 
| 62081 | 1238 | "the_default d None = d" | 
| 1239 | | "the_default _ (Some a) = a" | |
| 1240 | ||
| 1241 | text \<open> \blankline \<close> | |
| 53621 | 1242 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1243 |     primrec mirrror :: "('a, 'b, 'c) triple \<Rightarrow> ('c, 'b, 'a) triple" where
 | 
| 52841 | 1244 | "mirrror (Triple a b c) = Triple c b a" | 
| 1245 | ||
| 62081 | 1246 | text \<open> | 
| 53621 | 1247 | \noindent | 
| 1248 | The equations can be specified in any order, and it is acceptable to leave out | |
| 1249 | some cases, which are then unspecified. Pattern matching on the left-hand side | |
| 1250 | is restricted to a single datatype, which must correspond to the same argument | |
| 1251 | in all equations. | |
| 62081 | 1252 | \<close> | 
| 1253 | ||
| 1254 | ||
| 1255 | subsubsection \<open> Simple Recursion | |
| 1256 |   \label{sssec:primrec-simple-recursion} \<close>
 | |
| 1257 | ||
| 1258 | text \<open> | |
| 53621 | 1259 | For simple recursive types, recursive calls on a constructor argument are | 
| 1260 | allowed on the right-hand side: | |
| 62081 | 1261 | \<close> | 
| 52841 | 1262 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1263 | primrec replicate :: "nat \<Rightarrow> 'a \<Rightarrow> 'a list" where | 
| 62081 | 1264 | "replicate Zero _ = []" | 
| 1265 | | "replicate (Succ n) x = x # replicate n x" | |
| 1266 | ||
| 1267 | text \<open> \blankline \<close> | |
| 52843 | 1268 | |
| 60136 | 1269 | primrec (nonexhaustive) at :: "'a list \<Rightarrow> nat \<Rightarrow> 'a" where | 
| 53644 | 1270 | "at (x # xs) j = | 
| 52843 | 1271 | (case j of | 
| 53644 | 1272 | Zero \<Rightarrow> x | 
| 58245 | 1273 | | Succ j' \<Rightarrow> at xs j')" | 
| 52843 | 1274 | |
| 62081 | 1275 | text \<open> \blankline \<close> | 
| 53621 | 1276 | |
| 59284 | 1277 |     primrec (*<*)(in early) (transfer) (*>*)tfold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a, 'b) tlist \<Rightarrow> 'b" where
 | 
| 62081 | 1278 | "tfold _ (TNil y) = y" | 
| 1279 | | "tfold f (TCons x xs) = f x (tfold f xs)" | |
| 1280 | ||
| 1281 | text \<open> | |
| 53621 | 1282 | \noindent | 
| 54402 | 1283 | Pattern matching is only available for the argument on which the recursion takes | 
| 1284 | place. Fortunately, it is easy to generate pattern-maching equations using the | |
| 62081 | 1285 | @{command simps_of_case} command provided by the theory
 | 
| 61304 | 1286 | @{file "~~/src/HOL/Library/Simps_Case_Conv.thy"}.
 | 
| 62081 | 1287 | \<close> | 
| 1288 | ||
| 1289 | simps_of_case at_simps_alt: at.simps | |
| 1290 | ||
| 1291 | text \<open> | |
| 1292 | This generates the lemma collection @{thm [source] at_simps_alt}:
 | |
| 54402 | 1293 | % | 
| 62081 | 1294 | \[@{thm at_simps_alt(1)[no_vars]}
 | 
| 1295 |   \qquad @{thm at_simps_alt(2)[no_vars]}\]
 | |
| 54402 | 1296 | % | 
| 54184 | 1297 | The next example is defined using \keyw{fun} to escape the syntactic
 | 
| 60135 
852f7a49ec0c
updated docs, esp. relating to 'datatype_compat'
 blanchet parents: 
60134diff
changeset | 1298 | restrictions imposed on primitively recursive functions: | 
| 62081 | 1299 | \<close> | 
| 52828 | 1300 | |
| 53621 | 1301 | fun at_least_two :: "nat \<Rightarrow> bool" where | 
| 62081 | 1302 | "at_least_two (Succ (Succ _)) \<longleftrightarrow> True" | 
| 1303 | | "at_least_two _ \<longleftrightarrow> False" | |
| 1304 | ||
| 1305 | ||
| 1306 | subsubsection \<open> Mutual Recursion | |
| 1307 |   \label{sssec:primrec-mutual-recursion} \<close>
 | |
| 1308 | ||
| 1309 | text \<open> | |
| 53621 | 1310 | The syntax for mutually recursive functions over mutually recursive datatypes | 
| 1311 | is straightforward: | |
| 62081 | 1312 | \<close> | 
| 52841 | 1313 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1314 | primrec | 
| 53623 | 1315 | nat_of_even_nat :: "even_nat \<Rightarrow> nat" and | 
| 1316 | nat_of_odd_nat :: "odd_nat \<Rightarrow> nat" | |
| 52841 | 1317 | where | 
| 62081 | 1318 | "nat_of_even_nat Even_Zero = Zero" | 
| 1319 | | "nat_of_even_nat (Even_Succ n) = Succ (nat_of_odd_nat n)" | |
| 1320 | | "nat_of_odd_nat (Odd_Succ n) = Succ (nat_of_even_nat n)" | |
| 1321 | ||
| 1322 | text \<open> \blankline \<close> | |
| 53752 | 1323 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1324 | primrec | 
| 53330 
77da8d3c46e0
fixed docs w.r.t. availability of "primrec_new" and friends
 blanchet parents: 
53262diff
changeset | 1325 |       eval\<^sub>e :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) exp \<Rightarrow> int" and
 | 
| 
77da8d3c46e0
fixed docs w.r.t. availability of "primrec_new" and friends
 blanchet parents: 
53262diff
changeset | 1326 |       eval\<^sub>t :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) trm \<Rightarrow> int" and
 | 
| 
77da8d3c46e0
fixed docs w.r.t. availability of "primrec_new" and friends
 blanchet parents: 
53262diff
changeset | 1327 |       eval\<^sub>f :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) fct \<Rightarrow> int"
 | 
| 52841 | 1328 | where | 
| 62081 | 1329 | "eval\<^sub>e \<gamma> \<xi> (Term t) = eval\<^sub>t \<gamma> \<xi> t" | 
| 1330 | | "eval\<^sub>e \<gamma> \<xi> (Sum t e) = eval\<^sub>t \<gamma> \<xi> t + eval\<^sub>e \<gamma> \<xi> e" | |
| 1331 | | "eval\<^sub>t \<gamma> \<xi> (Factor f) = eval\<^sub>f \<gamma> \<xi> f" | |
| 1332 | | "eval\<^sub>t \<gamma> \<xi> (Prod f t) = eval\<^sub>f \<gamma> \<xi> f + eval\<^sub>t \<gamma> \<xi> t" | |
| 1333 | | "eval\<^sub>f \<gamma> _ (Const a) = \<gamma> a" | |
| 1334 | | "eval\<^sub>f _ \<xi> (Var b) = \<xi> b" | |
| 1335 | | "eval\<^sub>f \<gamma> \<xi> (Expr e) = eval\<^sub>e \<gamma> \<xi> e" | |
| 1336 | ||
| 1337 | text \<open> | |
| 53621 | 1338 | \noindent | 
| 53647 | 1339 | Mutual recursion is possible within a single type, using \keyw{fun}:
 | 
| 62081 | 1340 | \<close> | 
| 52828 | 1341 | |
| 53621 | 1342 | fun | 
| 1343 | even :: "nat \<Rightarrow> bool" and | |
| 1344 | odd :: "nat \<Rightarrow> bool" | |
| 1345 | where | |
| 62081 | 1346 | "even Zero = True" | 
| 1347 | | "even (Succ n) = odd n" | |
| 1348 | | "odd Zero = False" | |
| 1349 | | "odd (Succ n) = even n" | |
| 1350 | ||
| 1351 | ||
| 1352 | subsubsection \<open> Nested Recursion | |
| 1353 |   \label{sssec:primrec-nested-recursion} \<close>
 | |
| 1354 | ||
| 1355 | text \<open> | |
| 53621 | 1356 | In a departure from the old datatype package, nested recursion is normally | 
| 1357 | handled via the map functions of the nesting type constructors. For example, | |
| 1358 | recursive calls are lifted to lists using @{const map}:
 | |
| 62081 | 1359 | \<close> | 
| 52828 | 1360 | |
| 52843 | 1361 | (*<*) | 
| 58310 | 1362 | datatype '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") | 
| 52843 | 1363 | (*>*) | 
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1364 | primrec at\<^sub>f\<^sub>f :: "'a tree\<^sub>f\<^sub>f \<Rightarrow> nat list \<Rightarrow> 'a" where | 
| 53028 | 1365 | "at\<^sub>f\<^sub>f (Node\<^sub>f\<^sub>f a ts) js = | 
| 52843 | 1366 | (case js of | 
| 1367 | [] \<Rightarrow> a | |
| 53028 | 1368 | | j # js' \<Rightarrow> at (map (\<lambda>t. at\<^sub>f\<^sub>f t js') ts) j)" | 
| 52843 | 1369 | |
| 62081 | 1370 | text \<open> | 
| 53647 | 1371 | \noindent | 
| 53621 | 1372 | The next example features recursion through the @{text option} type. Although
 | 
| 53623 | 1373 | @{text option} is not a new-style datatype, it is registered as a BNF with the
 | 
| 54491 | 1374 | map function @{const map_option}:
 | 
| 62081 | 1375 | \<close> | 
| 52843 | 1376 | |
| 61076 | 1377 |     primrec (*<*)(in early) (*>*)sum_btree :: "('a::{zero,plus}) btree \<Rightarrow> 'a" where
 | 
| 52843 | 1378 | "sum_btree (BNode a lt rt) = | 
| 54491 | 1379 | a + the_default 0 (map_option sum_btree lt) + | 
| 1380 | the_default 0 (map_option sum_btree rt)" | |
| 52843 | 1381 | |
| 62081 | 1382 | text \<open> | 
| 53621 | 1383 | \noindent | 
| 1384 | The same principle applies for arbitrary type constructors through which | |
| 1385 | recursion is possible. Notably, the map function for the function type | |
| 1386 | (@{text \<Rightarrow>}) is simply composition (@{text "op \<circ>"}):
 | |
| 62081 | 1387 | \<close> | 
| 52828 | 1388 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1389 |     primrec (*<*)(in early) (*>*)relabel_ft :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where
 | 
| 62081 | 1390 | "relabel_ft f (FTLeaf x) = FTLeaf (f x)" | 
| 1391 | | "relabel_ft f (FTNode g) = FTNode (relabel_ft f \<circ> g)" | |
| 1392 | ||
| 1393 | text \<open> | |
| 54182 | 1394 | \noindent | 
| 1395 | For convenience, recursion through functions can also be expressed using | |
| 1396 | $\lambda$-abstractions and function application rather than through composition. | |
| 1397 | For example: | |
| 62081 | 1398 | \<close> | 
| 54182 | 1399 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1400 |     primrec relabel_ft :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where
 | 
| 62081 | 1401 | "relabel_ft f (FTLeaf x) = FTLeaf (f x)" | 
| 1402 | | "relabel_ft f (FTNode g) = FTNode (\<lambda>x. relabel_ft f (g x))" | |
| 1403 | ||
| 1404 | text \<open> \blankline \<close> | |
| 54183 | 1405 | |
| 60136 | 1406 | primrec (nonexhaustive) subtree_ft :: "'a \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where | 
| 54183 | 1407 | "subtree_ft x (FTNode g) = g x" | 
| 1408 | ||
| 62081 | 1409 | text \<open> | 
| 53621 | 1410 | \noindent | 
| 54182 | 1411 | For recursion through curried $n$-ary functions, $n$ applications of | 
| 1412 | @{term "op \<circ>"} are necessary. The examples below illustrate the case where
 | |
| 1413 | $n = 2$: | |
| 62081 | 1414 | \<close> | 
| 53621 | 1415 | |
| 58310 | 1416 | datatype 'a ftree2 = FTLeaf2 'a | FTNode2 "'a \<Rightarrow> 'a \<Rightarrow> 'a ftree2" | 
| 54182 | 1417 | |
| 62081 | 1418 | text \<open> \blankline \<close> | 
| 54182 | 1419 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1420 |     primrec (*<*)(in early) (*>*)relabel_ft2 :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where
 | 
| 62081 | 1421 | "relabel_ft2 f (FTLeaf2 x) = FTLeaf2 (f x)" | 
| 1422 | | "relabel_ft2 f (FTNode2 g) = FTNode2 (op \<circ> (op \<circ> (relabel_ft2 f)) g)" | |
| 1423 | ||
| 1424 | text \<open> \blankline \<close> | |
| 54182 | 1425 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1426 |     primrec relabel_ft2 :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where
 | 
| 62081 | 1427 | "relabel_ft2 f (FTLeaf2 x) = FTLeaf2 (f x)" | 
| 1428 | | "relabel_ft2 f (FTNode2 g) = FTNode2 (\<lambda>x y. relabel_ft2 f (g x y))" | |
| 1429 | ||
| 1430 | text \<open> \blankline \<close> | |
| 54183 | 1431 | |
| 60136 | 1432 | primrec (nonexhaustive) subtree_ft2 :: "'a \<Rightarrow> 'a \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where | 
| 54183 | 1433 | "subtree_ft2 x y (FTNode2 g) = g x y" | 
| 1434 | ||
| 53621 | 1435 | |
| 62081 | 1436 | subsubsection \<open> Nested-as-Mutual Recursion | 
| 1437 |   \label{sssec:primrec-nested-as-mutual-recursion} \<close>
 | |
| 53621 | 1438 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1439 | (*<*) | 
| 59284 | 1440 | locale n2m | 
| 1441 | begin | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1442 | (*>*) | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1443 | |
| 62081 | 1444 | text \<open> | 
| 53621 | 1445 | For compatibility with the old package, but also because it is sometimes | 
| 1446 | convenient in its own right, it is possible to treat nested recursive datatypes | |
| 1447 | as mutually recursive ones if the recursion takes place though new-style | |
| 1448 | datatypes. For example: | |
| 62081 | 1449 | \<close> | 
| 52843 | 1450 | |
| 60136 | 1451 | primrec (nonexhaustive) | 
| 53647 | 1452 | at\<^sub>f\<^sub>f :: "'a tree\<^sub>f\<^sub>f \<Rightarrow> nat list \<Rightarrow> 'a" and | 
| 1453 | ats\<^sub>f\<^sub>f :: "'a tree\<^sub>f\<^sub>f list \<Rightarrow> nat \<Rightarrow> nat list \<Rightarrow> 'a" | |
| 52843 | 1454 | where | 
| 53647 | 1455 | "at\<^sub>f\<^sub>f (Node\<^sub>f\<^sub>f a ts) js = | 
| 52843 | 1456 | (case js of | 
| 1457 | [] \<Rightarrow> a | |
| 62081 | 1458 | | j # js' \<Rightarrow> ats\<^sub>f\<^sub>f ts j js')" | 
| 1459 | | "ats\<^sub>f\<^sub>f (t # ts) j = | |
| 52843 | 1460 | (case j of | 
| 53647 | 1461 | Zero \<Rightarrow> at\<^sub>f\<^sub>f t | 
| 58245 | 1462 | | Succ j' \<Rightarrow> ats\<^sub>f\<^sub>f ts j')" | 
| 52843 | 1463 | |
| 62081 | 1464 | text \<open> | 
| 53647 | 1465 | \noindent | 
| 54287 | 1466 | Appropriate induction rules are generated as | 
| 54031 | 1467 | @{thm [source] at\<^sub>f\<^sub>f.induct},
 | 
| 1468 | @{thm [source] ats\<^sub>f\<^sub>f.induct}, and
 | |
| 54287 | 1469 | @{thm [source] at\<^sub>f\<^sub>f_ats\<^sub>f\<^sub>f.induct}. The
 | 
| 1470 | induction rules and the underlying recursors are generated on a per-need basis | |
| 1471 | and are kept in a cache to speed up subsequent definitions. | |
| 53647 | 1472 | |
| 1473 | Here is a second example: | |
| 62081 | 1474 | \<close> | 
| 53621 | 1475 | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1476 | primrec | 
| 61076 | 1477 |       sum_btree :: "('a::{zero,plus}) btree \<Rightarrow> 'a" and
 | 
| 53330 
77da8d3c46e0
fixed docs w.r.t. availability of "primrec_new" and friends
 blanchet parents: 
53262diff
changeset | 1478 | sum_btree_option :: "'a btree option \<Rightarrow> 'a" | 
| 52843 | 1479 | where | 
| 1480 | "sum_btree (BNode a lt rt) = | |
| 62081 | 1481 | a + sum_btree_option lt + sum_btree_option rt" | 
| 1482 | | "sum_btree_option None = 0" | |
| 1483 | | "sum_btree_option (Some t) = sum_btree t" | |
| 1484 | ||
| 1485 | text \<open> | |
| 53621 | 1486 | % * can pretend a nested type is mutually recursive (if purely inductive) | 
| 1487 | % * avoids the higher-order map | |
| 1488 | % * e.g. | |
| 1489 | ||
| 53617 | 1490 | % * this can always be avoided; | 
| 1491 | % * e.g. in our previous example, we first mapped the recursive | |
| 1492 | % calls, then we used a generic at function to retrieve the result | |
| 1493 | % | |
| 1494 | % * there's no hard-and-fast rule of when to use one or the other, | |
| 1495 | % just like there's no rule when to use fold and when to use | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1496 | % primrec | 
| 53617 | 1497 | % | 
| 1498 | % * higher-order approach, considering nesting as nesting, is more | |
| 1499 | % compositional -- e.g. we saw how we could reuse an existing polymorphic | |
| 53647 | 1500 | %    at or the_default, whereas @{const ats\<^sub>f\<^sub>f} is much more specific
 | 
| 53617 | 1501 | % | 
| 1502 | % * but: | |
| 1503 | % * is perhaps less intuitive, because it requires higher-order thinking | |
| 1504 | % * may seem inefficient, and indeed with the code generator the | |
| 1505 | % mutually recursive version might be nicer | |
| 1506 | % * is somewhat indirect -- must apply a map first, then compute a result | |
| 1507 | % (cannot mix) | |
| 53647 | 1508 | %     * the auxiliary functions like @{const ats\<^sub>f\<^sub>f} are sometimes useful in own right
 | 
| 53617 | 1509 | % | 
| 1510 | % * impact on automation unclear | |
| 1511 | % | |
| 62081 | 1512 | \<close> | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1513 | (*<*) | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1514 | end | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1515 | (*>*) | 
| 52843 | 1516 | |
| 52824 | 1517 | |
| 62081 | 1518 | subsection \<open> Command Syntax | 
| 1519 |   \label{ssec:primrec-command-syntax} \<close>
 | |
| 1520 | ||
| 1521 | subsubsection \<open> \keyw{primrec}
 | |
| 1522 |   \label{sssec:primrec-new} \<close>
 | |
| 1523 | ||
| 1524 | text \<open> | |
| 53829 | 1525 | \begin{matharray}{rcl}
 | 
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1526 |   @{command_def "primrec"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | 
| 53829 | 1527 | \end{matharray}
 | 
| 52794 | 1528 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 1529 | @{rail \<open>
 | 
| 59277 | 1530 |   @@{command primrec} target? @{syntax pr_options}? fixes \<newline>
 | 
| 56123 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1531 |   @'where' (@{syntax pr_equation} + '|')
 | 
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1532 | ; | 
| 59282 | 1533 |   @{syntax_def pr_options}: '(' ((@{syntax plugins} | 'nonexhaustive' | 'transfer') + ',') ')'
 | 
| 52840 | 1534 | ; | 
| 53829 | 1535 |   @{syntax_def pr_equation}: thmdecl? prop
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 1536 | \<close>} | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1537 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1538 | \medskip | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1539 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1540 | \noindent | 
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1541 | The @{command primrec} command introduces a set of mutually recursive functions
 | 
| 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1542 | over datatypes. | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1543 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1544 | The syntactic entity \synt{target} can be used to specify a local context,
 | 
| 55474 | 1545 | \synt{fixes} denotes a list of names with optional type signatures,
 | 
| 1546 | \synt{thmdecl} denotes an optional name for the formula that follows, and
 | |
| 58620 | 1547 | \synt{prop} denotes a HOL proposition @{cite "isabelle-isar-ref"}.
 | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1548 | |
| 59280 | 1549 | The optional target is optionally followed by a combination of the following | 
| 1550 | options: | |
| 56123 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1551 | |
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1552 | \begin{itemize}
 | 
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1553 | \setlength{\itemsep}{0pt}
 | 
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1554 | |
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1555 | \item | 
| 59282 | 1556 | The @{text plugins} option indicates which plugins should be enabled
 | 
| 1557 | (@{text only}) or disabled (@{text del}). By default, all plugins are enabled.
 | |
| 1558 | ||
| 1559 | \item | |
| 1560 | The @{text nonexhaustive} option indicates that the functions are not
 | |
| 56123 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1561 | necessarily specified for all constructors. It can be used to suppress the | 
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1562 | warning that is normally emitted when some constructors are missing. | 
| 59277 | 1563 | |
| 1564 | \item | |
| 59282 | 1565 | The @{text transfer} option indicates that an unconditional transfer rule
 | 
| 59278 | 1566 | should be generated and proved @{text "by transfer_prover"}. The
 | 
| 1567 | @{text "[transfer_rule]"} attribute is set on the generated theorem.
 | |
| 56123 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1568 | \end{itemize}
 | 
| 
a27859b0ef7d
document the new 'nonexhaustive' option (cf. 52e8f110fec3)
 blanchet parents: 
55945diff
changeset | 1569 | |
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1570 | %%% TODO: elaborate on format of the equations | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 1571 | %%% TODO: elaborate on mutual and nested-to-mutual | 
| 62081 | 1572 | \<close> | 
| 1573 | ||
| 1574 | ||
| 1575 | subsection \<open> Generated Theorems | |
| 1576 |   \label{ssec:primrec-generated-theorems} \<close>
 | |
| 52824 | 1577 | |
| 59284 | 1578 | (*<*) | 
| 1579 | context early | |
| 1580 | begin | |
| 1581 | (*>*) | |
| 1582 | ||
| 62081 | 1583 | text \<open> | 
| 59284 | 1584 | The @{command primrec} command generates the following properties (listed
 | 
| 1585 | for @{const tfold}):
 | |
| 1586 | ||
| 1587 | \begin{indentblock}
 | |
| 1588 | \begin{description}
 | |
| 1589 | ||
| 1590 | \item[@{text "f."}\hthm{simps} @{text "[simp, code]"}\rm:] ~ \\
 | |
| 1591 | @{thm tfold.simps(1)[no_vars]} \\
 | |
| 1592 | @{thm tfold.simps(2)[no_vars]} \\
 | |
| 1593 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | |
| 1594 | (Section~\ref{ssec:code-generator}).
 | |
| 1595 | ||
| 1596 | \item[@{text "f."}\hthm{transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | |
| 1597 | @{thm tfold.transfer[no_vars]} \\
 | |
| 1598 | This theorem is generated by the @{text transfer} plugin
 | |
| 1599 | (Section~\ref{ssec:transfer}) for functions declared with the @{text transfer}
 | |
| 1600 | option enabled. | |
| 1601 | ||
| 1602 | \item[@{text "f."}\hthm{induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
 | |
| 1603 | This induction rule is generated for nested-as-mutual recursive functions | |
| 1604 | (Section~\ref{sssec:primrec-nested-as-mutual-recursion}).
 | |
| 1605 | ||
| 1606 | \item[@{text "f\<^sub>1_\<dots>_f\<^sub>m."}\hthm{induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rm:] ~ \\
 | |
| 1607 | This induction rule is generated for nested-as-mutual recursive functions | |
| 1608 | (Section~\ref{sssec:primrec-nested-as-mutual-recursion}). Given $m > 1$ mutually
 | |
| 1609 | recursive functions, this rule can be used to prove $m$ properties | |
| 1610 | simultaneously. | |
| 1611 | ||
| 1612 | \end{description}
 | |
| 1613 | \end{indentblock}
 | |
| 62081 | 1614 | \<close> | 
| 59284 | 1615 | |
| 1616 | (*<*) | |
| 1617 | end | |
| 1618 | (*>*) | |
| 53619 | 1619 | |
| 52824 | 1620 | |
| 62081 | 1621 | subsection \<open> Recursive Default Values for Selectors | 
| 1622 |   \label{ssec:primrec-recursive-default-values-for-selectors} \<close>
 | |
| 1623 | ||
| 1624 | text \<open> | |
| 52827 | 1625 | A datatype selector @{text un_D} can have a default value for each constructor
 | 
| 1626 | on which it is not otherwise specified. Occasionally, it is useful to have the | |
| 55354 | 1627 | default value be defined recursively. This leads to a chicken-and-egg | 
| 1628 | situation, because the datatype is not introduced yet at the moment when the | |
| 1629 | selectors are introduced. Of course, we can always define the selectors | |
| 1630 | manually afterward, but we then have to state and prove all the characteristic | |
| 1631 | theorems ourselves instead of letting the package do it. | |
| 1632 | ||
| 1633 | Fortunately, there is a workaround that relies on overloading to relieve us | |
| 1634 | from the tedium of manual derivations: | |
| 52827 | 1635 | |
| 1636 | \begin{enumerate}
 | |
| 1637 | \setlength{\itemsep}{0pt}
 | |
| 1638 | ||
| 1639 | \item | |
| 61076 | 1640 | Introduce a fully unspecified constant @{text "un_D\<^sub>0 :: 'a"} using
 | 
| 58931 | 1641 | @{command consts}.
 | 
| 52827 | 1642 | |
| 1643 | \item | |
| 53535 | 1644 | Define the datatype, specifying @{text "un_D\<^sub>0"} as the selector's default
 | 
| 1645 | value. | |
| 52827 | 1646 | |
| 1647 | \item | |
| 53535 | 1648 | Define the behavior of @{text "un_D\<^sub>0"} on values of the newly introduced
 | 
| 1649 | datatype using the \keyw{overloading} command.
 | |
| 52827 | 1650 | |
| 1651 | \item | |
| 1652 | Derive the desired equation on @{text un_D} from the characteristic equations
 | |
| 1653 | for @{text "un_D\<^sub>0"}.
 | |
| 1654 | \end{enumerate}
 | |
| 1655 | ||
| 53619 | 1656 | \noindent | 
| 52827 | 1657 | The following example illustrates this procedure: | 
| 62081 | 1658 | \<close> | 
| 52827 | 1659 | |
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1660 | (*<*) | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1661 | hide_const termi | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1662 | (*>*) | 
| 52827 | 1663 | consts termi\<^sub>0 :: 'a | 
| 1664 | ||
| 62081 | 1665 | text \<open> \blankline \<close> | 
| 53619 | 1666 | |
| 58310 | 1667 |     datatype ('a, 'b) tlist =
 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1668 | TNil (termi: 'b) | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1669 |     | TCons (thd: 'a) (ttl: "('a, 'b) tlist")
 | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1670 | where | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1671 | "ttl (TNil y) = TNil y" | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1672 | | "termi (TCons _ xs) = termi\<^sub>0 xs" | 
| 52827 | 1673 | |
| 62081 | 1674 | text \<open> \blankline \<close> | 
| 53619 | 1675 | |
| 52827 | 1676 | overloading | 
| 61076 | 1677 |       termi\<^sub>0 \<equiv> "termi\<^sub>0 :: ('a, 'b) tlist \<Rightarrow> 'b"
 | 
| 52827 | 1678 | begin | 
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1679 |     primrec termi\<^sub>0 :: "('a, 'b) tlist \<Rightarrow> 'b" where
 | 
| 62081 | 1680 | "termi\<^sub>0 (TNil y) = y" | 
| 1681 | | "termi\<^sub>0 (TCons x xs) = termi\<^sub>0 xs" | |
| 52827 | 1682 | end | 
| 1683 | ||
| 62081 | 1684 | text \<open> \blankline \<close> | 
| 53619 | 1685 | |
| 55354 | 1686 | lemma termi_TCons[simp]: "termi (TCons x xs) = termi xs" | 
| 60152 | 1687 | by (cases xs) auto | 
| 52827 | 1688 | |
| 1689 | ||
| 62081 | 1690 | subsection \<open> Compatibility Issues | 
| 1691 |   \label{ssec:primrec-compatibility-issues} \<close>
 | |
| 1692 | ||
| 1693 | text \<open> | |
| 55530 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1694 | The command @{command primrec}'s behavior on new-style datatypes has been
 | 
| 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1695 | designed to be highly compatible with that for old-style datatypes, to ease | 
| 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1696 | migration. There is nonetheless at least one incompatibility that may arise when | 
| 
3dfb724db099
renamed 'primrec_new' to 'primrec', overriding the old command (which it still uses as a fallback for old-style datatypes)
 blanchet parents: 
55474diff
changeset | 1697 | porting to the new package: | 
| 53997 | 1698 | |
| 1699 | \begin{itemize}
 | |
| 1700 | \setlength{\itemsep}{0pt}
 | |
| 1701 | ||
| 54185 | 1702 | \item \emph{Some theorems have different names.}
 | 
| 53997 | 1703 | For $m > 1$ mutually recursive functions, | 
| 54023 
cede3c1d2417
minor doc fix (there is no guarantee that the equations for a given f_i are contiguous in the collection)
 blanchet parents: 
54014diff
changeset | 1704 | @{text "f\<^sub>1_\<dots>_f\<^sub>m.simps"} has been broken down into separate
 | 
| 
cede3c1d2417
minor doc fix (there is no guarantee that the equations for a given f_i are contiguous in the collection)
 blanchet parents: 
54014diff
changeset | 1705 | subcollections @{text "f\<^sub>i.simps"}.
 | 
| 53997 | 1706 | \end{itemize}
 | 
| 62081 | 1707 | \<close> | 
| 1708 | ||
| 1709 | ||
| 1710 | section \<open> Defining Codatatypes | |
| 1711 |   \label{sec:defining-codatatypes} \<close>
 | |
| 1712 | ||
| 1713 | text \<open> | |
| 53829 | 1714 | Codatatypes can be specified using the @{command codatatype} command. The
 | 
| 53623 | 1715 | command is first illustrated through concrete examples featuring different | 
| 1716 | flavors of corecursion. More examples can be found in the directory | |
| 61304 | 1717 | @{file "~~/src/HOL/Datatype_Examples"}. The \emph{Archive of Formal Proofs} also
 | 
| 1718 | includes some useful codatatypes, notably for lazy lists @{cite
 | |
| 1719 | "lochbihler-2010"}. | |
| 62081 | 1720 | \<close> | 
| 1721 | ||
| 1722 | ||
| 1723 | subsection \<open> Introductory Examples | |
| 1724 |   \label{ssec:codatatype-introductory-examples} \<close>
 | |
| 1725 | ||
| 1726 | subsubsection \<open> Simple Corecursion | |
| 1727 |   \label{sssec:codatatype-simple-corecursion} \<close>
 | |
| 1728 | ||
| 1729 | text \<open> | |
| 57542 | 1730 | Non-corecursive codatatypes coincide with the corresponding datatypes, so they | 
| 56947 | 1731 | are rarely used in practice. \emph{Corecursive codatatypes} have the same syntax
 | 
| 53623 | 1732 | as recursive datatypes, except for the command name. For example, here is the | 
| 1733 | definition of lazy lists: | |
| 62081 | 1734 | \<close> | 
| 53623 | 1735 | |
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1736 | codatatype (lset: 'a) llist = | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1737 | lnull: LNil | 
| 53623 | 1738 | | LCons (lhd: 'a) (ltl: "'a llist") | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1739 | for | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1740 | map: lmap | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1741 | rel: llist_all2 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1742 | where | 
| 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 1743 | "ltl LNil = LNil" | 
| 53623 | 1744 | |
| 62081 | 1745 | text \<open> | 
| 53623 | 1746 | \noindent | 
| 1747 | Lazy lists can be infinite, such as @{text "LCons 0 (LCons 0 (\<dots>))"} and
 | |
| 53647 | 1748 | @{text "LCons 0 (LCons 1 (LCons 2 (\<dots>)))"}. Here is a related type, that of
 | 
| 1749 | infinite streams: | |
| 62081 | 1750 | \<close> | 
| 53647 | 1751 | |
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1752 | codatatype (sset: 'a) stream = | 
| 53647 | 1753 | SCons (shd: 'a) (stl: "'a stream") | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1754 | for | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1755 | map: smap | 
| 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 1756 | rel: stream_all2 | 
| 53647 | 1757 | |
| 62081 | 1758 | text \<open> | 
| 53647 | 1759 | \noindent | 
| 1760 | Another interesting type that can | |
| 53623 | 1761 | be defined as a codatatype is that of the extended natural numbers: | 
| 62081 | 1762 | \<close> | 
| 53623 | 1763 | |
| 58245 | 1764 | codatatype enat = EZero | ESucc enat | 
| 53623 | 1765 | |
| 62081 | 1766 | text \<open> | 
| 53623 | 1767 | \noindent | 
| 58245 | 1768 | This type has exactly one infinite element, @{text "ESucc (ESucc (ESucc (\<dots>)))"},
 | 
| 53623 | 1769 | that represents $\infty$. In addition, it has finite values of the form | 
| 58245 | 1770 | @{text "ESucc (\<dots> (ESucc EZero)\<dots>)"}.
 | 
| 53675 | 1771 | |
| 1772 | Here is an example with many constructors: | |
| 62081 | 1773 | \<close> | 
| 53623 | 1774 | |
| 53675 | 1775 | codatatype 'a process = | 
| 1776 | Fail | |
| 1777 | | Skip (cont: "'a process") | |
| 1778 | | Action (prefix: 'a) (cont: "'a process") | |
| 1779 | | Choice (left: "'a process") (right: "'a process") | |
| 1780 | ||
| 62081 | 1781 | text \<open> | 
| 53829 | 1782 | \noindent | 
| 53750 | 1783 | Notice that the @{const cont} selector is associated with both @{const Skip}
 | 
| 54146 | 1784 | and @{const Action}.
 | 
| 62081 | 1785 | \<close> | 
| 1786 | ||
| 1787 | ||
| 1788 | subsubsection \<open> Mutual Corecursion | |
| 1789 |   \label{sssec:codatatype-mutual-corecursion} \<close>
 | |
| 1790 | ||
| 1791 | text \<open> | |
| 53623 | 1792 | \noindent | 
| 1793 | The example below introduces a pair of \emph{mutually corecursive} types:
 | |
| 62081 | 1794 | \<close> | 
| 53623 | 1795 | |
| 58245 | 1796 | codatatype even_enat = Even_EZero | Even_ESucc odd_enat | 
| 1797 | and odd_enat = Odd_ESucc even_enat | |
| 53623 | 1798 | |
| 1799 | ||
| 62081 | 1800 | subsubsection \<open> Nested Corecursion | 
| 1801 |   \label{sssec:codatatype-nested-corecursion} \<close>
 | |
| 1802 | ||
| 1803 | text \<open> | |
| 53623 | 1804 | \noindent | 
| 53675 | 1805 | The next examples feature \emph{nested corecursion}:
 | 
| 62081 | 1806 | \<close> | 
| 53623 | 1807 | |
| 53644 | 1808 | 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") | 
| 53675 | 1809 | |
| 62081 | 1810 | text \<open> \blankline \<close> | 
| 53752 | 1811 | |
| 53644 | 1812 | 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") | 
| 52805 | 1813 | |
| 62081 | 1814 | text \<open> \blankline \<close> | 
| 53752 | 1815 | |
| 55350 | 1816 | codatatype 'a sm = SM (accept: bool) (trans: "'a \<Rightarrow> 'a sm") | 
| 53675 | 1817 | |
| 52824 | 1818 | |
| 62081 | 1819 | subsection \<open> Command Syntax | 
| 1820 |   \label{ssec:codatatype-command-syntax} \<close>
 | |
| 1821 | ||
| 1822 | subsubsection \<open> \keyw{codatatype}
 | |
| 1823 |   \label{sssec:codatatype} \<close>
 | |
| 1824 | ||
| 1825 | text \<open> | |
| 53829 | 1826 | \begin{matharray}{rcl}
 | 
| 1827 |   @{command_def "codatatype"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | |
| 1828 | \end{matharray}
 | |
| 1829 | ||
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 1830 | @{rail \<open>
 | 
| 59282 | 1831 |   @@{command codatatype} target? @{syntax dt_options}? @{syntax dt_spec}
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 1832 | \<close>} | 
| 53829 | 1833 | |
| 55351 | 1834 | \medskip | 
| 1835 | ||
| 53829 | 1836 | \noindent | 
| 52827 | 1837 | Definitions of codatatypes have almost exactly the same syntax as for datatypes | 
| 57094 
589ec121ce1a
don't generate discriminators and selectors for 'datatype_new' unless the user asked for it
 blanchet parents: 
57092diff
changeset | 1838 | (Section~\ref{ssec:datatype-command-syntax}). The @{text "discs_sels"} option
 | 
| 
589ec121ce1a
don't generate discriminators and selectors for 'datatype_new' unless the user asked for it
 blanchet parents: 
57092diff
changeset | 1839 | is superfluous because discriminators and selectors are always generated for | 
| 
589ec121ce1a
don't generate discriminators and selectors for 'datatype_new' unless the user asked for it
 blanchet parents: 
57092diff
changeset | 1840 | codatatypes. | 
| 62081 | 1841 | \<close> | 
| 1842 | ||
| 1843 | ||
| 1844 | subsection \<open> Generated Constants | |
| 1845 |   \label{ssec:codatatype-generated-constants} \<close>
 | |
| 1846 | ||
| 1847 | text \<open> | |
| 53623 | 1848 | Given a codatatype @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"}
 | 
| 1849 | with $m > 0$ live type variables and $n$ constructors @{text "t.C\<^sub>1"},
 | |
| 1850 | \ldots, @{text "t.C\<^sub>n"}, the same auxiliary constants are generated as for
 | |
| 1851 | datatypes (Section~\ref{ssec:datatype-generated-constants}), except that the
 | |
| 58190 | 1852 | recursor is replaced by a dual concept: | 
| 53623 | 1853 | |
| 55354 | 1854 | \medskip | 
| 1855 | ||
| 1856 | \begin{tabular}{@ {}ll@ {}}
 | |
| 1857 | Corecursor: & | |
| 56655 | 1858 |   @{text t.corec_t}
 | 
| 55354 | 1859 | \end{tabular}
 | 
| 62081 | 1860 | \<close> | 
| 1861 | ||
| 1862 | ||
| 1863 | subsection \<open> Generated Theorems | |
| 1864 |   \label{ssec:codatatype-generated-theorems} \<close>
 | |
| 1865 | ||
| 1866 | text \<open> | |
| 53829 | 1867 | The characteristic theorems generated by @{command codatatype} are grouped in
 | 
| 53623 | 1868 | three broad categories: | 
| 1869 | ||
| 1870 | \begin{itemize}
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1871 | \setlength{\itemsep}{0pt}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1872 | |
| 56655 | 1873 | \item The \emph{free constructor theorems}
 | 
| 1874 | (Section~\ref{sssec:free-constructor-theorems}) are properties of the
 | |
| 1875 | constructors and destructors that can be derived for any freely generated type. | |
| 1876 | ||
| 1877 | \item The \emph{functorial theorems}
 | |
| 1878 | (Section~\ref{sssec:functorial-theorems}) are properties of datatypes related to
 | |
| 53623 | 1879 | their BNF nature. | 
| 1880 | ||
| 56655 | 1881 | \item The \emph{coinductive theorems} (Section~\ref{sssec:coinductive-theorems})
 | 
| 1882 | are properties of datatypes related to their coinductive nature. | |
| 53623 | 1883 | \end{itemize}
 | 
| 1884 | ||
| 1885 | \noindent | |
| 56655 | 1886 | The first two categories are exactly as for datatypes. | 
| 62081 | 1887 | \<close> | 
| 1888 | ||
| 1889 | ||
| 1890 | subsubsection \<open> Coinductive Theorems | |
| 1891 |   \label{sssec:coinductive-theorems} \<close>
 | |
| 1892 | ||
| 1893 | text \<open> | |
| 54031 | 1894 | The coinductive theorems are listed below for @{typ "'a llist"}:
 | 
| 53623 | 1895 | |
| 1896 | \begin{indentblock}
 | |
| 1897 | \begin{description}
 | |
| 1898 | ||
| 53643 | 1899 | \item[\begin{tabular}{@ {}l@ {}}
 | 
| 57304 | 1900 |   @{text "t."}\hthm{coinduct} @{text "[consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | 
| 1901 |   \phantom{@{text "t."}\hthm{coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots>
 | |
| 1902 | D\<^sub>n, coinduct t]"}\rm: | |
| 53643 | 1903 | \end{tabular}] ~ \\
 | 
| 53623 | 1904 | @{thm llist.coinduct[no_vars]}
 | 
| 53617 | 1905 | |
| 53643 | 1906 | \item[\begin{tabular}{@ {}l@ {}}
 | 
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1907 |   @{text "t."}\hthm{coinduct_strong} @{text "[consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1908 |   \phantom{@{text "t."}\hthm{coinduct_strong} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"}\rm:
 | 
| 53643 | 1909 | \end{tabular}] ~ \\
 | 
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1910 | @{thm llist.coinduct_strong[no_vars]}
 | 
| 53617 | 1911 | |
| 53643 | 1912 | \item[\begin{tabular}{@ {}l@ {}}
 | 
| 57304 | 1913 |   @{text "t."}\hthm{rel_coinduct} @{text "[consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | 
| 1914 |   \phantom{@{text "t."}\hthm{rel_coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots>
 | |
| 1915 | D\<^sub>n, coinduct pred]"}\rm: | |
| 1916 | \end{tabular}] ~ \\
 | |
| 1917 | @{thm llist.rel_coinduct[no_vars]}
 | |
| 1918 | ||
| 1919 | \item[\begin{tabular}{@ {}l@ {}}
 | |
| 53643 | 1920 |   @{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]"} \\
 | 
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1921 |   @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{coinduct_strong} @{text "[case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1922 |   \phantom{@{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{coinduct_strong} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"}\rm: \\
 | 
| 57542 | 1923 |   @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{rel_coinduct} @{text "[case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | 
| 1924 |   \phantom{@{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{rel_coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> D\<^sub>n]"}\rm: \\
 | |
| 53643 | 1925 | \end{tabular}] ~ \\
 | 
| 1926 | Given $m > 1$ mutually corecursive codatatypes, these coinduction rules can be | |
| 1927 | used to prove $m$ properties simultaneously. | |
| 1928 | ||
| 57701 | 1929 | \item[\begin{tabular}{@ {}l@ {}}
 | 
| 1930 |   @{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{set_induct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n,"} \\
 | |
| 1931 |   \phantom{@{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{set_induct} @{text "["}}@{text "induct set: set\<^sub>j_t\<^sub>1, \<dots>, induct set: set\<^sub>j_t\<^sub>m]"}\rm: \\
 | |
| 1932 | \end{tabular}] ~ \\
 | |
| 1933 | @{thm llist.set_induct[no_vars]} \\
 | |
| 1934 | If $m = 1$, the attribute @{text "[consumes 1]"} is generated as well.
 | |
| 1935 | ||
| 54031 | 1936 | \item[@{text "t."}\hthm{corec}\rm:] ~ \\
 | 
| 53623 | 1937 | @{thm llist.corec(1)[no_vars]} \\
 | 
| 1938 | @{thm llist.corec(2)[no_vars]}
 | |
| 1939 | ||
| 57542 | 1940 | \item[@{text "t."}\hthm{corec_code} @{text "[code]"}\rm:] ~ \\
 | 
| 58335 
a5a3b576fcfb
generate 'code' attribute only if 'code' plugin is enabled
 blanchet parents: 
58311diff
changeset | 1941 | @{thm llist.corec_code[no_vars]} \\
 | 
| 59284 | 1942 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | 
| 1943 | (Section~\ref{ssec:code-generator}).
 | |
| 57490 | 1944 | |
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1945 | \item[@{text "t."}\hthm{corec_disc}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1946 | @{thm llist.corec_disc(1)[no_vars]} \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1947 | @{thm llist.corec_disc(2)[no_vars]}
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1948 | |
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1949 | \item[@{text "t."}\hthm{corec_disc_iff} @{text "[simp]"}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1950 | @{thm llist.corec_disc_iff(1)[no_vars]} \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1951 | @{thm llist.corec_disc_iff(2)[no_vars]}
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1952 | |
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1953 | \item[@{text "t."}\hthm{corec_sel} @{text "[simp]"}\rm:] ~ \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1954 | @{thm llist.corec_sel(1)[no_vars]} \\
 | 
| 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 1955 | @{thm llist.corec_sel(2)[no_vars]}
 | 
| 53643 | 1956 | |
| 58735 | 1957 | \item[@{text "t."}\hthm{map_o_corec}\rm:] ~ \\
 | 
| 1958 | @{thm llist.map_o_corec[no_vars]}
 | |
| 1959 | ||
| 58915 | 1960 | \item[@{text "t."}\hthm{corec_transfer} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 1961 | @{thm llist.corec_transfer[no_vars]} \\
 | |
| 59284 | 1962 | The @{text "[transfer_rule]"} attribute is set by the @{text transfer} plugin
 | 
| 59824 | 1963 | (Section~\ref{ssec:transfer}) for type constructors with no dead type arguments.
 | 
| 58449 | 1964 | |
| 53623 | 1965 | \end{description}
 | 
| 1966 | \end{indentblock}
 | |
| 1967 | ||
| 1968 | \noindent | |
| 53829 | 1969 | For convenience, @{command codatatype} also provides the following collection:
 | 
| 53623 | 1970 | |
| 1971 | \begin{indentblock}
 | |
| 1972 | \begin{description}
 | |
| 1973 | ||
| 59284 | 1974 | \item[@{text "t."}\hthm{simps}] = @{text t.inject} @{text t.distinct} @{text t.case} @{text t.corec_disc_iff} @{text t.corec_sel} \\
 | 
| 55896 | 1975 | @{text t.map} @{text t.rel_inject} @{text t.rel_distinct} @{text t.set}
 | 
| 53623 | 1976 | |
| 1977 | \end{description}
 | |
| 1978 | \end{indentblock}
 | |
| 62081 | 1979 | \<close> | 
| 1980 | ||
| 1981 | ||
| 1982 | section \<open> Defining Primitively Corecursive Functions | |
| 1983 |   \label{sec:defining-primitively-corecursive-functions} \<close>
 | |
| 1984 | ||
| 1985 | text \<open> | |
| 54183 | 1986 | Corecursive functions can be specified using the @{command primcorec} and
 | 
| 61788 | 1987 | \keyw{prim\-corec\-ursive} commands, which support primitive corecursion.
 | 
| 1988 | Other approaches include the more general \keyw{partial_function} command, the
 | |
| 1989 | forthcoming \keyw{corec} command @{cite "blanchette-et-al-2015-corec"}, and
 | |
| 1990 | techniques based on domains and topologies @{cite "lochbihler-hoelzl-2014"}.
 | |
| 1991 | In this tutorial, the focus is on @{command primcorec} and
 | |
| 1992 | @{command primcorecursive}. More examples can be found in the directory
 | |
| 61304 | 1993 | @{file "~~/src/HOL/Datatype_Examples"}.
 | 
| 53644 | 1994 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1995 | Whereas recursive functions consume datatypes one constructor at a time, | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1996 | corecursive functions construct codatatypes one constructor at a time. | 
| 53752 | 1997 | Partly reflecting a lack of agreement among proponents of coalgebraic methods, | 
| 1998 | Isabelle supports three competing syntaxes for specifying a function $f$: | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 1999 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2000 | \begin{itemize}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2001 | \setlength{\itemsep}{0pt}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2002 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2003 | \abovedisplayskip=.5\abovedisplayskip | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2004 | \belowdisplayskip=.5\belowdisplayskip | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2005 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2006 | \item The \emph{destructor view} specifies $f$ by implications of the form
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2007 | \[@{text "\<dots> \<Longrightarrow> is_C\<^sub>j (f x\<^sub>1 \<dots> x\<^sub>n)"}\] and
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2008 | equations of the form | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2009 | \[@{text "un_C\<^sub>ji (f x\<^sub>1 \<dots> x\<^sub>n) = \<dots>"}\]
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2010 | This style is popular in the coalgebraic literature. | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2011 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2012 | \item The \emph{constructor view} specifies $f$ by equations of the form
 | 
| 54183 | 2013 | \[@{text "\<dots> \<Longrightarrow> f x\<^sub>1 \<dots> x\<^sub>n = C\<^sub>j \<dots>"}\]
 | 
| 53752 | 2014 | This style is often more concise than the previous one. | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2015 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2016 | \item The \emph{code view} specifies $f$ by a single equation of the form
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2017 | \[@{text "f x\<^sub>1 \<dots> x\<^sub>n = \<dots>"}\]
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2018 | with restrictions on the format of the right-hand side. Lazy functional | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2019 | programming languages such as Haskell support a generalized version of this | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2020 | style. | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2021 | \end{itemize}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2022 | |
| 53753 
ae7f50e70c09
renamed "primcorec" to "primcorecursive", to open the door to a 'theory -> theory' command called "primcorec" (cf. "fun" vs. "function")
 blanchet parents: 
53752diff
changeset | 2023 | All three styles are available as input syntax. Whichever syntax is chosen, | 
| 
ae7f50e70c09
renamed "primcorec" to "primcorecursive", to open the door to a 'theory -> theory' command called "primcorec" (cf. "fun" vs. "function")
 blanchet parents: 
53752diff
changeset | 2024 | characteristic theorems for all three styles are generated. | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2025 | |
| 52828 | 2026 | %%% TODO: partial_function? E.g. for defining tail recursive function on lazy | 
| 2027 | %%% lists (cf. terminal0 in TLList.thy) | |
| 62081 | 2028 | \<close> | 
| 2029 | ||
| 2030 | ||
| 2031 | subsection \<open> Introductory Examples | |
| 2032 |   \label{ssec:primcorec-introductory-examples} \<close>
 | |
| 2033 | ||
| 2034 | text \<open> | |
| 53646 | 2035 | Primitive corecursion is illustrated through concrete examples based on the | 
| 2036 | codatatypes defined in Section~\ref{ssec:codatatype-introductory-examples}. More
 | |
| 61304 | 2037 | examples can be found in the directory @{file "~~/src/HOL/Datatype_Examples"}.
 | 
| 2038 | The code view is favored in the examples below. Sections | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2039 | \ref{ssec:primrec-constructor-view} and \ref{ssec:primrec-destructor-view}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2040 | present the same examples expressed using the constructor and destructor views. | 
| 62081 | 2041 | \<close> | 
| 2042 | ||
| 2043 | ||
| 2044 | subsubsection \<open> Simple Corecursion | |
| 2045 |   \label{sssec:primcorec-simple-corecursion} \<close>
 | |
| 2046 | ||
| 2047 | text \<open> | |
| 53752 | 2048 | Following the code view, corecursive calls are allowed on the right-hand side as | 
| 2049 | long as they occur under a constructor, which itself appears either directly to | |
| 2050 | the right of the equal sign or in a conditional expression: | |
| 62081 | 2051 | \<close> | 
| 53646 | 2052 | |
| 59284 | 2053 |     primcorec (*<*)(transfer) (*>*)literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where
 | 
| 54072 | 2054 | "literate g x = LCons x (literate g (g x))" | 
| 53647 | 2055 | |
| 62081 | 2056 | text \<open> \blankline \<close> | 
| 53677 | 2057 | |
| 53826 | 2058 |     primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where
 | 
| 54072 | 2059 | "siterate g x = SCons x (siterate g (g x))" | 
| 53644 | 2060 | |
| 62081 | 2061 | text \<open> | 
| 53646 | 2062 | \noindent | 
| 2063 | The constructor ensures that progress is made---i.e., the function is | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2064 | \emph{productive}. The above functions compute the infinite lazy list or stream
 | 
| 54072 | 2065 | @{text "[x, g x, g (g x), \<dots>]"}. Productivity guarantees that prefixes
 | 
| 2066 | @{text "[x, g x, g (g x), \<dots>, (g ^^ k) x]"} of arbitrary finite length
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2067 | @{text k} can be computed by unfolding the code equation a finite number of
 | 
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 2068 | times. | 
| 53646 | 2069 | |
| 53752 | 2070 | Corecursive functions construct codatatype values, but nothing prevents them | 
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 2071 | from also consuming such values. The following function drops every second | 
| 53675 | 2072 | element in a stream: | 
| 62081 | 2073 | \<close> | 
| 53675 | 2074 | |
| 53826 | 2075 | primcorec every_snd :: "'a stream \<Rightarrow> 'a stream" where | 
| 53675 | 2076 | "every_snd s = SCons (shd s) (stl (stl s))" | 
| 2077 | ||
| 62081 | 2078 | text \<open> | 
| 53752 | 2079 | \noindent | 
| 56124 | 2080 | Constructs such as @{text "let"}--@{text "in"}, @{text
 | 
| 2081 | "if"}--@{text "then"}--@{text "else"}, and @{text "case"}--@{text "of"} may
 | |
| 53646 | 2082 | appear around constructors that guard corecursive calls: | 
| 62081 | 2083 | \<close> | 
| 2084 | ||
| 2085 | primcorec lapp :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where | |
| 2086 | "lapp xs ys = | |
| 53644 | 2087 | (case xs of | 
| 2088 | LNil \<Rightarrow> ys | |
| 62081 | 2089 | | LCons x xs' \<Rightarrow> LCons x (lapp xs' ys))" | 
| 2090 | ||
| 2091 | text \<open> | |
| 53752 | 2092 | \noindent | 
| 54402 | 2093 | Pattern matching is not supported by @{command primcorec}. Fortunately, it is
 | 
| 62081 | 2094 | easy to generate pattern-maching equations using the @{command simps_of_case}
 | 
| 61304 | 2095 | command provided by the theory @{file "~~/src/HOL/Library/Simps_Case_Conv.thy"}.
 | 
| 62081 | 2096 | \<close> | 
| 2097 | ||
| 2098 | simps_of_case lapp_simps: lapp.code | |
| 2099 | ||
| 2100 | text \<open> | |
| 2101 | This generates the lemma collection @{thm [source] lapp_simps}:
 | |
| 54402 | 2102 | % | 
| 62081 | 2103 | \begin{gather*}
 | 
| 2104 |   @{thm lapp_simps(1)[no_vars]} \\
 | |
| 2105 |   @{thm lapp_simps(2)[no_vars]}
 | |
| 2106 | \end{gather*}
 | |
| 54402 | 2107 | % | 
| 53646 | 2108 | Corecursion is useful to specify not only functions but also infinite objects: | 
| 62081 | 2109 | \<close> | 
| 53646 | 2110 | |
| 53826 | 2111 | primcorec infty :: enat where | 
| 58245 | 2112 | "infty = ESucc infty" | 
| 53644 | 2113 | |
| 62081 | 2114 | text \<open> | 
| 53752 | 2115 | \noindent | 
| 2116 | The example below constructs a pseudorandom process value. It takes a stream of | |
| 53675 | 2117 | actions (@{text s}), a pseudorandom function generator (@{text f}), and a
 | 
| 2118 | pseudorandom seed (@{text n}):
 | |
| 62081 | 2119 | \<close> | 
| 53675 | 2120 | |
| 59861 | 2121 | (*<*) | 
| 2122 | context early | |
| 2123 | begin | |
| 2124 | (*>*) | |
| 2125 | primcorec | |
| 53752 | 2126 | random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process" | 
| 2127 | where | |
| 53675 | 2128 | "random_process s f n = | 
| 2129 | (if n mod 4 = 0 then | |
| 2130 | Fail | |
| 2131 | else if n mod 4 = 1 then | |
| 2132 | Skip (random_process s f (f n)) | |
| 2133 | else if n mod 4 = 2 then | |
| 2134 | Action (shd s) (random_process (stl s) f (f n)) | |
| 2135 | else | |
| 2136 | Choice (random_process (every_snd s) (f \<circ> f) (f n)) | |
| 2137 | (random_process (every_snd (stl s)) (f \<circ> f) (f (f n))))" | |
| 59861 | 2138 | (*<*) | 
| 2139 | end | |
| 2140 | (*>*) | |
| 53675 | 2141 | |
| 62081 | 2142 | text \<open> | 
| 53675 | 2143 | \noindent | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2144 | The main disadvantage of the code view is that the conditions are tested | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2145 | sequentially. This is visible in the generated theorems. The constructor and | 
| 53752 | 2146 | destructor views offer nonsequential alternatives. | 
| 62081 | 2147 | \<close> | 
| 2148 | ||
| 2149 | ||
| 2150 | subsubsection \<open> Mutual Corecursion | |
| 2151 |   \label{sssec:primcorec-mutual-corecursion} \<close>
 | |
| 2152 | ||
| 2153 | text \<open> | |
| 53647 | 2154 | The syntax for mutually corecursive functions over mutually corecursive | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2155 | datatypes is unsurprising: | 
| 62081 | 2156 | \<close> | 
| 53647 | 2157 | |
| 53826 | 2158 | primcorec | 
| 53644 | 2159 | even_infty :: even_enat and | 
| 2160 | odd_infty :: odd_enat | |
| 2161 | where | |
| 62081 | 2162 | "even_infty = Even_ESucc odd_infty" | 
| 2163 | | "odd_infty = Odd_ESucc even_infty" | |
| 2164 | ||
| 2165 | ||
| 2166 | subsubsection \<open> Nested Corecursion | |
| 2167 |   \label{sssec:primcorec-nested-corecursion} \<close>
 | |
| 2168 | ||
| 2169 | text \<open> | |
| 53647 | 2170 | The next pair of examples generalize the @{const literate} and @{const siterate}
 | 
| 2171 | functions (Section~\ref{sssec:primcorec-nested-corecursion}) to possibly
 | |
| 2172 | infinite trees in which subnodes are organized either as a lazy list (@{text
 | |
| 54072 | 2173 | tree\<^sub>i\<^sub>i}) or as a finite set (@{text tree\<^sub>i\<^sub>s}). They rely on the map functions of
 | 
| 2174 | the nesting type constructors to lift the corecursive calls: | |
| 62081 | 2175 | \<close> | 
| 53647 | 2176 | |
| 53826 | 2177 |     primcorec iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where
 | 
| 54072 | 2178 | "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (lmap (iterate\<^sub>i\<^sub>i g) (g x))" | 
| 53644 | 2179 | |
| 62081 | 2180 | text \<open> \blankline \<close> | 
| 53677 | 2181 | |
| 53826 | 2182 |     primcorec iterate\<^sub>i\<^sub>s :: "('a \<Rightarrow> 'a fset) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>s" where
 | 
| 54072 | 2183 | "iterate\<^sub>i\<^sub>s g x = Node\<^sub>i\<^sub>s x (fimage (iterate\<^sub>i\<^sub>s g) (g x))" | 
| 53644 | 2184 | |
| 62081 | 2185 | text \<open> | 
| 53752 | 2186 | \noindent | 
| 54072 | 2187 | Both examples follow the usual format for constructor arguments associated | 
| 2188 | with nested recursive occurrences of the datatype. Consider | |
| 2189 | @{const iterate\<^sub>i\<^sub>i}. The term @{term "g x"} constructs an @{typ "'a llist"}
 | |
| 2190 | value, which is turned into an @{typ "'a tree\<^sub>i\<^sub>i llist"} value using
 | |
| 2191 | @{const lmap}.
 | |
| 2192 | ||
| 2193 | This format may sometimes feel artificial. The following function constructs | |
| 2194 | a tree with a single, infinite branch from a stream: | |
| 62081 | 2195 | \<close> | 
| 54072 | 2196 | |
| 2197 | primcorec tree\<^sub>i\<^sub>i_of_stream :: "'a stream \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where | |
| 2198 | "tree\<^sub>i\<^sub>i_of_stream s = | |
| 2199 | Node\<^sub>i\<^sub>i (shd s) (lmap tree\<^sub>i\<^sub>i_of_stream (LCons (stl s) LNil))" | |
| 2200 | ||
| 62081 | 2201 | text \<open> | 
| 54072 | 2202 | \noindent | 
| 54955 
cf8d429dc24e
reintroduce recursive calls under constructors, taken out in 8dd0e0316881 mainly and in subsequent changes
 blanchet parents: 
54832diff
changeset | 2203 | A more natural syntax, also supported by Isabelle, is to move corecursive calls | 
| 
cf8d429dc24e
reintroduce recursive calls under constructors, taken out in 8dd0e0316881 mainly and in subsequent changes
 blanchet parents: 
54832diff
changeset | 2204 | under constructors: | 
| 62081 | 2205 | \<close> | 
| 54072 | 2206 | |
| 54955 
cf8d429dc24e
reintroduce recursive calls under constructors, taken out in 8dd0e0316881 mainly and in subsequent changes
 blanchet parents: 
54832diff
changeset | 2207 | primcorec (*<*)(in late) (*>*)tree\<^sub>i\<^sub>i_of_stream :: "'a stream \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where | 
| 55350 | 2208 | "tree\<^sub>i\<^sub>i_of_stream s = | 
| 2209 | Node\<^sub>i\<^sub>i (shd s) (LCons (tree\<^sub>i\<^sub>i_of_stream (stl s)) LNil)" | |
| 54072 | 2210 | |
| 62081 | 2211 | text \<open> | 
| 54072 | 2212 | The next example illustrates corecursion through functions, which is a bit | 
| 2213 | special. Deterministic finite automata (DFAs) are traditionally defined as | |
| 2214 | 5-tuples @{text "(Q, \<Sigma>, \<delta>, q\<^sub>0, F)"}, where @{text Q} is a finite set of states,
 | |
| 53675 | 2215 | @{text \<Sigma>} is a finite alphabet, @{text \<delta>} is a transition function, @{text q\<^sub>0}
 | 
| 2216 | is an initial state, and @{text F} is a set of final states. The following
 | |
| 55350 | 2217 | function translates a DFA into a state machine: | 
| 62081 | 2218 | \<close> | 
| 53675 | 2219 | |
| 55350 | 2220 |     primcorec (*<*)(in early) (*>*)sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a sm" where
 | 
| 2221 | "sm_of_dfa \<delta> F q = SM (q \<in> F) (sm_of_dfa \<delta> F \<circ> \<delta> q)" | |
| 53675 | 2222 | |
| 62081 | 2223 | text \<open> | 
| 53751 | 2224 | \noindent | 
| 2225 | The map function for the function type (@{text \<Rightarrow>}) is composition
 | |
| 54181 | 2226 | (@{text "op \<circ>"}). For convenience, corecursion through functions can
 | 
| 54182 | 2227 | also be expressed using $\lambda$-abstractions and function application rather | 
| 54031 | 2228 | than through composition. For example: | 
| 62081 | 2229 | \<close> | 
| 53751 | 2230 | |
| 55350 | 2231 |     primcorec sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a sm" where
 | 
| 2232 | "sm_of_dfa \<delta> F q = SM (q \<in> F) (\<lambda>a. sm_of_dfa \<delta> F (\<delta> q a))" | |
| 53752 | 2233 | |
| 62081 | 2234 | text \<open> \blankline \<close> | 
| 53752 | 2235 | |
| 55350 | 2236 | primcorec empty_sm :: "'a sm" where | 
| 2237 | "empty_sm = SM False (\<lambda>_. empty_sm)" | |
| 53751 | 2238 | |
| 62081 | 2239 | text \<open> \blankline \<close> | 
| 53752 | 2240 | |
| 55350 | 2241 | primcorec not_sm :: "'a sm \<Rightarrow> 'a sm" where | 
| 2242 | "not_sm M = SM (\<not> accept M) (\<lambda>a. not_sm (trans M a))" | |
| 53751 | 2243 | |
| 62081 | 2244 | text \<open> \blankline \<close> | 
| 53752 | 2245 | |
| 55350 | 2246 | primcorec or_sm :: "'a sm \<Rightarrow> 'a sm \<Rightarrow> 'a sm" where | 
| 2247 | "or_sm M N = | |
| 2248 | SM (accept M \<or> accept N) (\<lambda>a. or_sm (trans M a) (trans N a))" | |
| 53751 | 2249 | |
| 62081 | 2250 | text \<open> | 
| 54182 | 2251 | \noindent | 
| 2252 | For recursion through curried $n$-ary functions, $n$ applications of | |
| 2253 | @{term "op \<circ>"} are necessary. The examples below illustrate the case where
 | |
| 2254 | $n = 2$: | |
| 62081 | 2255 | \<close> | 
| 54182 | 2256 | |
| 55350 | 2257 |     codatatype ('a, 'b) sm2 =
 | 
| 2258 |       SM2 (accept2: bool) (trans2: "'a \<Rightarrow> 'b \<Rightarrow> ('a, 'b) sm2")
 | |
| 54182 | 2259 | |
| 62081 | 2260 | text \<open> \blankline \<close> | 
| 54182 | 2261 | |
| 2262 | primcorec | |
| 55350 | 2263 |       (*<*)(in early) (*>*)sm2_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> ('a, 'b) sm2"
 | 
| 54182 | 2264 | where | 
| 55350 | 2265 | "sm2_of_dfa \<delta> F q = SM2 (q \<in> F) (op \<circ> (op \<circ> (sm2_of_dfa \<delta> F)) (\<delta> q))" | 
| 54182 | 2266 | |
| 62081 | 2267 | text \<open> \blankline \<close> | 
| 54182 | 2268 | |
| 2269 | primcorec | |
| 55350 | 2270 |       sm2_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> ('a, 'b) sm2"
 | 
| 54182 | 2271 | where | 
| 55350 | 2272 | "sm2_of_dfa \<delta> F q = SM2 (q \<in> F) (\<lambda>a b. sm2_of_dfa \<delta> F (\<delta> q a b))" | 
| 54182 | 2273 | |
| 53644 | 2274 | |
| 62081 | 2275 | subsubsection \<open> Nested-as-Mutual Corecursion | 
| 2276 |   \label{sssec:primcorec-nested-as-mutual-corecursion} \<close>
 | |
| 2277 | ||
| 2278 | text \<open> | |
| 53647 | 2279 | Just as it is possible to recurse over nested recursive datatypes as if they | 
| 2280 | were mutually recursive | |
| 2281 | (Section~\ref{sssec:primrec-nested-as-mutual-recursion}), it is possible to
 | |
| 53752 | 2282 | pretend that nested codatatypes are mutually corecursive. For example: | 
| 62081 | 2283 | \<close> | 
| 53647 | 2284 | |
| 54287 | 2285 | (*<*) | 
| 2286 | context late | |
| 2287 | begin | |
| 2288 | (*>*) | |
| 54072 | 2289 | primcorec | 
| 54287 | 2290 |       iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" and
 | 
| 53644 | 2291 |       iterates\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a llist \<Rightarrow> 'a tree\<^sub>i\<^sub>i llist"
 | 
| 2292 | where | |
| 62081 | 2293 | "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (iterates\<^sub>i\<^sub>i g (g x))" | 
| 2294 | | "iterates\<^sub>i\<^sub>i g xs = | |
| 53644 | 2295 | (case xs of | 
| 2296 | LNil \<Rightarrow> LNil | |
| 54072 | 2297 | | LCons x xs' \<Rightarrow> LCons (iterate\<^sub>i\<^sub>i g x) (iterates\<^sub>i\<^sub>i g xs'))" | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2298 | |
| 62081 | 2299 | text \<open> | 
| 54287 | 2300 | \noindent | 
| 2301 | Coinduction rules are generated as | |
| 2302 | @{thm [source] iterate\<^sub>i\<^sub>i.coinduct},
 | |
| 2303 | @{thm [source] iterates\<^sub>i\<^sub>i.coinduct}, and
 | |
| 2304 | @{thm [source] iterate\<^sub>i\<^sub>i_iterates\<^sub>i\<^sub>i.coinduct}
 | |
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57982diff
changeset | 2305 | and analogously for @{text coinduct_strong}. These rules and the
 | 
| 54287 | 2306 | underlying corecursors are generated on a per-need basis and are kept in a cache | 
| 2307 | to speed up subsequent definitions. | |
| 62081 | 2308 | \<close> | 
| 54287 | 2309 | |
| 2310 | (*<*) | |
| 2311 | end | |
| 2312 | (*>*) | |
| 2313 | ||
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2314 | |
| 62081 | 2315 | subsubsection \<open> Constructor View | 
| 2316 |   \label{ssec:primrec-constructor-view} \<close>
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2317 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2318 | (*<*) | 
| 54182 | 2319 | locale ctr_view | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2320 | begin | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2321 | (*>*) | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2322 | |
| 62081 | 2323 | text \<open> | 
| 53750 | 2324 | The constructor view is similar to the code view, but there is one separate | 
| 2325 | conditional equation per constructor rather than a single unconditional | |
| 2326 | equation. Examples that rely on a single constructor, such as @{const literate}
 | |
| 2327 | and @{const siterate}, are identical in both styles.
 | |
| 2328 | ||
| 2329 | Here is an example where there is a difference: | |
| 62081 | 2330 | \<close> | 
| 2331 | ||
| 2332 | primcorec lapp :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where | |
| 2333 | "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lapp xs ys = LNil" | |
| 2334 | | "_ \<Longrightarrow> lapp xs ys = LCons (lhd (if lnull xs then ys else xs)) | |
| 2335 | (if xs = LNil then ltl ys else lapp (ltl xs) ys)" | |
| 2336 | ||
| 2337 | text \<open> | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2338 | \noindent | 
| 53752 | 2339 | With the constructor view, we must distinguish between the @{const LNil} and
 | 
| 2340 | the @{const LCons} case. The condition for @{const LCons} is
 | |
| 2341 | left implicit, as the negation of that for @{const LNil}.
 | |
| 53750 | 2342 | |
| 59861 | 2343 | For this example, the constructor view is slightly more involved than the | 
| 53750 | 2344 | code equation. Recall the code view version presented in | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2345 | Section~\ref{sssec:primcorec-simple-corecursion}.
 | 
| 62081 | 2346 | % TODO: \[{thm code_view.lapp.code}\]
 | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2347 | The constructor view requires us to analyze the second argument (@{term ys}).
 | 
| 53752 | 2348 | The code equation generated from the constructor view also suffers from this. | 
| 62081 | 2349 | % TODO: \[{thm lapp.code}\]
 | 
| 53750 | 2350 | |
| 53752 | 2351 | In contrast, the next example is arguably more naturally expressed in the | 
| 2352 | constructor view: | |
| 62081 | 2353 | \<close> | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2354 | |
| 53831 
80423b9080cf
support "of" syntax to disambiguate selector equations
 panny parents: 
53829diff
changeset | 2355 | primcorec | 
| 53752 | 2356 | random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process" | 
| 2357 | where | |
| 62081 | 2358 | "n mod 4 = 0 \<Longrightarrow> random_process s f n = Fail" | 
| 2359 | | "n mod 4 = 1 \<Longrightarrow> | |
| 2360 | random_process s f n = Skip (random_process s f (f n))" | |
| 2361 | | "n mod 4 = 2 \<Longrightarrow> | |
| 2362 | random_process s f n = Action (shd s) (random_process (stl s) f (f n))" | |
| 2363 | | "n mod 4 = 3 \<Longrightarrow> | |
| 53752 | 2364 | random_process s f n = Choice (random_process (every_snd s) f (f n)) | 
| 53826 | 2365 | (random_process (every_snd (stl s)) f (f n))" | 
| 2366 | (*<*) | |
| 53644 | 2367 | end | 
| 2368 | (*>*) | |
| 52805 | 2369 | |
| 62081 | 2370 | text \<open> | 
| 53752 | 2371 | \noindent | 
| 53750 | 2372 | Since there is no sequentiality, we can apply the equation for @{const Choice}
 | 
| 61076 | 2373 | without having first to discharge @{term "n mod (4::int) \<noteq> 0"},
 | 
| 2374 | @{term "n mod (4::int) \<noteq> 1"}, and
 | |
| 2375 | @{term "n mod (4::int) \<noteq> 2"}.
 | |
| 59284 | 2376 | The price to pay for this elegance is that we must discharge exclusiveness proof | 
| 53750 | 2377 | obligations, one for each pair of conditions | 
| 61076 | 2378 | @{term "(n mod (4::int) = i, n mod (4::int) = j)"}
 | 
| 53752 | 2379 | with @{term "i < j"}. If we prefer not to discharge any obligations, we can
 | 
| 2380 | enable the @{text "sequential"} option. This pushes the problem to the users of
 | |
| 2381 | the generated properties. | |
| 53750 | 2382 | %Here are more examples to conclude: | 
| 62081 | 2383 | \<close> | 
| 2384 | ||
| 2385 | ||
| 2386 | subsubsection \<open> Destructor View | |
| 2387 |   \label{ssec:primrec-destructor-view} \<close>
 | |
| 53752 | 2388 | |
| 2389 | (*<*) | |
| 54182 | 2390 | locale dtr_view | 
| 53752 | 2391 | begin | 
| 2392 | (*>*) | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2393 | |
| 62081 | 2394 | text \<open> | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2395 | The destructor view is in many respects dual to the constructor view. Conditions | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2396 | determine which constructor to choose, and these conditions are interpreted | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2397 | sequentially or not depending on the @{text "sequential"} option.
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2398 | Consider the following examples: | 
| 62081 | 2399 | \<close> | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2400 | |
| 53826 | 2401 |     primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where
 | 
| 62081 | 2402 | "\<not> lnull (literate _ x)" | 
| 2403 | | "lhd (literate _ x) = x" | |
| 2404 | | "ltl (literate g x) = literate g (g x)" | |
| 2405 | ||
| 2406 | text \<open> \blankline \<close> | |
| 53752 | 2407 | |
| 53826 | 2408 |     primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where
 | 
| 62081 | 2409 | "shd (siterate _ x) = x" | 
| 2410 | | "stl (siterate g x) = siterate g (g x)" | |
| 2411 | ||
| 2412 | text \<open> \blankline \<close> | |
| 53752 | 2413 | |
| 53826 | 2414 | primcorec every_snd :: "'a stream \<Rightarrow> 'a stream" where | 
| 62081 | 2415 | "shd (every_snd s) = shd s" | 
| 2416 | | "stl (every_snd s) = stl (stl s)" | |
| 2417 | ||
| 2418 | text \<open> | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2419 | \noindent | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2420 | The first formula in the @{const literate} specification indicates which
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2421 | constructor to choose. For @{const siterate} and @{const every_snd}, no such
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2422 | formula is necessary, since the type has only one constructor. The last two | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2423 | formulas are equations specifying the value of the result for the relevant | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2424 | selectors. Corecursive calls appear directly to the right of the equal sign. | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2425 | Their arguments are unrestricted. | 
| 53750 | 2426 | |
| 2427 | The next example shows how to specify functions that rely on more than one | |
| 2428 | constructor: | |
| 62081 | 2429 | \<close> | 
| 2430 | ||
| 2431 | primcorec lapp :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where | |
| 2432 | "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lnull (lapp xs ys)" | |
| 2433 | | "lhd (lapp xs ys) = lhd (if lnull xs then ys else xs)" | |
| 2434 | | "ltl (lapp xs ys) = (if xs = LNil then ltl ys else lapp (ltl xs) ys)" | |
| 2435 | ||
| 2436 | text \<open> | |
| 53750 | 2437 | \noindent | 
| 2438 | For a codatatype with $n$ constructors, it is sufficient to specify $n - 1$ | |
| 2439 | discriminator formulas. The command will then assume that the remaining | |
| 2440 | constructor should be taken otherwise. This can be made explicit by adding | |
| 62081 | 2441 | \<close> | 
| 53750 | 2442 | |
| 2443 | (*<*) | |
| 2444 | end | |
| 2445 | ||
| 54182 | 2446 | locale dtr_view2 | 
| 2447 | begin | |
| 2448 | ||
| 62081 | 2449 | primcorec lapp :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where | 
| 2450 | "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lnull (lapp xs ys)" | |
| 2451 | | "lhd (lapp xs ys) = lhd (if lnull xs then ys else xs)" | |
| 2452 | | "ltl (lapp xs ys) = (if xs = LNil then ltl ys else lapp (ltl xs) ys)" | | |
| 53750 | 2453 | (*>*) | 
| 62081 | 2454 | "_ \<Longrightarrow> \<not> lnull (lapp xs ys)" | 
| 2455 | ||
| 2456 | text \<open> | |
| 53750 | 2457 | \noindent | 
| 53752 | 2458 | to the specification. The generated selector theorems are conditional. | 
| 2459 | ||
| 2460 | The next example illustrates how to cope with selectors defined for several | |
| 53750 | 2461 | constructors: | 
| 62081 | 2462 | \<close> | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2463 | |
| 53831 
80423b9080cf
support "of" syntax to disambiguate selector equations
 panny parents: 
53829diff
changeset | 2464 | primcorec | 
| 53752 | 2465 | random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process" | 
| 2466 | where | |
| 62081 | 2467 | "n mod 4 = 0 \<Longrightarrow> random_process s f n = Fail" | 
| 2468 | | "n mod 4 = 1 \<Longrightarrow> is_Skip (random_process s f n)" | |
| 2469 | | "n mod 4 = 2 \<Longrightarrow> is_Action (random_process s f n)" | |
| 2470 | | "n mod 4 = 3 \<Longrightarrow> is_Choice (random_process s f n)" | |
| 2471 | | "cont (random_process s f n) = random_process s f (f n)" of Skip | |
| 2472 | | "prefix (random_process s f n) = shd s" | |
| 2473 | | "cont (random_process s f n) = random_process (stl s) f (f n)" of Action | |
| 2474 | | "left (random_process s f n) = random_process (every_snd s) f (f n)" | |
| 2475 | | "right (random_process s f n) = random_process (every_snd (stl s)) f (f n)" | |
| 2476 | ||
| 2477 | text \<open> | |
| 53750 | 2478 | \noindent | 
| 2479 | Using the @{text "of"} keyword, different equations are specified for @{const
 | |
| 2480 | cont} depending on which constructor is selected. | |
| 2481 | ||
| 2482 | Here are more examples to conclude: | |
| 62081 | 2483 | \<close> | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2484 | |
| 53826 | 2485 | primcorec | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2486 | even_infty :: even_enat and | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2487 | odd_infty :: odd_enat | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2488 | where | 
| 62081 | 2489 | "even_infty \<noteq> Even_EZero" | 
| 2490 | | "un_Even_ESucc even_infty = odd_infty" | |
| 2491 | | "un_Odd_ESucc odd_infty = even_infty" | |
| 2492 | ||
| 2493 | text \<open> \blankline \<close> | |
| 53752 | 2494 | |
| 53826 | 2495 |     primcorec iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where
 | 
| 62081 | 2496 | "lbl\<^sub>i\<^sub>i (iterate\<^sub>i\<^sub>i g x) = x" | 
| 2497 | | "sub\<^sub>i\<^sub>i (iterate\<^sub>i\<^sub>i g x) = lmap (iterate\<^sub>i\<^sub>i g) (g x)" | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2498 | (*<*) | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2499 | end | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2500 | (*>*) | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2501 | |
| 53750 | 2502 | |
| 62081 | 2503 | subsection \<open> Command Syntax | 
| 2504 |   \label{ssec:primcorec-command-syntax} \<close>
 | |
| 2505 | ||
| 2506 | subsubsection \<open> \keyw{primcorec} and \keyw{primcorecursive}
 | |
| 2507 |   \label{sssec:primcorecursive-and-primcorec} \<close>
 | |
| 2508 | ||
| 2509 | text \<open> | |
| 53829 | 2510 | \begin{matharray}{rcl}
 | 
| 2511 |   @{command_def "primcorec"} & : & @{text "local_theory \<rightarrow> local_theory"} \\
 | |
| 2512 |   @{command_def "primcorecursive"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
 | |
| 2513 | \end{matharray}
 | |
| 52840 | 2514 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 2515 | @{rail \<open>
 | 
| 55029 
61a6bf7d4b02
clarified @{rail} syntax: prefer explicit \<newline> symbol;
 wenzelm parents: 
54958diff
changeset | 2516 |   (@@{command primcorec} | @@{command primcorecursive}) target? \<newline>
 | 
| 59277 | 2517 |     @{syntax pcr_options}? fixes @'where' (@{syntax pcr_formula} + '|')
 | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2518 | ; | 
| 59282 | 2519 |   @{syntax_def pcr_options}: '(' ((@{syntax plugins} | 'sequential' | 'exhaustive' | 'transfer') + ',') ')'
 | 
| 52840 | 2520 | ; | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2521 |   @{syntax_def pcr_formula}: thmdecl? prop (@'of' (term * ))?
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 2522 | \<close>} | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2523 | |
| 55351 | 2524 | \medskip | 
| 2525 | ||
| 2526 | \noindent | |
| 55474 | 2527 | The @{command primcorec} and @{command primcorecursive} commands introduce a set
 | 
| 2528 | of mutually corecursive functions over codatatypes. | |
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2529 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2530 | The syntactic entity \synt{target} can be used to specify a local context,
 | 
| 55474 | 2531 | \synt{fixes} denotes a list of names with optional type signatures,
 | 
| 2532 | \synt{thmdecl} denotes an optional name for the formula that follows, and
 | |
| 58620 | 2533 | \synt{prop} denotes a HOL proposition @{cite "isabelle-isar-ref"}.
 | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2534 | |
| 59280 | 2535 | The optional target is optionally followed by a combination of the following | 
| 56124 | 2536 | options: | 
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2537 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2538 | \begin{itemize}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2539 | \setlength{\itemsep}{0pt}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2540 | |
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2541 | \item | 
| 59282 | 2542 | The @{text plugins} option indicates which plugins should be enabled
 | 
| 2543 | (@{text only}) or disabled (@{text del}). By default, all plugins are enabled.
 | |
| 2544 | ||
| 2545 | \item | |
| 2546 | The @{text sequential} option indicates that the conditions in specifications
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2547 | expressed using the constructor or destructor view are to be interpreted | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2548 | sequentially. | 
| 53826 | 2549 | |
| 2550 | \item | |
| 59282 | 2551 | The @{text exhaustive} option indicates that the conditions in specifications
 | 
| 53826 | 2552 | expressed using the constructor or destructor view cover all possible cases. | 
| 59284 | 2553 | This generally gives rise to an additional proof obligation. | 
| 59277 | 2554 | |
| 2555 | \item | |
| 59282 | 2556 | The @{text transfer} option indicates that an unconditional transfer rule
 | 
| 59278 | 2557 | should be generated and proved @{text "by transfer_prover"}. The
 | 
| 2558 | @{text "[transfer_rule]"} attribute is set on the generated theorem.
 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2559 | \end{itemize}
 | 
| 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 2560 | |
| 55474 | 2561 | The @{command primcorec} command is an abbreviation for @{command
 | 
| 2562 | primcorecursive} with @{text "by auto?"} to discharge any emerging proof
 | |
| 2563 | obligations. | |
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2564 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2565 | %%% TODO: elaborate on format of the propositions | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2566 | %%% TODO: elaborate on mutual and nested-to-mutual | 
| 62081 | 2567 | \<close> | 
| 2568 | ||
| 2569 | ||
| 2570 | subsection \<open> Generated Theorems | |
| 2571 |   \label{ssec:primcorec-generated-theorems} \<close>
 | |
| 2572 | ||
| 2573 | text \<open> | |
| 59284 | 2574 | The @{command primcorec} and @{command primcorecursive} commands generate the
 | 
| 2575 | following properties (listed for @{const literate}):
 | |
| 2576 | ||
| 2577 | \begin{indentblock}
 | |
| 2578 | \begin{description}
 | |
| 2579 | ||
| 2580 | \item[@{text "f."}\hthm{code} @{text "[code]"}\rm:] ~ \\
 | |
| 2581 | @{thm literate.code[no_vars]} \\
 | |
| 2582 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | |
| 2583 | (Section~\ref{ssec:code-generator}).
 | |
| 2584 | ||
| 2585 | \item[@{text "f."}\hthm{ctr}\rm:] ~ \\
 | |
| 2586 | @{thm literate.ctr[no_vars]}
 | |
| 2587 | ||
| 2588 | \item[@{text "f."}\hthm{disc} @{text "[simp, code]"}\rm:] ~ \\
 | |
| 2589 | @{thm literate.disc[no_vars]} \\
 | |
| 2590 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | |
| 2591 | (Section~\ref{ssec:code-generator}). The @{text "[simp]"} attribute is set only
 | |
| 2592 | for functions for which @{text f.disc_iff} is not available.
 | |
| 2593 | ||
| 2594 | \item[@{text "f."}\hthm{disc_iff} @{text "[simp]"}\rm:] ~ \\
 | |
| 2595 | @{thm literate.disc_iff[no_vars]} \\
 | |
| 2596 | This property is generated only for functions declared with the | |
| 2597 | @{text exhaustive} option or whose conditions are trivially exhaustive.
 | |
| 2598 | ||
| 2599 | \item[@{text "f."}\hthm{sel} @{text "[simp, code]"}\rm:] ~ \\
 | |
| 2600 | @{thm literate.disc[no_vars]} \\
 | |
| 2601 | The @{text "[code]"} attribute is set by the @{text code} plugin
 | |
| 2602 | (Section~\ref{ssec:code-generator}).
 | |
| 2603 | ||
| 2604 | \item[@{text "f."}\hthm{exclude}\rm:] ~ \\
 | |
| 2605 | These properties are missing for @{const literate} because no exclusiveness
 | |
| 2606 | proof obligations arose. In general, the properties correspond to the | |
| 2607 | discharged proof obligations. | |
| 2608 | ||
| 2609 | \item[@{text "f."}\hthm{exhaust}\rm:] ~ \\
 | |
| 2610 | This property is missing for @{const literate} because no exhaustiveness
 | |
| 2611 | proof obligation arose. In general, the property correspond to the discharged | |
| 2612 | proof obligation. | |
| 2613 | ||
| 2614 | \item[\begin{tabular}{@ {}l@ {}}
 | |
| 2615 |   @{text "f."}\hthm{coinduct} @{text "[consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | |
| 2616 |   \phantom{@{text "f."}\hthm{coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots>
 | |
| 2617 | D\<^sub>n]"}\rm: | |
| 2618 | \end{tabular}] ~ \\
 | |
| 2619 | This coinduction rule is generated for nested-as-mutual corecursive functions | |
| 2620 | (Section~\ref{sssec:primcorec-nested-as-mutual-corecursion}).
 | |
| 2621 | ||
| 2622 | \item[\begin{tabular}{@ {}l@ {}}
 | |
| 2623 |   @{text "f."}\hthm{coinduct_strong} @{text "[consumes m, case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | |
| 2624 |   \phantom{@{text "f."}\hthm{coinduct_strong} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots>
 | |
| 2625 | D\<^sub>n]"}\rm: | |
| 2626 | \end{tabular}] ~ \\
 | |
| 2627 | This coinduction rule is generated for nested-as-mutual corecursive functions | |
| 2628 | (Section~\ref{sssec:primcorec-nested-as-mutual-corecursion}).
 | |
| 2629 | ||
| 2630 | \item[\begin{tabular}{@ {}l@ {}}
 | |
| 2631 |   @{text "f\<^sub>1_\<dots>_f\<^sub>m."}\hthm{coinduct} @{text "[case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | |
| 2632 |   \phantom{@{text "f."}\hthm{coinduct} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots>
 | |
| 2633 | D\<^sub>n]"}\rm: | |
| 2634 | \end{tabular}] ~ \\
 | |
| 2635 | This coinduction rule is generated for nested-as-mutual corecursive functions | |
| 2636 | (Section~\ref{sssec:primcorec-nested-as-mutual-corecursion}). Given $m > 1$
 | |
| 2637 | mutually corecursive functions, this rule can be used to prove $m$ properties | |
| 2638 | simultaneously. | |
| 2639 | ||
| 2640 | \item[\begin{tabular}{@ {}l@ {}}
 | |
| 2641 |   @{text "f\<^sub>1_\<dots>_f\<^sub>m."}\hthm{coinduct_strong} @{text "[case_names t\<^sub>1 \<dots> t\<^sub>m,"} \\
 | |
| 2642 |   \phantom{@{text "f."}\hthm{coinduct_strong} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots>
 | |
| 2643 | D\<^sub>n]"}\rm: | |
| 2644 | \end{tabular}] ~ \\
 | |
| 2645 | This coinduction rule is generated for nested-as-mutual corecursive functions | |
| 2646 | (Section~\ref{sssec:primcorec-nested-as-mutual-corecursion}). Given $m > 1$
 | |
| 2647 | mutually corecursive functions, this rule can be used to prove $m$ properties | |
| 2648 | simultaneously. | |
| 2649 | ||
| 2650 | \end{description}
 | |
| 2651 | \end{indentblock}
 | |
| 2652 | ||
| 2653 | \noindent | |
| 2654 | For convenience, @{command primcorec} and @{command primcorecursive} also
 | |
| 2655 | provide the following collection: | |
| 2656 | ||
| 2657 | \begin{indentblock}
 | |
| 2658 | \begin{description}
 | |
| 2659 | ||
| 2660 | \item[@{text "f."}\hthm{simps}] = @{text f.disc_iff} (or @{text f.disc}) @{text t.sel}
 | |
| 2661 | ||
| 2662 | \end{description}
 | |
| 2663 | \end{indentblock}
 | |
| 62081 | 2664 | \<close> | 
| 52794 | 2665 | |
| 2666 | ||
| 53623 | 2667 | (* | 
| 62081 | 2668 | subsection \<open> Recursive Default Values for Selectors | 
| 2669 |   \label{ssec:primcorec-recursive-default-values-for-selectors} \<close>
 | |
| 2670 | ||
| 2671 | text \<open> | |
| 53623 | 2672 | partial_function to the rescue | 
| 62081 | 2673 | \<close> | 
| 53623 | 2674 | *) | 
| 2675 | ||
| 2676 | ||
| 62081 | 2677 | section \<open> Registering Bounded Natural Functors | 
| 2678 |   \label{sec:registering-bounded-natural-functors} \<close>
 | |
| 2679 | ||
| 2680 | text \<open> | |
| 53647 | 2681 | The (co)datatype package can be set up to allow nested recursion through | 
| 55350 | 2682 | arbitrary type constructors, as long as they adhere to the BNF requirements | 
| 2683 | and are registered as BNFs. It is also possible to declare a BNF abstractly | |
| 2684 | without specifying its internal structure. | |
| 62081 | 2685 | \<close> | 
| 2686 | ||
| 2687 | ||
| 2688 | subsection \<open> Bounded Natural Functors | |
| 2689 |   \label{ssec:bounded-natural-functors} \<close>
 | |
| 2690 | ||
| 2691 | text \<open> | |
| 55350 | 2692 | Bounded natural functors (BNFs) are a semantic criterion for where | 
| 2693 | (co)re\-cur\-sion may appear on the right-hand side of an equation | |
| 60146 | 2694 | @{cite "traytel-et-al-2012" and "blanchette-et-al-2015-wit"}.
 | 
| 55350 | 2695 | |
| 2696 | An $n$-ary BNF is a type constructor equipped with a map function | |
| 2697 | (functorial action), $n$ set functions (natural transformations), | |
| 2698 | and an infinite cardinal bound that satisfy certain properties. | |
| 2699 | For example, @{typ "'a llist"} is a unary BNF.
 | |
| 61076 | 2700 | Its relator @{text "llist_all2 ::
 | 
| 55350 | 2701 |   ('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow>
 | 
| 2702 | 'a llist \<Rightarrow> 'b llist \<Rightarrow> bool"} | |
| 2703 | extends binary predicates over elements to binary predicates over parallel | |
| 2704 | lazy lists. The cardinal bound limits the number of elements returned by the | |
| 2705 | set function; it may not depend on the cardinality of @{typ 'a}.
 | |
| 2706 | ||
| 58310 | 2707 | The type constructors introduced by @{command datatype} and
 | 
| 55350 | 2708 | @{command codatatype} are automatically registered as BNFs. In addition, a
 | 
| 2709 | number of old-style datatypes and non-free types are preregistered. | |
| 2710 | ||
| 2711 | Given an $n$-ary BNF, the $n$ type variables associated with set functions, | |
| 2712 | and on which the map function acts, are \emph{live}; any other variables are
 | |
| 2713 | \emph{dead}. Nested (co)recursion can only take place through live variables.
 | |
| 62081 | 2714 | \<close> | 
| 2715 | ||
| 2716 | ||
| 2717 | subsection \<open> Introductory Examples | |
| 2718 |   \label{ssec:bnf-introductory-examples} \<close>
 | |
| 2719 | ||
| 2720 | text \<open> | |
| 55350 | 2721 | The example below shows how to register a type as a BNF using the @{command bnf}
 | 
| 2722 | command. Some of the proof obligations are best viewed with the theory | |
| 61304 | 2723 | @{file "~~/src/HOL/Library/Cardinal_Notations.thy"} imported.
 | 
| 55350 | 2724 | |
| 2725 | The type is simply a copy of the function space @{typ "'d \<Rightarrow> 'a"}, where @{typ 'a}
 | |
| 2726 | is live and @{typ 'd} is dead. We introduce it together with its map function,
 | |
| 2727 | set function, and relator. | |
| 62081 | 2728 | \<close> | 
| 55350 | 2729 | |
| 61076 | 2730 |     typedef ('d, 'a) fn = "UNIV :: ('d \<Rightarrow> 'a) set"
 | 
| 60152 | 2731 | by simp | 
| 2732 | ||
| 62081 | 2733 | text \<open> \blankline \<close> | 
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2734 | |
| 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2735 | setup_lifting type_definition_fn | 
| 55350 | 2736 | |
| 62081 | 2737 | text \<open> \blankline \<close> | 
| 55350 | 2738 | |
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2739 |     lift_definition map_fn :: "('a \<Rightarrow> 'b) \<Rightarrow> ('d, 'a) fn \<Rightarrow> ('d, 'b) fn" is "op \<circ>" .
 | 
| 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2740 |     lift_definition set_fn :: "('d, 'a) fn \<Rightarrow> 'a set" is range .
 | 
| 55350 | 2741 | |
| 62081 | 2742 | text \<open> \blankline \<close> | 
| 55350 | 2743 | |
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2744 | lift_definition | 
| 55350 | 2745 |       rel_fn :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> ('d, 'a) fn \<Rightarrow> ('d, 'b) fn \<Rightarrow> bool"
 | 
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2746 | is | 
| 55945 | 2747 | "rel_fun (op =)" . | 
| 55350 | 2748 | |
| 62081 | 2749 | text \<open> \blankline \<close> | 
| 55350 | 2750 | |
| 2751 |     bnf "('d, 'a) fn"
 | |
| 2752 | map: map_fn | |
| 2753 | sets: set_fn | |
| 2754 | bd: "natLeq +c |UNIV :: 'd set|" | |
| 2755 | rel: rel_fn | |
| 2756 | proof - | |
| 2757 | show "map_fn id = id" | |
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2758 | by transfer auto | 
| 55350 | 2759 | next | 
| 60136 | 2760 | fix f :: "'a \<Rightarrow> 'b" and g :: "'b \<Rightarrow> 'c" | 
| 2761 | show "map_fn (g \<circ> f) = map_fn g \<circ> map_fn f" | |
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2762 | by transfer (auto simp add: comp_def) | 
| 55350 | 2763 | next | 
| 60136 | 2764 |       fix F :: "('d, 'a) fn" and f g :: "'a \<Rightarrow> 'b"
 | 
| 55350 | 2765 | assume "\<And>x. x \<in> set_fn F \<Longrightarrow> f x = g x" | 
| 61303 | 2766 | then show "map_fn f F = map_fn g F" | 
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2767 | by transfer auto | 
| 55350 | 2768 | next | 
| 60136 | 2769 | fix f :: "'a \<Rightarrow> 'b" | 
| 2770 | show "set_fn \<circ> map_fn f = op ` f \<circ> set_fn" | |
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2771 | by transfer (auto simp add: comp_def) | 
| 55350 | 2772 | next | 
| 61076 | 2773 | show "card_order (natLeq +c |UNIV :: 'd set| )" | 
| 55350 | 2774 | apply (rule card_order_csum) | 
| 2775 | apply (rule natLeq_card_order) | |
| 2776 | by (rule card_of_card_order_on) | |
| 2777 | next | |
| 61076 | 2778 | show "cinfinite (natLeq +c |UNIV :: 'd set| )" | 
| 55350 | 2779 | apply (rule cinfinite_csum) | 
| 2780 | apply (rule disjI1) | |
| 2781 | by (rule natLeq_cinfinite) | |
| 2782 | next | |
| 2783 |       fix F :: "('d, 'a) fn"
 | |
| 61076 | 2784 | have "|set_fn F| \<le>o |UNIV :: 'd set|" (is "_ \<le>o ?U") | 
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2785 | by transfer (rule card_of_image) | 
| 55350 | 2786 | also have "?U \<le>o natLeq +c ?U" | 
| 2787 | by (rule ordLeq_csum2) (rule card_of_Card_order) | |
| 61076 | 2788 | finally show "|set_fn F| \<le>o natLeq +c |UNIV :: 'd set|" . | 
| 55350 | 2789 | next | 
| 60136 | 2790 | fix R :: "'a \<Rightarrow> 'b \<Rightarrow> bool" and S :: "'b \<Rightarrow> 'c \<Rightarrow> bool" | 
| 55350 | 2791 | show "rel_fn R OO rel_fn S \<le> rel_fn (R OO S)" | 
| 55945 | 2792 | by (rule, transfer) (auto simp add: rel_fun_def) | 
| 55350 | 2793 | next | 
| 60136 | 2794 | fix R :: "'a \<Rightarrow> 'b \<Rightarrow> bool" | 
| 55350 | 2795 | show "rel_fn R = | 
| 61424 
c3658c18b7bc
prod_case as canonical name for product type eliminator
 haftmann parents: 
61351diff
changeset | 2796 |             (BNF_Def.Grp {x. set_fn x \<subseteq> {(x, y). R x y}} (map_fn fst))\<inverse>\<inverse> OO
 | 
| 
c3658c18b7bc
prod_case as canonical name for product type eliminator
 haftmann parents: 
61351diff
changeset | 2797 |              BNF_Def.Grp {x. set_fn x \<subseteq> {(x, y). R x y}} (map_fn snd)"
 | 
| 55459 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2798 | unfolding Grp_def fun_eq_iff relcompp.simps conversep.simps | 
| 
1cd927ca8296
cleaner, complete proof in documentation, contributed by Dmitriy T.
 blanchet parents: 
55410diff
changeset | 2799 | apply transfer | 
| 55945 | 2800 | unfolding rel_fun_def subset_iff image_iff | 
| 61424 
c3658c18b7bc
prod_case as canonical name for product type eliminator
 haftmann parents: 
61351diff
changeset | 2801 | by auto (force, metis prod.collapse) | 
| 55350 | 2802 | qed | 
| 2803 | ||
| 62081 | 2804 | text \<open> \blankline \<close> | 
| 55350 | 2805 | |
| 2806 | print_theorems | |
| 2807 | print_bnfs | |
| 2808 | ||
| 62081 | 2809 | text \<open> | 
| 55350 | 2810 | \noindent | 
| 58931 | 2811 | Using \keyw{print_theorems} and @{command print_bnfs}, we can contemplate and
 | 
| 55350 | 2812 | show the world what we have achieved. | 
| 2813 | ||
| 2814 | This particular example does not need any nonemptiness witness, because the | |
| 2815 | one generated by default is good enough, but in general this would be | |
| 61304 | 2816 | necessary. See @{file "~~/src/HOL/Basic_BNFs.thy"},
 | 
| 62081 | 2817 | @{file "~~/src/HOL/Library/Countable_Set_Type.thy"},
 | 
| 61304 | 2818 | @{file "~~/src/HOL/Library/FSet.thy"}, and
 | 
| 2819 | @{file "~~/src/HOL/Library/Multiset.thy"} for further examples of BNF
 | |
| 2820 | registration, some of which feature custom witnesses. | |
| 55350 | 2821 | |
| 61303 | 2822 | For many typedefs, lifting the BNF structure from the raw type to the abstract | 
| 2823 | type can be done uniformly. This is the task of the @{command lift_bnf} command.
 | |
| 2824 | Using @{command lift_bnf}, the above registration of @{typ "('d, 'a) fn"} as a
 | |
| 2825 | BNF becomes much shorter: | |
| 62081 | 2826 | \<close> | 
| 60920 | 2827 | |
| 61303 | 2828 | (*<*) | 
| 2829 | context early | |
| 2830 | begin | |
| 2831 | (*>*) | |
| 2832 |     lift_bnf (*<*)(no_warn_wits) (*>*)('d, 'a) fn
 | |
| 2833 | by auto | |
| 2834 | (*<*) | |
| 2835 | end | |
| 2836 | (*>*) | |
| 60920 | 2837 | |
| 62081 | 2838 | text \<open> | 
| 61303 | 2839 | For type copies (@{command typedef}s with @{term UNIV} as the representing set),
 | 
| 2840 | the proof obligations are so simple that they can be | |
| 2841 | discharged automatically, yielding another command, @{command copy_bnf}, which
 | |
| 2842 | does not emit any proof obligations: | |
| 62081 | 2843 | \<close> | 
| 60920 | 2844 | |
| 61303 | 2845 | (*<*) | 
| 2846 | context late | |
| 2847 | begin | |
| 2848 | (*>*) | |
| 60920 | 2849 |     copy_bnf ('d, 'a) fn
 | 
| 61303 | 2850 | (*<*) | 
| 2851 | end | |
| 2852 | (*>*) | |
| 60920 | 2853 | |
| 62081 | 2854 | text \<open> | 
| 61303 | 2855 | Since record schemas are type copies, @{command copy_bnf} can be used to
 | 
| 2856 | register them as BNFs: | |
| 62081 | 2857 | \<close> | 
| 60920 | 2858 | |
| 2859 | record 'a point = | |
| 2860 | xval :: 'a | |
| 2861 | yval :: 'a | |
| 61303 | 2862 | |
| 62081 | 2863 | text \<open> \blankline \<close> | 
| 60920 | 2864 | |
| 2865 |     copy_bnf ('a, 'z) point_ext
 | |
| 2866 | ||
| 62081 | 2867 | text \<open> | 
| 61303 | 2868 | In the general case, the proof obligations generated by @{command lift_bnf} are
 | 
| 2869 | simpler than the acual BNF properties. In particular, no cardinality reasoning | |
| 2870 | is required. Consider the following type of nonempty lists: | |
| 62081 | 2871 | \<close> | 
| 60920 | 2872 | |
| 2873 |     typedef 'a nonempty_list = "{xs :: 'a list. xs \<noteq> []}" by auto
 | |
| 2874 | ||
| 62081 | 2875 | text \<open> | 
| 61303 | 2876 | The @{command lift_bnf} command requires us to prove that the set of nonempty lists
 | 
| 2877 | is closed under the map function and the zip function. The latter only | |
| 60920 | 2878 | occurs implicitly in the goal, in form of the variable | 
| 61303 | 2879 | @{term "zs :: ('a \<times> 'b) list"}.
 | 
| 62081 | 2880 | \<close> | 
| 60920 | 2881 | |
| 61303 | 2882 | lift_bnf (*<*)(no_warn_wits) (*>*)'a nonempty_list | 
| 60920 | 2883 | proof - | 
| 2884 | fix f and xs :: "'a list" | |
| 2885 |       assume "xs \<in> {xs. xs \<noteq> []}"
 | |
| 61303 | 2886 |       then show "map f xs \<in> {xs. xs \<noteq> []}"
 | 
| 2887 | by (cases xs(*<*) rule: list.exhaust(*>*)) auto | |
| 60920 | 2888 | next | 
| 2889 |       fix zs :: "('a \<times> 'b) list"
 | |
| 2890 |       assume "map fst zs \<in> {xs. xs \<noteq> []}" "map snd zs \<in> {xs. xs \<noteq> []}"
 | |
| 61303 | 2891 |       then show "zs \<in> {xs. xs \<noteq> []}"
 | 
| 2892 | by (cases zs (*<*)rule: list.exhaust(*>*)) auto | |
| 60920 | 2893 | qed | 
| 2894 | ||
| 62081 | 2895 | text \<open> | 
| 57542 | 2896 | The next example declares a BNF axiomatically. This can be convenient for | 
| 2897 | reasoning abstractly about an arbitrary BNF. The @{command bnf_axiomatization}
 | |
| 2898 | command below introduces a type @{text "('a, 'b, 'c) F"}, three set constants,
 | |
| 2899 | a map function, a relator, and a nonemptiness witness that depends only on | |
| 59284 | 2900 | @{typ 'a}. The type @{text "'a \<Rightarrow> ('a, 'b, 'c) F"} of the witness can be read
 | 
| 2901 | as an implication: Given a witness for @{typ 'a}, we can construct a witness for
 | |
| 2902 | @{text "('a, 'b, 'c) F"}. The BNF properties are postulated as axioms.
 | |
| 62081 | 2903 | \<close> | 
| 55350 | 2904 | |
| 57542 | 2905 | bnf_axiomatization (setA: 'a, setB: 'b, setC: 'c) F | 
| 2906 |       [wits: "'a \<Rightarrow> ('a, 'b, 'c) F"]
 | |
| 55350 | 2907 | |
| 62081 | 2908 | text \<open> \blankline \<close> | 
| 55350 | 2909 | |
| 2910 | print_theorems | |
| 2911 | print_bnfs | |
| 52794 | 2912 | |
| 52824 | 2913 | |
| 62081 | 2914 | subsection \<open> Command Syntax | 
| 2915 |   \label{ssec:bnf-command-syntax} \<close>
 | |
| 2916 | ||
| 2917 | subsubsection \<open> \keyw{bnf}
 | |
| 2918 |   \label{sssec:bnf} \<close>
 | |
| 2919 | ||
| 2920 | text \<open> | |
| 53829 | 2921 | \begin{matharray}{rcl}
 | 
| 2922 |   @{command_def "bnf"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
 | |
| 2923 | \end{matharray}
 | |
| 2924 | ||
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 2925 | @{rail \<open>
 | 
| 55474 | 2926 |   @@{command bnf} target? (name ':')? type \<newline>
 | 
| 55029 
61a6bf7d4b02
clarified @{rail} syntax: prefer explicit \<newline> symbol;
 wenzelm parents: 
54958diff
changeset | 2927 |     'map:' term ('sets:' (term +))? 'bd:' term \<newline>
 | 
| 58190 | 2928 |     ('wits:' (term +))? ('rel:' term)? \<newline>
 | 
| 2929 |     @{syntax plugins}?
 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 2930 | \<close>} | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2931 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2932 | \medskip | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2933 | |
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2934 | \noindent | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2935 | The @{command bnf} command registers an existing type as a bounded natural
 | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2936 | functor (BNF). The type must be equipped with an appropriate map function | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2937 | (functorial action). In addition, custom set functions, relators, and | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2938 | nonemptiness witnesses can be specified; otherwise, default versions are used. | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 2939 | |
| 55474 | 2940 | The syntactic entity \synt{target} can be used to specify a local context,
 | 
| 2941 | \synt{type} denotes a HOL type, and \synt{term} denotes a HOL term
 | |
| 58620 | 2942 | @{cite "isabelle-isar-ref"}.
 | 
| 55474 | 2943 | |
| 59280 | 2944 | The @{syntax plugins} option indicates which plugins should be enabled
 | 
| 2945 | (@{text only}) or disabled (@{text del}). By default, all plugins are enabled.
 | |
| 2946 | ||
| 55474 | 2947 | %%% TODO: elaborate on proof obligations | 
| 62081 | 2948 | \<close> | 
| 2949 | ||
| 2950 | subsubsection \<open> \keyw{lift_bnf}
 | |
| 2951 |   \label{sssec:lift-bnf} \<close>
 | |
| 2952 | ||
| 2953 | text \<open> | |
| 60920 | 2954 | \begin{matharray}{rcl}
 | 
| 61303 | 2955 |   @{command_def "lift_bnf"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
 | 
| 60920 | 2956 | \end{matharray}
 | 
| 2957 | ||
| 2958 | @{rail \<open>
 | |
| 2959 |   @@{command lift_bnf} target? lb_options? \<newline>
 | |
| 2960 |     @{syntax tyargs} name wit_terms?  \<newline>
 | |
| 62081 | 2961 |     ('via' thmref)? @{syntax map_rel}?
 | 
| 60920 | 2962 | ; | 
| 2963 |   @{syntax_def lb_options}: '(' ((@{syntax plugins} | 'no_warn_wits') + ',') ')'
 | |
| 2964 | ; | |
| 2965 |   @{syntax_def wit_terms}: '[' 'wits' ':' terms ']'
 | |
| 61303 | 2966 | \<close>} | 
| 2967 | \medskip | |
| 2968 | ||
| 2969 | \noindent | |
| 2970 | The @{command lift_bnf} command registers as a BNF an existing type (the
 | |
| 2971 | \emph{abstract type}) that was defined as a subtype of a BNF (the \emph{raw
 | |
| 2972 | type}) using the @{command typedef} command. To achieve this, it lifts the BNF
 | |
| 2973 | structure on the raw type to the abstract type following a @{term
 | |
| 2974 | type_definition} theorem. The theorem is usually inferred from the type, but can | |
| 2975 | also be explicitly supplied by means of the optional @{text via} clause. In
 | |
| 2976 | addition, custom names for the set functions, the map function, and the relator, | |
| 2977 | as well as nonemptiness witnesses can be specified. | |
| 2978 | ||
| 2979 | Nonemptiness witnesses are not lifted from the raw type's BNF, as this would be | |
| 2980 | incomplete. They must be given as terms (on the raw type) and proved to be | |
| 2981 | witnesses. The command warns about witness types that are present in the raw | |
| 2982 | type's BNF but not supplied by the user. The warning can be disabled by | |
| 2983 | specifying the @{text no_warn_wits} option.
 | |
| 62081 | 2984 | \<close> | 
| 2985 | ||
| 2986 | subsubsection \<open> \keyw{copy_bnf}
 | |
| 2987 |   \label{sssec:copy-bnf} \<close>
 | |
| 2988 | ||
| 2989 | text \<open> | |
| 61303 | 2990 | \begin{matharray}{rcl}
 | 
| 2991 |   @{command_def "copy_bnf"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | |
| 2992 | \end{matharray}
 | |
| 2993 | ||
| 2994 | @{rail \<open>
 | |
| 60920 | 2995 |   @@{command copy_bnf} target? ('(' @{syntax plugins} ')')? \<newline>
 | 
| 62081 | 2996 |     @{syntax tyargs} name ('via' thmref)? @{syntax map_rel}?
 | 
| 60920 | 2997 | \<close>} | 
| 2998 | \medskip | |
| 2999 | ||
| 3000 | \noindent | |
| 61303 | 3001 | The @{command copy_bnf} command performs the same lifting as @{command lift_bnf}
 | 
| 3002 | for type copies (@{command typedef}s with @{term UNIV} as the representing set),
 | |
| 3003 | without requiring the user to discharge any proof obligations or provide | |
| 3004 | nonemptiness witnesses. | |
| 62081 | 3005 | \<close> | 
| 3006 | ||
| 3007 | subsubsection \<open> \keyw{bnf_axiomatization}
 | |
| 3008 |   \label{sssec:bnf-axiomatization} \<close>
 | |
| 3009 | ||
| 3010 | text \<open> | |
| 54187 | 3011 | \begin{matharray}{rcl}
 | 
| 56942 | 3012 |   @{command_def "bnf_axiomatization"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | 
| 54187 | 3013 | \end{matharray}
 | 
| 3014 | ||
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 3015 | @{rail \<open>
 | 
| 59280 | 3016 |   @@{command bnf_axiomatization} target? ('(' @{syntax plugins} ')')? \<newline>
 | 
| 58190 | 3017 |     @{syntax tyargs}? name @{syntax wit_types}? \<newline>
 | 
| 3018 |     mixfix? @{syntax map_rel}?
 | |
| 54602 | 3019 | ; | 
| 55350 | 3020 |   @{syntax_def wit_types}: '[' 'wits' ':' types ']'
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 3021 | \<close>} | 
| 54602 | 3022 | |
| 55351 | 3023 | \medskip | 
| 3024 | ||
| 55350 | 3025 | \noindent | 
| 56942 | 3026 | The @{command bnf_axiomatization} command declares a new type and associated constants
 | 
| 55350 | 3027 | (map, set, relator, and cardinal bound) and asserts the BNF properties for | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3028 | these constants as axioms. | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3029 | |
| 55474 | 3030 | The syntactic entity \synt{target} can be used to specify a local context,
 | 
| 3031 | \synt{name} denotes an identifier, \synt{typefree} denotes fixed type variable
 | |
| 3032 | (@{typ 'a}, @{typ 'b}, \ldots), and \synt{mixfix} denotes the usual
 | |
| 58620 | 3033 | parenthesized mixfix notation @{cite "isabelle-isar-ref"}.
 | 
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3034 | |
| 59280 | 3035 | The @{syntax plugins} option indicates which plugins should be enabled
 | 
| 3036 | (@{text only}) or disabled (@{text del}). By default, all plugins are enabled.
 | |
| 3037 | ||
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3038 | Type arguments are live by default; they can be marked as dead by entering | 
| 58220 | 3039 | @{text dead} in front of the type variable (e.g., @{text "(dead 'a)"})
 | 
| 57092 | 3040 | instead of an identifier for the corresponding set function. Witnesses can be | 
| 3041 | specified by their types. Otherwise, the syntax of @{command bnf_axiomatization}
 | |
| 58310 | 3042 | is identical to the left-hand side of a @{command datatype} or
 | 
| 57092 | 3043 | @{command codatatype} definition.
 | 
| 55350 | 3044 | |
| 3045 | The command is useful to reason abstractly about BNFs. The axioms are safe | |
| 57575 | 3046 | because there exist BNFs of arbitrary large arities. Applications must import | 
| 61304 | 3047 | the @{file "~~/src/HOL/Library/BNF_Axiomatization.thy"} theory
 | 
| 3048 | to use this functionality. | |
| 62081 | 3049 | \<close> | 
| 3050 | ||
| 3051 | ||
| 3052 | subsubsection \<open> \keyw{print_bnfs}
 | |
| 3053 |   \label{sssec:print-bnfs} \<close>
 | |
| 3054 | ||
| 3055 | text \<open> | |
| 53829 | 3056 | \begin{matharray}{rcl}
 | 
| 3057 |   @{command_def "print_bnfs"} & : & @{text "local_theory \<rightarrow>"}
 | |
| 3058 | \end{matharray}
 | |
| 3059 | ||
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 3060 | @{rail \<open>
 | 
| 53829 | 3061 |   @@{command print_bnfs}
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 3062 | \<close>} | 
| 62081 | 3063 | \<close> | 
| 3064 | ||
| 3065 | ||
| 3066 | section \<open> Deriving Destructors and Theorems for Free Constructors | |
| 3067 |   \label{sec:deriving-destructors-and-theorems-for-free-constructors} \<close>
 | |
| 3068 | ||
| 3069 | text \<open> | |
| 53623 | 3070 | The derivation of convenience theorems for types equipped with free constructors, | 
| 58310 | 3071 | as performed internally by @{command datatype} and @{command codatatype},
 | 
| 55468 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 3072 | is available as a stand-alone command called @{command free_constructors}.
 | 
| 52794 | 3073 | |
| 53617 | 3074 | % * need for this is rare but may arise if you want e.g. to add destructors to | 
| 3075 | % a type not introduced by ... | |
| 3076 | % | |
| 55468 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 3077 | %  * @{command free_constructors}
 | 
| 58192 | 3078 | %    * @{text plugins}, @{text discs_sels}
 | 
| 53617 | 3079 | % * hack to have both co and nonco view via locale (cf. ext nats) | 
| 62081 | 3080 | \<close> | 
| 52792 | 3081 | |
| 52824 | 3082 | |
| 53619 | 3083 | (* | 
| 62081 | 3084 | subsection \<open> Introductory Example | 
| 3085 |   \label{ssec:ctors-introductory-example} \<close>
 | |
| 53619 | 3086 | *) | 
| 52794 | 3087 | |
| 52824 | 3088 | |
| 62081 | 3089 | subsection \<open> Command Syntax | 
| 3090 |   \label{ssec:ctors-command-syntax} \<close>
 | |
| 3091 | ||
| 3092 | subsubsection \<open> \keyw{free_constructors}
 | |
| 3093 |   \label{sssec:free-constructors} \<close>
 | |
| 3094 | ||
| 3095 | text \<open> | |
| 53829 | 3096 | \begin{matharray}{rcl}
 | 
| 55468 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 3097 |   @{command_def "free_constructors"} & : & @{text "local_theory \<rightarrow> proof(prove)"}
 | 
| 53829 | 3098 | \end{matharray}
 | 
| 53018 | 3099 | |
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 3100 | @{rail \<open>
 | 
| 55468 
98b25c51e9e5
renamed 'wrap_free_constructors' to 'free_constructors' (cf. 'functor', 'bnf', etc.)
 blanchet parents: 
55460diff
changeset | 3101 |   @@{command free_constructors} target? @{syntax dt_options} \<newline>
 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 3102 |     name 'for' (@{syntax fc_ctor} + '|') \<newline>
 | 
| 57206 
d9be905d6283
changed syntax of map: and rel: arguments to BNF-based datatypes
 blanchet parents: 
57200diff
changeset | 3103 | (@'where' (prop + '|'))? | 
| 53018 | 3104 | ; | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 3105 |   @{syntax_def fc_ctor}: (name ':')? term (name * )
 | 
| 55112 
b1a5d603fd12
prefer rail cartouche -- avoid back-slashed quotes;
 wenzelm parents: 
55029diff
changeset | 3106 | \<close>} | 
| 53018 | 3107 | |
| 55351 | 3108 | \medskip | 
| 3109 | ||
| 55460 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3110 | \noindent | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3111 | The @{command free_constructors} command generates destructor constants for
 | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3112 | freely constructed types as well as properties about constructors and | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3113 | destructors. It also registers the constants and theorems in a data structure | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3114 | that is queried by various tools (e.g., \keyw{function}).
 | 
| 
3f4efd7d950d
added a bit of documentation for the different commands
 blanchet parents: 
55459diff
changeset | 3115 | |
| 55474 | 3116 | The syntactic entity \synt{target} can be used to specify a local context,
 | 
| 57200 
aab87ffa60cc
use 'where' clause for selector default value syntax
 blanchet parents: 
57153diff
changeset | 3117 | \synt{name} denotes an identifier, \synt{prop} denotes a HOL proposition, and
 | 
| 58620 | 3118 | \synt{term} denotes a HOL term @{cite "isabelle-isar-ref"}.
 | 
| 55474 | 3119 | |
| 58310 | 3120 | The syntax resembles that of @{command datatype} and @{command codatatype}
 | 
| 55474 | 3121 | definitions (Sections | 
| 3122 | \ref{ssec:datatype-command-syntax}~and~\ref{ssec:codatatype-command-syntax}).
 | |
| 3123 | A constructor is specified by an optional name for the discriminator, the | |
| 3124 | constructor itself (as a term), and a list of optional names for the selectors. | |
| 53028 | 3125 | |
| 53542 | 3126 | Section~\ref{ssec:datatype-generated-theorems} lists the generated theorems.
 | 
| 57542 | 3127 | For bootstrapping reasons, the generally useful @{text "[fundef_cong]"}
 | 
| 3128 | attribute is not set on the generated @{text case_cong} theorem. It can be
 | |
| 3129 | added manually using \keyw{declare}.
 | |
| 62081 | 3130 | \<close> | 
| 3131 | ||
| 3132 | ||
| 3133 | subsubsection \<open> \keyw{simps_of_case}
 | |
| 3134 |   \label{sssec:simps-of-case} \<close>
 | |
| 3135 | ||
| 3136 | text \<open> | |
| 3137 | \begin{matharray}{rcl}
 | |
| 3138 |   @{command_def "simps_of_case"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | |
| 3139 | \end{matharray}
 | |
| 3140 | ||
| 3141 | @{rail \<open>
 | |
| 3142 |   @@{command simps_of_case} target? (name ':')? \<newline>
 | |
| 3143 | (thmref + ) (@'splits' ':' (thmref + ))? | |
| 3144 | \<close>} | |
| 3145 | ||
| 3146 | \medskip | |
| 3147 | ||
| 3148 | \noindent | |
| 3149 | The @{command simps_of_case} command provided by theory
 | |
| 3150 | @{file "~~/src/HOL/Library/Simps_Case_Conv.thy"} converts a single equation with
 | |
| 3151 | a complex case expression on the right-hand side into a set of pattern-matching | |
| 3152 | equations. For example, | |
| 3153 | \<close> | |
| 3154 | ||
| 3155 | (*<*) | |
| 3156 | context late | |
| 3157 | begin | |
| 3158 | (*>*) | |
| 3159 | simps_of_case lapp_simps: lapp.code | |
| 3160 | ||
| 3161 | text \<open> | |
| 3162 | \noindent | |
| 3163 | translates @{thm lapp.code[no_vars]} into
 | |
| 3164 | % | |
| 3165 | \begin{gather*}
 | |
| 3166 |   @{thm lapp_simps(1)[no_vars]} \\
 | |
| 3167 |   @{thm lapp_simps(2)[no_vars]}
 | |
| 3168 | \end{gather*}
 | |
| 3169 | \<close> | |
| 3170 | ||
| 3171 | ||
| 3172 | subsubsection \<open> \keyw{case_of_simps}
 | |
| 3173 |   \label{sssec:case-of-simps} \<close>
 | |
| 3174 | ||
| 3175 | text \<open> | |
| 3176 | \begin{matharray}{rcl}
 | |
| 3177 |   @{command_def "case_of_simps"} & : & @{text "local_theory \<rightarrow> local_theory"}
 | |
| 3178 | \end{matharray}
 | |
| 3179 | ||
| 3180 | @{rail \<open>
 | |
| 3181 |   @@{command case_of_simps} target? (name ':')? \<newline>
 | |
| 3182 | (thmref + ) | |
| 3183 | \<close>} | |
| 3184 | ||
| 3185 | \medskip | |
| 3186 | ||
| 3187 | \noindent | |
| 3188 | The \keyw{case_of_simps} command provided by theory
 | |
| 3189 | @{file "~~/src/HOL/Library/Simps_Case_Conv.thy"} converts a set of
 | |
| 3190 | pattern-matching equations into single equation with a complex case expression | |
| 3191 | on the right-hand side (cf.\ @{command simps_of_case}). For example,
 | |
| 3192 | \<close> | |
| 3193 | ||
| 3194 | case_of_simps lapp_case: lapp_simps | |
| 3195 | ||
| 3196 | text \<open> | |
| 3197 | \noindent | |
| 3198 | translates | |
| 3199 | % | |
| 3200 | \begin{gather*}
 | |
| 3201 |   @{thm lapp_simps(1)[no_vars]} \\
 | |
| 3202 |   @{thm lapp_simps(2)[no_vars]}
 | |
| 3203 | \end{gather*}
 | |
| 3204 | % | |
| 3205 | into @{thm lapp_case[no_vars]}.
 | |
| 3206 | \<close> | |
| 3207 | (*<*) | |
| 3208 | end | |
| 3209 | (*>*) | |
| 52828 | 3210 | |
| 52794 | 3211 | |
| 53617 | 3212 | (* | 
| 62081 | 3213 | section \<open> Using the Standard ML Interface | 
| 3214 |   \label{sec:using-the-standard-ml-interface} \<close>
 | |
| 3215 | ||
| 3216 | text \<open> | |
| 53623 | 3217 | The package's programmatic interface. | 
| 62081 | 3218 | \<close> | 
| 53617 | 3219 | *) | 
| 52794 | 3220 | |
| 3221 | ||
| 62081 | 3222 | section \<open> Selecting Plugins | 
| 3223 |   \label{sec:selecting-plugins} \<close>
 | |
| 3224 | ||
| 3225 | text \<open> | |
| 58190 | 3226 | Plugins extend the (co)datatype package to interoperate with other Isabelle | 
| 58192 | 3227 | packages and tools, such as the code generator, Transfer, Lifting, and | 
| 3228 | Quickcheck. They can be enabled or disabled individually using the | |
| 58310 | 3229 | @{syntax plugins} option to the commands @{command datatype},
 | 
| 59300 | 3230 | @{command primrec}, @{command codatatype}, @{command primcorec},
 | 
| 3231 | @{command primcorecursive}, @{command bnf}, @{command bnf_axiomatization}, and
 | |
| 3232 | @{command free_constructors}. For example:
 | |
| 62081 | 3233 | \<close> | 
| 58190 | 3234 | |
| 58659 
6c9821c32dd5
Local_Interpretation is superseded by Plugin with formal Plugin_Name management, avoiding undeclared strings;
 wenzelm parents: 
58620diff
changeset | 3235 | datatype (plugins del: code "quickcheck") color = Red | Black | 
| 58192 | 3236 | |
| 62081 | 3237 | text \<open> | 
| 61788 | 3238 | Beyond the standard plugins, the \emph{Archive of Formal Proofs} includes a
 | 
| 3239 | \keyw{derive} command that derives class instances of datatypes
 | |
| 3240 | @{cite "sternagel-thiemann-2015"}.
 | |
| 62081 | 3241 | \<close> | 
| 3242 | ||
| 3243 | subsection \<open> Code Generator | |
| 3244 |   \label{ssec:code-generator} \<close>
 | |
| 3245 | ||
| 3246 | text \<open> | |
| 59299 | 3247 | The \hthm{code} plugin registers freely generated types, including
 | 
| 3248 | (co)datatypes, and (co)recursive functions for code generation. No distinction | |
| 3249 | is made between datatypes and codatatypes. This means that for target languages | |
| 3250 | with a strict evaluation strategy (e.g., Standard ML), programs that attempt to | |
| 3251 | produce infinite codatatype values will not terminate. | |
| 3252 | ||
| 3253 | For types, the plugin derives the following properties: | |
| 58244 | 3254 | |
| 3255 | \begin{indentblock}
 | |
| 3256 | \begin{description}
 | |
| 3257 | ||
| 3258 | \item[@{text "t."}\hthm{eq.refl} @{text "[code nbe]"}\rm:] ~ \\
 | |
| 3259 | @{thm list.eq.refl[no_vars]}
 | |
| 3260 | ||
| 3261 | \item[@{text "t."}\hthm{eq.simps} @{text "[code]"}\rm:] ~ \\
 | |
| 3262 | @{thm list.eq.simps(1)[no_vars]} \\
 | |
| 3263 | @{thm list.eq.simps(2)[no_vars]} \\
 | |
| 3264 | @{thm list.eq.simps(3)[no_vars]} \\
 | |
| 3265 | @{thm list.eq.simps(4)[no_vars]} \\
 | |
| 3266 | @{thm list.eq.simps(5)[no_vars]} \\
 | |
| 3267 | @{thm list.eq.simps(6)[no_vars]}
 | |
| 3268 | ||
| 3269 | \end{description}
 | |
| 3270 | \end{indentblock}
 | |
| 58509 | 3271 | |
| 3272 | In addition, the plugin sets the @{text "[code]"} attribute on a number of
 | |
| 59299 | 3273 | properties of freely generated types and of (co)recursive functions, as | 
| 3274 | documented in Sections \ref{ssec:datatype-generated-theorems},
 | |
| 3275 | \ref{ssec:primrec-generated-theorems}, \ref{ssec:codatatype-generated-theorems},
 | |
| 3276 | and~\ref{ssec:primcorec-generated-theorems}.
 | |
| 62081 | 3277 | \<close> | 
| 3278 | ||
| 3279 | ||
| 3280 | subsection \<open> Size | |
| 3281 |   \label{ssec:size} \<close>
 | |
| 3282 | ||
| 3283 | text \<open> | |
| 61787 | 3284 | For each datatype @{text t}, the \hthm{size} plugin generates a generic size
 | 
| 58190 | 3285 | function @{text "t.size_t"} as well as a specific instance
 | 
| 61787 | 3286 | @{text "size :: t \<Rightarrow> nat"} belonging to the @{text size} type class. The
 | 
| 3287 | \keyw{fun} command relies on @{const size} to prove termination of recursive
 | |
| 3288 | functions on datatypes. | |
| 58190 | 3289 | |
| 3290 | The plugin derives the following properties: | |
| 3291 | ||
| 3292 | \begin{indentblock}
 | |
| 3293 | \begin{description}
 | |
| 3294 | ||
| 3295 | \item[@{text "t."}\hthm{size} @{text "[simp, code]"}\rm:] ~ \\
 | |
| 3296 | @{thm list.size(1)[no_vars]} \\
 | |
| 3297 | @{thm list.size(2)[no_vars]} \\
 | |
| 3298 | @{thm list.size(3)[no_vars]} \\
 | |
| 3299 | @{thm list.size(4)[no_vars]}
 | |
| 3300 | ||
| 58737 | 3301 | \item[@{text "t."}\hthm{size_gen}\rm:] ~ \\
 | 
| 3302 | @{thm list.size_gen(1)[no_vars]} \\
 | |
| 3303 | @{thm list.size_gen(2)[no_vars]}
 | |
| 3304 | ||
| 58739 | 3305 | \item[@{text "t."}\hthm{size_gen_o_map}\rm:] ~ \\
 | 
| 3306 | @{thm list.size_gen_o_map[no_vars]}
 | |
| 58190 | 3307 | |
| 58914 | 3308 | \item[@{text "t."}\hthm{size_neq}\rm:] ~ \\
 | 
| 3309 | This property is missing for @{typ "'a list"}. If the @{term size} function
 | |
| 60134 | 3310 | always evaluates to a non-zero value, this theorem has the form | 
| 58914 | 3311 | @{prop "\<not> size x = 0"}.
 | 
| 3312 | ||
| 58190 | 3313 | \end{description}
 | 
| 3314 | \end{indentblock}
 | |
| 61787 | 3315 | |
| 3316 | The @{text "t.size"} and @{text "t.size_t"} functions generated for datatypes
 | |
| 3317 | defined by nested recursion through a datatype @{text u} depend on
 | |
| 3318 | @{text "u.size_u"}.
 | |
| 3319 | ||
| 3320 | If the recursion is through a non-datatype @{text u} with type arguments
 | |
| 3321 | @{text "'a\<^sub>1, \<dots>, 'a\<^sub>m"}, by default @{text u} values are given a size of 0. This
 | |
| 3322 | can be improved upon by registering a custom size function of type | |
| 3323 | @{text "('a\<^sub>1 \<Rightarrow> nat) \<Rightarrow> \<dots> \<Rightarrow> ('a\<^sub>m \<Rightarrow> nat) \<Rightarrow> u \<Rightarrow> nat"} using
 | |
| 61788 | 3324 | the ML function @{ML BNF_LFP_Size.register_size} or
 | 
| 3325 | @{ML BNF_LFP_Size.register_size_global}. See theory
 | |
| 61787 | 3326 | @{file "~~/src/HOL/Library/Multiset.thy"} for an example.
 | 
| 62081 | 3327 | \<close> | 
| 3328 | ||
| 3329 | ||
| 3330 | subsection \<open> Transfer | |
| 3331 |   \label{ssec:transfer} \<close>
 | |
| 3332 | ||
| 3333 | text \<open> | |
| 58192 | 3334 | For each (co)datatype with live type arguments and each manually registered BNF, | 
| 58245 | 3335 | the \hthm{transfer} plugin generates a predicator @{text "t.pred_t"} and
 | 
| 58244 | 3336 | properties that guide the Transfer tool. | 
| 3337 | ||
| 61349 | 3338 | For types with at least one live type argument and \emph{no dead type
 | 
| 3339 | arguments}, the plugin derives the following properties: | |
| 58244 | 3340 | |
| 3341 | \begin{indentblock}
 | |
| 3342 | \begin{description}
 | |
| 3343 | ||
| 3344 | \item[@{text "t."}\hthm{Domainp_rel} @{text "[relator_domain]"}\rm:] ~ \\
 | |
| 3345 | @{thm list.Domainp_rel[no_vars]}
 | |
| 3346 | ||
| 3347 | \item[@{text "t."}\hthm{pred_inject} @{text "[simp]"}\rm:] ~ \\
 | |
| 3348 | @{thm list.pred_inject(1)[no_vars]} \\
 | |
| 59579 | 3349 | @{thm list.pred_inject(2)[no_vars]} \\
 | 
| 3350 | This property is generated only for (co)datatypes. | |
| 58244 | 3351 | |
| 3352 | \item[@{text "t."}\hthm{rel_eq_onp}\rm:] ~ \\
 | |
| 3353 | @{thm list.rel_eq_onp[no_vars]}
 | |
| 3354 | ||
| 58374 
1b4d31b7bd10
fixed attribute name in docs (thanks to Andreas Lochbihler)
 blanchet parents: 
58357diff
changeset | 3355 | \item[@{text "t."}\hthm{left_total_rel} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 58244 | 3356 | @{thm list.left_total_rel[no_vars]}
 | 
| 3357 | ||
| 58374 
1b4d31b7bd10
fixed attribute name in docs (thanks to Andreas Lochbihler)
 blanchet parents: 
58357diff
changeset | 3358 | \item[@{text "t."}\hthm{left_unique_rel} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 58244 | 3359 | @{thm list.left_unique_rel[no_vars]}
 | 
| 3360 | ||
| 58374 
1b4d31b7bd10
fixed attribute name in docs (thanks to Andreas Lochbihler)
 blanchet parents: 
58357diff
changeset | 3361 | \item[@{text "t."}\hthm{right_total_rel} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 58244 | 3362 | @{thm list.right_total_rel[no_vars]}
 | 
| 3363 | ||
| 58374 
1b4d31b7bd10
fixed attribute name in docs (thanks to Andreas Lochbihler)
 blanchet parents: 
58357diff
changeset | 3364 | \item[@{text "t."}\hthm{right_unique_rel} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 58244 | 3365 | @{thm list.right_unique_rel[no_vars]}
 | 
| 3366 | ||
| 58374 
1b4d31b7bd10
fixed attribute name in docs (thanks to Andreas Lochbihler)
 blanchet parents: 
58357diff
changeset | 3367 | \item[@{text "t."}\hthm{bi_total_rel} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 58244 | 3368 | @{thm list.bi_total_rel[no_vars]}
 | 
| 3369 | ||
| 58374 
1b4d31b7bd10
fixed attribute name in docs (thanks to Andreas Lochbihler)
 blanchet parents: 
58357diff
changeset | 3370 | \item[@{text "t."}\hthm{bi_unique_rel} @{text "[transfer_rule]"}\rm:] ~ \\
 | 
| 58244 | 3371 | @{thm list.bi_unique_rel[no_vars]}
 | 
| 3372 | ||
| 3373 | \end{description}
 | |
| 3374 | \end{indentblock}
 | |
| 59282 | 3375 | |
| 61349 | 3376 | For (co)datatypes with at least one live type argument, the plugin sets the | 
| 3377 | @{text "[transfer_rule]"} attribute on the following (co)datatypes properties:
 | |
| 61788 | 3378 | @{text "t.case_"}\allowbreak @{text "transfer"},
 | 
| 3379 | @{text "t.sel_"}\allowbreak @{text "transfer"},
 | |
| 3380 | @{text "t.ctr_"}\allowbreak @{text "transfer"},
 | |
| 3381 | @{text "t.disc_"}\allowbreak @{text "transfer"},
 | |
| 3382 | @{text "t.rec_"}\allowbreak @{text "transfer"}, and
 | |
| 3383 | @{text "t.corec_"}\allowbreak @{text "transfer"}.
 | |
| 3384 | For (co)datatypes that further have \emph{no dead type arguments}, the plugin
 | |
| 3385 | sets @{text "[transfer_rule]"} on
 | |
| 3386 | @{text "t.set_"}\allowbreak @{text "transfer"},
 | |
| 3387 | @{text "t.map_"}\allowbreak @{text "transfer"}, and
 | |
| 3388 | @{text "t.rel_"}\allowbreak @{text "transfer"}.
 | |
| 59579 | 3389 | |
| 59282 | 3390 | For @{command primrec}, @{command primcorec}, and @{command primcorecursive},
 | 
| 59579 | 3391 | the plugin implements the generation of the @{text "f.transfer"} property,
 | 
| 3392 | conditioned by the @{text transfer} option, and sets the
 | |
| 3393 | @{text "[transfer_rule]"} attribute on these.
 | |
| 62081 | 3394 | \<close> | 
| 3395 | ||
| 3396 | ||
| 3397 | subsection \<open> Lifting | |
| 3398 |   \label{ssec:lifting} \<close>
 | |
| 3399 | ||
| 3400 | text \<open> | |
| 59721 | 3401 | For each (co)datatype and each manually registered BNF with at least one live | 
| 61349 | 3402 | type argument \emph{and no dead type arguments}, the \hthm{lifting} plugin
 | 
| 3403 | generates properties and attributes that guide the Lifting tool. | |
| 58244 | 3404 | |
| 3405 | The plugin derives the following property: | |
| 3406 | ||
| 3407 | \begin{indentblock}
 | |
| 3408 | \begin{description}
 | |
| 3409 | ||
| 3410 | \item[@{text "t."}\hthm{Quotient} @{text "[quot_map]"}\rm:] ~ \\
 | |
| 3411 | @{thm list.Quotient[no_vars]}
 | |
| 3412 | ||
| 3413 | \end{description}
 | |
| 3414 | \end{indentblock}
 | |
| 3415 | ||
| 61349 | 3416 | In addition, the plugin sets the @{text "[relator_eq]"} attribute on a
 | 
| 58508 | 3417 | variant of the @{text t.rel_eq_onp} property generated by the @{text lifting}
 | 
| 58244 | 3418 | plugin, the @{text "[relator_mono]"} attribute on @{text t.rel_mono}, and the
 | 
| 3419 | @{text "[relator_distr]"} attribute on @{text t.rel_compp}.
 | |
| 62081 | 3420 | \<close> | 
| 3421 | ||
| 3422 | ||
| 3423 | subsection \<open> Quickcheck | |
| 3424 |   \label{ssec:quickcheck} \<close>
 | |
| 3425 | ||
| 3426 | text \<open> | |
| 59280 | 3427 | The integration of datatypes with Quickcheck is accomplished by the | 
| 59282 | 3428 | \hthm{quick\-check} plugin. It combines a number of subplugins that instantiate
 | 
| 59280 | 3429 | specific type classes. The subplugins can be enabled or disabled individually. | 
| 3430 | They are listed below: | |
| 58245 | 3431 | |
| 3432 | \begin{indentblock}
 | |
| 3433 | \hthm{quickcheck_random} \\
 | |
| 3434 | \hthm{quickcheck_exhaustive} \\
 | |
| 3435 | \hthm{quickcheck_bounded_forall} \\
 | |
| 3436 | \hthm{quickcheck_full_exhaustive} \\
 | |
| 3437 | \hthm{quickcheck_narrowing}
 | |
| 3438 | \end{indentblock}
 | |
| 62081 | 3439 | \<close> | 
| 3440 | ||
| 3441 | ||
| 3442 | subsection \<open> Program Extraction | |
| 3443 |   \label{ssec:program-extraction} \<close>
 | |
| 3444 | ||
| 3445 | text \<open> | |
| 58278 | 3446 | The \hthm{extraction} plugin provides realizers for induction and case analysis,
 | 
| 3447 | to enable program extraction from proofs involving datatypes. This functionality | |
| 58395 | 3448 | is only available with full proof objects, i.e., with the \emph{HOL-Proofs}
 | 
| 58278 | 3449 | session. | 
| 62081 | 3450 | \<close> | 
| 3451 | ||
| 3452 | ||
| 3453 | section \<open> Known Bugs and Limitations | |
| 3454 |   \label{sec:known-bugs-and-limitations} \<close>
 | |
| 3455 | ||
| 3456 | text \<open> | |
| 58395 | 3457 | This section lists the known bugs and limitations in the (co)datatype package at | 
| 3458 | the time of this writing. Many of them are expected to be addressed in future | |
| 3459 | releases. | |
| 3460 | ||
| 3461 | \begin{enumerate}
 | |
| 3462 | \setlength{\itemsep}{0pt}
 | |
| 3463 | ||
| 3464 | \item | |
| 3465 | \emph{Defining mutually (co)recursive (co)datatypes is slow.} Fortunately,
 | |
| 3466 | it is always possible to recast mutual specifications to nested ones, which are | |
| 3467 | processed more efficiently. | |
| 3468 | ||
| 3469 | \item | |
| 60736 | 3470 | \emph{Locally fixed types and terms cannot be used in type specifications.}
 | 
| 3471 | The limitation on types can be circumvented by adding type arguments to the local | |
| 58395 | 3472 | (co)datatypes to abstract over the locally fixed types. | 
| 3473 | ||
| 3474 | \item | |
| 3475 | \emph{The \emph{\keyw{primcorec}} command does not allow user-specified names and
 | |
| 3476 | attributes next to the entered formulas.} The less convenient syntax, using the | |
| 3477 | \keyw{lemmas} command, is available as an alternative.
 | |
| 3478 | ||
| 3479 | \item | |
| 3480 | \emph{There is no way to use an overloaded constant from a syntactic type
 | |
| 3481 | class, such as @{text 0}, as a constructor.}
 | |
| 3482 | ||
| 3483 | \item | |
| 3484 | \emph{There is no way to register the same type as both a datatype and a
 | |
| 3485 | codatatype.} This affects types such as the extended natural numbers, for which | |
| 3486 | both views would make sense (for a different set of constructors). | |
| 3487 | ||
| 3488 | \item | |
| 3489 | \emph{The names of variables are often suboptimal in the properties generated by
 | |
| 3490 | the package.} | |
| 3491 | ||
| 60146 | 3492 | \item | 
| 3493 | \emph{The compatibility layer sometimes produces induction principles with a
 | |
| 61788 | 3494 | slightly different ordering of the premises than the old package.} | 
| 60146 | 3495 | |
| 58395 | 3496 | \end{enumerate}
 | 
| 62081 | 3497 | \<close> | 
| 3498 | ||
| 3499 | ||
| 3500 | text \<open> | |
| 53863 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 3501 | \section*{Acknowledgment}
 | 
| 
c7364dca96f2
textual improvements following Christian Sternagel's feedback
 blanchet parents: 
53857diff
changeset | 3502 | |
| 53749 
b37db925b663
adapted primcorec documentation to reflect the three views
 blanchet parents: 
53748diff
changeset | 3503 | Tobias Nipkow and Makarius Wenzel encouraged us to implement the new | 
| 53617 | 3504 | (co)datatype package. Andreas Lochbihler provided lots of comments on earlier | 
| 56655 | 3505 | versions of the package, especially on the coinductive part. Brian Huffman | 
| 58245 | 3506 | suggested major simplifications to the internal constructions. Ond\v{r}ej
 | 
| 3507 | Kun\v{c}ar implemented the @{text transfer} and @{text lifting} plugins.
 | |
| 60137 | 3508 | Christian Sternagel and Ren\'e Thiemann ported the \keyw{derive} command
 | 
| 62081 | 3509 | from the \emph{Archive of Formal Proofs} to the new datatypes. Gerwin Klein and
 | 
| 3510 | Lars Noschinski implemented the @{command simps_of_case} and @{command
 | |
| 3511 | case_of_simps} commands. Florian Haftmann, Christian Urban, and Makarius | |
| 3512 | Wenzel provided general advice on Isabelle and package writing. Stefan Milius | |
| 3513 | and Lutz Schr\"oder found an elegant proof that eliminated one of the BNF | |
| 3514 | proof obligations. Mamoun Filali-Amine, Gerwin Klein, Andreas Lochbihler, | |
| 3515 | Tobias Nipkow, and Christian Sternagel suggested many textual improvements to | |
| 3516 | this tutorial. | |
| 3517 | \<close> | |
| 53617 | 3518 | |
| 52792 | 3519 | end |