49 datatypes, or \emph{codatatypes}, which may have infinite values. For example, |
49 datatypes, or \emph{codatatypes}, which may have infinite values. For example, |
50 the following command introduces the type of lazy lists, which comprises both |
50 the following command introduces the type of lazy lists, which comprises both |
51 finite and infinite values: |
51 finite and infinite values: |
52 *} |
52 *} |
53 |
53 |
54 codatatype 'a llist (*<*)(map: lmap) (*>*)= LNil | LCons 'a "'a llist" |
54 (*<*) |
|
55 locale dummy_llist |
|
56 begin |
|
57 (*>*) |
|
58 codatatype 'a llist = LNil | LCons 'a "'a llist" |
55 |
59 |
56 text {* |
60 text {* |
57 \noindent |
61 \noindent |
58 Mixed inductive--coinductive recursion is possible via nesting. Compare the |
62 Mixed inductive--coinductive recursion is possible via nesting. Compare the |
59 following four Rose tree examples: |
63 following four Rose tree examples: |
60 *} |
64 *} |
61 |
65 |
62 (*<*) |
|
63 locale dummy_tree |
|
64 begin |
|
65 (*>*) |
|
66 datatype_new 'a tree\<^sub>f\<^sub>f = Node\<^sub>f\<^sub>f 'a "'a tree\<^sub>f\<^sub>f list" |
66 datatype_new 'a tree\<^sub>f\<^sub>f = Node\<^sub>f\<^sub>f 'a "'a tree\<^sub>f\<^sub>f list" |
67 datatype_new 'a tree\<^sub>f\<^sub>i = Node\<^sub>f\<^sub>i 'a "'a tree\<^sub>f\<^sub>i llist" |
67 datatype_new 'a tree\<^sub>f\<^sub>i = Node\<^sub>f\<^sub>i 'a "'a tree\<^sub>f\<^sub>i llist" |
68 codatatype 'a tree\<^sub>i\<^sub>f = Node\<^sub>i\<^sub>f 'a "'a tree\<^sub>i\<^sub>f list" |
68 codatatype 'a tree\<^sub>i\<^sub>f = Node\<^sub>i\<^sub>f 'a "'a tree\<^sub>i\<^sub>f list" |
69 codatatype 'a tree\<^sub>i\<^sub>i = Node\<^sub>i\<^sub>i 'a "'a tree\<^sub>i\<^sub>i llist" |
69 codatatype 'a tree\<^sub>i\<^sub>i = Node\<^sub>i\<^sub>i 'a "'a tree\<^sub>i\<^sub>i llist" |
70 (*<*) |
70 (*<*) |
555 \noindent |
555 \noindent |
556 where the \textit{names} argument is simply a space-separated list of type names |
556 where the \textit{names} argument is simply a space-separated list of type names |
557 that are mutually recursive. For example: |
557 that are mutually recursive. For example: |
558 *} |
558 *} |
559 |
559 |
560 datatype_new_compat enat onat |
560 datatype_new_compat even_nat odd_nat |
561 |
561 |
562 text {* \blankline *} |
562 text {* \blankline *} |
563 |
563 |
564 thm enat_onat.size |
564 thm even_nat_odd_nat.size |
565 |
565 |
566 text {* \blankline *} |
566 text {* \blankline *} |
567 |
567 |
568 ML {* Datatype_Data.get_info @{theory} @{type_name enat} *} |
568 ML {* Datatype_Data.get_info @{theory} @{type_name even_nat} *} |
569 |
569 |
570 text {* |
570 text {* |
571 For nested recursive datatypes, all types through which recursion takes place |
571 For nested recursive datatypes, all types through which recursion takes place |
572 must be new-style datatypes. In principle, it should be possible to support |
572 must be new-style datatypes. In principle, it should be possible to support |
573 old-style datatypes as well, but the command does not support this yet. |
573 old-style datatypes as well, but the command does not support this yet. |
987 The syntax for mutually recursive functions over mutually recursive datatypes |
987 The syntax for mutually recursive functions over mutually recursive datatypes |
988 is straightforward: |
988 is straightforward: |
989 *} |
989 *} |
990 |
990 |
991 primrec_new |
991 primrec_new |
992 nat_of_enat :: "enat \<Rightarrow> nat" and |
992 nat_of_even_nat :: "even_nat \<Rightarrow> nat" and |
993 nat_of_onat :: "onat \<Rightarrow> nat" |
993 nat_of_odd_nat :: "odd_nat \<Rightarrow> nat" |
994 where |
994 where |
995 "nat_of_enat EZero = Zero" | |
995 "nat_of_even_nat Even_Zero = Zero" | |
996 "nat_of_enat (ESuc n) = Suc (nat_of_onat n)" | |
996 "nat_of_even_nat (Even_Suc n) = Suc (nat_of_odd_nat n)" | |
997 "nat_of_onat (OSuc n) = Suc (nat_of_enat n)" |
997 "nat_of_odd_nat (Odd_Suc n) = Suc (nat_of_even_nat n)" |
998 |
998 |
999 primrec_new |
999 primrec_new |
1000 eval\<^sub>e :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) exp \<Rightarrow> int" and |
1000 eval\<^sub>e :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) exp \<Rightarrow> int" and |
1001 eval\<^sub>t :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) trm \<Rightarrow> int" and |
1001 eval\<^sub>t :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) trm \<Rightarrow> int" and |
1002 eval\<^sub>f :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) fct \<Rightarrow> int" |
1002 eval\<^sub>f :: "('a \<Rightarrow> int) \<Rightarrow> ('b \<Rightarrow> int) \<Rightarrow> ('a, 'b) fct \<Rightarrow> int" |
1267 |
1266 |
1268 section {* Defining Codatatypes |
1267 section {* Defining Codatatypes |
1269 \label{sec:defining-codatatypes} *} |
1268 \label{sec:defining-codatatypes} *} |
1270 |
1269 |
1271 text {* |
1270 text {* |
1272 This section describes how to specify codatatypes using the @{command |
1271 Codatatypes can be specified using the @{command codatatype} command. The |
1273 codatatype} command. The command is first illustrated through concrete examples |
1272 command is first illustrated through concrete examples featuring different |
1274 featuring different flavors of corecursion. More examples can be found in the |
1273 flavors of corecursion. More examples can be found in the directory |
1275 directory \verb|~~/src/HOL/BNF/Examples|. The \emph{Archive of Formal Proofs} |
1274 \verb|~~/src/HOL/BNF/Examples|. The \emph{Archive of Formal Proofs} also |
1276 also includes some useful codatatypes, notably for lazy lists |
1275 includes some useful codatatypes, notably for lazy lists \cite{lochbihler-2010}. |
1277 \cite{lochbihler-2010}. |
1276 *} |
1278 *} |
1277 |
1279 |
1278 |
1280 |
|
1281 (* |
|
1282 subsection {* Introductory Examples |
1279 subsection {* Introductory Examples |
1283 \label{ssec:codatatype-introductory-examples} *} |
1280 \label{ssec:codatatype-introductory-examples} *} |
1284 |
1281 |
1285 text {* |
1282 |
1286 More examples in \verb|~~/src/HOL/BNF/Examples|. |
1283 subsubsection {* Simple Corecursion |
1287 *} |
1284 \label{sssec:codatatype-simple-corecursion} *} |
1288 *) |
1285 |
|
1286 text {* |
|
1287 Noncorecursive codatatypes coincide with the corresponding datatypes, so |
|
1288 they have no practical uses. \emph{Corecursive codatatypes} have the same syntax |
|
1289 as recursive datatypes, except for the command name. For example, here is the |
|
1290 definition of lazy lists: |
|
1291 *} |
|
1292 |
|
1293 codatatype (lset: 'a) llist (map: lmap rel: llist_all2) = |
|
1294 lnull: LNil (defaults ltl: LNil) |
|
1295 | LCons (lhd: 'a) (ltl: "'a llist") |
|
1296 |
|
1297 text {* |
|
1298 \noindent |
|
1299 Lazy lists can be infinite, such as @{text "LCons 0 (LCons 0 (\<dots>))"} and |
|
1300 @{text "LCons 0 (LCons 1 (LCons 2 (\<dots>)))"}. Another interesting type that can |
|
1301 be defined as a codatatype is that of the extended natural numbers: |
|
1302 *} |
|
1303 |
|
1304 codatatype enat = EZero | ESuc nat |
|
1305 |
|
1306 text {* |
|
1307 \noindent |
|
1308 This type has exactly one infinite element, @{text "ESuc (ESuc (ESuc (\<dots>)))"}, |
|
1309 that represents $\infty$. In addition, it has finite values of the form |
|
1310 @{text "ESuc (\<dots> (ESuc EZero)\<dots>)"}. |
|
1311 *} |
|
1312 |
|
1313 |
|
1314 subsubsection {* Mutual Corecursion |
|
1315 \label{sssec:codatatype-mutual-corecursion} *} |
|
1316 |
|
1317 text {* |
|
1318 \noindent |
|
1319 The example below introduces a pair of \emph{mutually corecursive} types: |
|
1320 *} |
|
1321 |
|
1322 codatatype even_enat = Even_EZero | Even_ESuc odd_enat |
|
1323 and odd_enat = Odd_ESuc even_enat |
|
1324 |
|
1325 |
|
1326 subsubsection {* Nested Corecursion |
|
1327 \label{sssec:codatatype-nested-corecursion} *} |
|
1328 |
|
1329 text {* |
|
1330 \noindent |
|
1331 The next two examples feature \emph{nested corecursion}: |
|
1332 *} |
|
1333 |
|
1334 codatatype 'a tree\<^sub>i\<^sub>i = Node\<^sub>i\<^sub>i 'a "'a tree\<^sub>i\<^sub>i llist" |
|
1335 codatatype 'a tree\<^sub>i\<^sub>s = Node\<^sub>i\<^sub>s 'a "'a tree\<^sub>i\<^sub>s fset" |
1289 |
1336 |
1290 |
1337 |
1291 subsection {* Command Syntax |
1338 subsection {* Command Syntax |
1292 \label{ssec:codatatype-command-syntax} *} |
1339 \label{ssec:codatatype-command-syntax} *} |
1293 |
1340 |
1296 \label{sssec:codatatype} *} |
1343 \label{sssec:codatatype} *} |
1297 |
1344 |
1298 text {* |
1345 text {* |
1299 Definitions of codatatypes have almost exactly the same syntax as for datatypes |
1346 Definitions of codatatypes have almost exactly the same syntax as for datatypes |
1300 (Section~\ref{ssec:datatype-command-syntax}), with two exceptions: The command |
1347 (Section~\ref{ssec:datatype-command-syntax}), with two exceptions: The command |
1301 is called @{command codatatype}; the \keyw{no\_discs\_sels} option is not |
1348 is called @{command codatatype}. The @{text "no_discs_sels"} option is not |
1302 available, because destructors are a central notion for codatatypes. |
1349 available, because destructors are a crucial notion for codatatypes. |
1303 *} |
1350 *} |
1304 |
1351 |
1305 |
1352 |
1306 (* |
|
1307 subsection {* Generated Constants |
1353 subsection {* Generated Constants |
1308 \label{ssec:codatatype-generated-constants} *} |
1354 \label{ssec:codatatype-generated-constants} *} |
1309 *) |
1355 |
1310 |
1356 text {* |
1311 |
1357 Given a codatatype @{text "('a\<^sub>1, \<dots>, 'a\<^sub>m) t"} |
1312 (* |
1358 with $m > 0$ live type variables and $n$ constructors @{text "t.C\<^sub>1"}, |
|
1359 \ldots, @{text "t.C\<^sub>n"}, the same auxiliary constants are generated as for |
|
1360 datatypes (Section~\ref{ssec:datatype-generated-constants}), except that the |
|
1361 iterator and the recursor are replaced by dual concepts: |
|
1362 |
|
1363 \begin{itemize} |
|
1364 \setlength{\itemsep}{0pt} |
|
1365 |
|
1366 \item \relax{Coiterator}: @{text t_unfold} |
|
1367 |
|
1368 \item \relax{Corecursor}: @{text t_corec} |
|
1369 |
|
1370 \end{itemize} |
|
1371 *} |
|
1372 |
|
1373 |
1313 subsection {* Generated Theorems |
1374 subsection {* Generated Theorems |
1314 \label{ssec:codatatype-generated-theorems} *} |
1375 \label{ssec:codatatype-generated-theorems} *} |
1315 *) |
1376 |
|
1377 text {* |
|
1378 The characteristic theorems generated by @{command codatatype} are grouped in |
|
1379 three broad categories: |
|
1380 |
|
1381 \begin{itemize} |
|
1382 \item The \emph{free constructor theorems} are properties about the constructors |
|
1383 and destructors that can be derived for any freely generated type. |
|
1384 |
|
1385 \item The \emph{functorial theorems} are properties of datatypes related to |
|
1386 their BNF nature. |
|
1387 |
|
1388 \item The \emph{coinductive theorems} are properties of datatypes related to |
|
1389 their coinductive nature. |
|
1390 \end{itemize} |
|
1391 |
|
1392 \noindent |
|
1393 The first two categories are exactly as for datatypes and are described in |
|
1394 Sections \ref{ssec:free-constructor-theorems}~and~\ref{ssec:functorial-theorems}. |
|
1395 *} |
|
1396 |
|
1397 |
|
1398 subsubsection {* Coinductive Theorems |
|
1399 \label{sssec:coinductive-theorems} *} |
|
1400 |
|
1401 text {* |
|
1402 The coinductive theorems are as follows: |
|
1403 |
|
1404 % [(coinductN, map single coinduct_thms, |
|
1405 % fn T_name => coinduct_attrs @ [coinduct_type_attr T_name]), |
|
1406 % (corecN, corec_thmss, K coiter_attrs), |
|
1407 % (disc_corecN, disc_corec_thmss, K disc_coiter_attrs), |
|
1408 % (disc_corec_iffN, disc_corec_iff_thmss, K disc_coiter_iff_attrs), |
|
1409 % (disc_unfoldN, disc_unfold_thmss, K disc_coiter_attrs), |
|
1410 % (disc_unfold_iffN, disc_unfold_iff_thmss, K disc_coiter_iff_attrs), |
|
1411 % (sel_corecN, sel_corec_thmss, K sel_coiter_attrs), |
|
1412 % (sel_unfoldN, sel_unfold_thmss, K sel_coiter_attrs), |
|
1413 % (simpsN, simp_thmss, K []), |
|
1414 % (strong_coinductN, map single strong_coinduct_thms, K coinduct_attrs), |
|
1415 % (unfoldN, unfold_thmss, K coiter_attrs)] |
|
1416 % |> massage_multi_notes; |
|
1417 |
|
1418 \begin{indentblock} |
|
1419 \begin{description} |
|
1420 |
|
1421 \item[@{text "t."}\hthm{coinduct} @{text "[induct t, case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rmfamily:] ~ \\ |
|
1422 @{thm llist.coinduct[no_vars]} |
|
1423 |
|
1424 \item[@{text "t\<^sub>1_\<dots>_t\<^sub>m."}\hthm{coinduct} @{text "[case_names C\<^sub>1 \<dots> C\<^sub>n]"}\rmfamily:] ~ \\ |
|
1425 Given $m > 1$ mutually recursive datatypes, this induction rule can be used to |
|
1426 prove $m$ properties simultaneously. |
|
1427 |
|
1428 \item[@{text "t."}\hthm{unfold} @{text "[code]"}\rmfamily:] ~ \\ |
|
1429 @{thm llist.unfold(1)[no_vars]} \\ |
|
1430 @{thm llist.unfold(2)[no_vars]} |
|
1431 |
|
1432 \item[@{text "t."}\hthm{corec} @{text "[code]"}\rmfamily:] ~ \\ |
|
1433 @{thm llist.corec(1)[no_vars]} \\ |
|
1434 @{thm llist.corec(2)[no_vars]} |
|
1435 |
|
1436 \end{description} |
|
1437 \end{indentblock} |
|
1438 |
|
1439 \noindent |
|
1440 For convenience, @{command codatatype} also provides the following collection: |
|
1441 |
|
1442 \begin{indentblock} |
|
1443 \begin{description} |
|
1444 |
|
1445 \item[@{text "t."}\hthm{simps} = @{text t.inject} @{text t.distinct} @{text t.case} @{text t.rec} @{text t.fold} @{text t.map} @{text t.rel_inject}] ~ \\ |
|
1446 @{text t.rel_distinct} @{text t.sets} |
|
1447 |
|
1448 \end{description} |
|
1449 \end{indentblock} |
|
1450 *} |
1316 |
1451 |
1317 |
1452 |
1318 section {* Defining Corecursive Functions |
1453 section {* Defining Corecursive Functions |
1319 \label{sec:defining-corecursive-functions} *} |
1454 \label{sec:defining-corecursive-functions} *} |
1320 |
1455 |
1321 text {* |
1456 text {* |
1322 This section describes how to specify corecursive functions using the |
1457 Corecursive functions can be specified using the @{command primcorec} command. |
1323 @{command primcorec} command. |
|
1324 |
1458 |
1325 %%% TODO: partial_function? E.g. for defining tail recursive function on lazy |
1459 %%% TODO: partial_function? E.g. for defining tail recursive function on lazy |
1326 %%% lists (cf. terminal0 in TLList.thy) |
1460 %%% lists (cf. terminal0 in TLList.thy) |
1327 *} |
1461 *} |
1328 |
1462 |
1418 |
1559 |
1419 section {* Deriving Destructors and Theorems for Free Constructors |
1560 section {* Deriving Destructors and Theorems for Free Constructors |
1420 \label{sec:deriving-destructors-and-theorems-for-free-constructors} *} |
1561 \label{sec:deriving-destructors-and-theorems-for-free-constructors} *} |
1421 |
1562 |
1422 text {* |
1563 text {* |
1423 This section explains how to derive convenience theorems for free constructors, |
1564 The derivation of convenience theorems for types equipped with free constructors, |
1424 as performed internally by @{command datatype_new} and @{command codatatype}. |
1565 as performed internally by @{command datatype_new} and @{command codatatype}, |
|
1566 is available as a stand-alone command called @{command wrap_free_constructors}. |
1425 |
1567 |
1426 % * need for this is rare but may arise if you want e.g. to add destructors to |
1568 % * need for this is rare but may arise if you want e.g. to add destructors to |
1427 % a type not introduced by ... |
1569 % a type not introduced by ... |
1428 % |
1570 % |
1429 % * also useful for compatibility with old package, e.g. add destructors to |
1571 % * also useful for compatibility with old package, e.g. add destructors to |
1430 % old \keyw{datatype} |
1572 % old \keyw{datatype} |
1431 % |
1573 % |
1432 % * @{command wrap_free_constructors} |
1574 % * @{command wrap_free_constructors} |
1433 % * \keyw{no\_discs\_sels}, \keyw{rep\_compat} |
1575 % * @{text "no_discs_sels"}, @{text "rep_compat"} |
1434 % * hack to have both co and nonco view via locale (cf. ext nats) |
1576 % * hack to have both co and nonco view via locale (cf. ext nats) |
1435 *} |
1577 *} |
1436 |
1578 |
1437 |
1579 |
1438 (* |
1580 (* |