author | blanchet |
Mon, 24 Oct 2016 20:32:02 +0200 | |
changeset 64383 | b9d4efb43fd9 |
parent 64380 | 4b22e1268779 |
child 64384 | f8c1c12d6af5 |
permissions | -rw-r--r-- |
62739 | 1 |
(* Title: Doc/Corec/Corec.thy |
2 |
Author: Jasmin Blanchette, Inria, LORIA, MPII |
|
3 |
Author: Aymeric Bouzy, Ecole polytechnique |
|
4 |
Author: Andreas Lochbihler, ETH Zuerich |
|
5 |
Author: Andrei Popescu, Middlesex University |
|
6 |
Author: Dmitriy Traytel, ETH Zuerich |
|
7 |
||
8 |
Tutorial for nonprimitively corecursive definitions. |
|
9 |
*) |
|
10 |
||
11 |
theory Corec |
|
12 |
imports |
|
62742 | 13 |
GCD |
62739 | 14 |
"../Datatypes/Setup" |
15 |
"~~/src/HOL/Library/BNF_Corec" |
|
62742 | 16 |
"~~/src/HOL/Library/FSet" |
62739 | 17 |
begin |
18 |
||
19 |
section \<open>Introduction |
|
20 |
\label{sec:introduction}\<close> |
|
21 |
||
22 |
text \<open> |
|
62756 | 23 |
Isabelle's (co)datatype package @{cite "isabelle-datatypes"} offers a convenient |
24 |
syntax for introducing codatatypes. For example, the type of (infinite) streams |
|
63680 | 25 |
can be defined as follows (cf. \<^file>\<open>~~/src/HOL/Library/Stream.thy\<close>): |
62756 | 26 |
\<close> |
27 |
||
28 |
codatatype 'a stream = |
|
29 |
SCons (shd: 'a) (stl: "'a stream") |
|
30 |
||
31 |
text \<open> |
|
32 |
\noindent |
|
33 |
The (co)datatype package also provides two commands, \keyw{primcorec} and |
|
34 |
\keyw{prim\-corec\-ur\-sive}, for defining primitively corecursive functions. |
|
35 |
||
36 |
This tutorial presents a definitional package for functions beyond |
|
37 |
primitive corecursion. It describes @{command corec} and related commands:\ |
|
38 |
@{command corecursive}, @{command friend_of_corec}, and @{command coinduction_upto}. |
|
39 |
It also covers the @{method corec_unique} proof method. |
|
40 |
The package is not part of @{theory Main}; it is located in |
|
63680 | 41 |
\<^file>\<open>~~/src/HOL/Library/BNF_Corec.thy\<close>. |
62742 | 42 |
|
62756 | 43 |
The @{command corec} command generalizes \keyw{primcorec} in three main |
44 |
respects. First, it allows multiple constructors around corecursive calls, where |
|
45 |
\keyw{primcorec} expects exactly one. For example: |
|
46 |
\<close> |
|
47 |
||
48 |
corec oneTwos :: "nat stream" where |
|
49 |
"oneTwos = SCons 1 (SCons 2 oneTwos)" |
|
50 |
||
51 |
text \<open> |
|
52 |
Second, @{command corec} allows other functions than constructors to appear in |
|
53 |
the corecursive call context (i.e., around any self-calls on the right-hand side |
|
54 |
of the equation). The requirement on these functions is that they must be |
|
55 |
\emph{friendly}. Intuitively, a function is friendly if it needs to destruct |
|
56 |
at most one constructor of input to produce one constructor of output. |
|
57 |
We can register functions as friendly using the @{command friend_of_corec} |
|
58 |
command, or by passing the @{text friend} option to @{command corec}. The |
|
59 |
friendliness check relies on an internal syntactic check in combination with |
|
60 |
a parametricity subgoal, which must be discharged manually (typically using |
|
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
61 |
@{method transfer_prover} or @{method transfer_prover_eq}). |
62756 | 62 |
|
63 |
Third, @{command corec} allows self-calls that are not guarded by a constructor, |
|
64 |
as long as these calls occur in a friendly context (a context consisting |
|
65 |
exclusively of friendly functions) and can be shown to be terminating |
|
66 |
(well founded). The mixture of recursive and corecursive calls in a single |
|
67 |
function can be quite useful in practice. |
|
62742 | 68 |
|
62756 | 69 |
Internally, the package synthesizes corecursors that take into account the |
70 |
possible call contexts. The corecursor is accompanined by a corresponding, |
|
71 |
equally general coinduction principle. The corecursor and the coinduction |
|
72 |
principle grow in expressiveness as we interact with it. In process algebra |
|
73 |
terminology, corecursion and coinduction take place \emph{up to} friendly |
|
74 |
contexts. |
|
62745 | 75 |
|
62756 | 76 |
The package fully adheres to the LCF philosophy @{cite mgordon79}: The |
77 |
characteristic theorems associated with the specified corecursive functions are |
|
78 |
derived rather than introduced axiomatically.% |
|
79 |
\footnote{However, most of the internal proof obligations are omitted if the |
|
80 |
@{text quick_and_dirty} option is enabled.} |
|
81 |
The package is described in a pair of scientific papers |
|
82 |
@{cite "blanchette-et-al-2015-fouco" and "blanchette-et-al-2016-fouco2"}. Some |
|
83 |
of the text and examples below originate from there. |
|
84 |
||
85 |
This tutorial is organized as follows: |
|
86 |
||
87 |
\begin{itemize} |
|
88 |
\setlength{\itemsep}{0pt} |
|
89 |
||
90 |
\item Section \ref{sec:introductory-examples}, ``Introductory Examples,'' |
|
91 |
describes how to specify corecursive functions and to reason about them. |
|
62742 | 92 |
|
62756 | 93 |
\item Section \ref{sec:command-syntax}, ``Command Syntax,'' describes the syntax |
94 |
of the commands offered by the package. |
|
95 |
||
96 |
\item Section \ref{sec:generated-theorems}, ``Generated Theorems,'' lists the |
|
97 |
theorems produced by the package's commands. |
|
98 |
||
99 |
\item Section \ref{sec:proof-method}, ``Proof Method,'' briefly describes the |
|
100 |
@{method corec_unique} proof method. |
|
101 |
||
102 |
\item Section \ref{sec:known-bugs-and-limitations}, ``Known Bugs and |
|
103 |
Limitations,'' concludes with known open issues. |
|
104 |
\end{itemize} |
|
62747 | 105 |
|
62756 | 106 |
Although it is more powerful than \keyw{primcorec} in many respects, |
107 |
@{command corec} suffers from a number of limitations. Most notably, it does |
|
108 |
not support mutually corecursive codatatypes, and it is less efficient than |
|
109 |
\keyw{primcorec} because it needs to dynamically synthesize corecursors and |
|
110 |
corresponding coinduction principles to accommodate the friends. |
|
111 |
||
112 |
\newbox\boxA |
|
113 |
\setbox\boxA=\hbox{\texttt{NOSPAM}} |
|
114 |
||
115 |
\newcommand\authoremaili{\texttt{jasmin.blan{\color{white}NOSPAM}\kern-\wd\boxA{}chette@\allowbreak |
|
116 |
gmail.\allowbreak com}} |
|
117 |
||
118 |
Comments and bug reports concerning either the package or this tutorial should |
|
119 |
be directed to the first author at \authoremaili{} or to the |
|
120 |
\texttt{cl-isabelle-users} mailing list. |
|
62739 | 121 |
\<close> |
122 |
||
123 |
||
124 |
section \<open>Introductory Examples |
|
125 |
\label{sec:introductory-examples}\<close> |
|
126 |
||
62742 | 127 |
text \<open> |
62756 | 128 |
The package is illustrated through concrete examples featuring different flavors |
129 |
of corecursion. More examples can be found in the directory |
|
63680 | 130 |
\<^dir>\<open>~~/src/HOL/Corec_Examples\<close>. |
62742 | 131 |
\<close> |
132 |
||
62739 | 133 |
|
134 |
subsection \<open>Simple Corecursion |
|
135 |
\label{ssec:simple-corecursion}\<close> |
|
136 |
||
62742 | 137 |
text \<open> |
62747 | 138 |
The case studies by Rutten~@{cite rutten05} and Hinze~@{cite hinze10} on stream |
62756 | 139 |
calculi serve as our starting point. The following definition of pointwise sum |
140 |
can be performed with either \keyw{primcorec} or @{command corec}: |
|
62742 | 141 |
\<close> |
142 |
||
143 |
primcorec ssum :: "('a :: plus) stream \<Rightarrow> 'a stream \<Rightarrow> 'a stream" where |
|
144 |
"ssum xs ys = SCons (shd xs + shd ys) (ssum (stl xs) (stl ys))" |
|
145 |
||
146 |
text \<open> |
|
147 |
\noindent |
|
148 |
Pointwise sum meets the friendliness criterion. We register it as a friend using |
|
149 |
the @{command friend_of_corec} command. The command requires us to give a |
|
150 |
specification of @{const ssum} where a constructor (@{const SCons}) occurs at |
|
151 |
the outermost position on the right-hand side. Here, we can simply reuse the |
|
152 |
\keyw{primcorec} specification above: |
|
153 |
\<close> |
|
154 |
||
155 |
friend_of_corec ssum :: "('a :: plus) stream \<Rightarrow> 'a stream \<Rightarrow> 'a stream" where |
|
156 |
"ssum xs ys = SCons (shd xs + shd ys) (ssum (stl xs) (stl ys))" |
|
157 |
apply (rule ssum.code) |
|
158 |
by transfer_prover |
|
159 |
||
160 |
text \<open> |
|
161 |
\noindent |
|
62756 | 162 |
The command emits two subgoals. The first subgoal corresponds to the equation we |
163 |
specified and is trivial to discharge. The second subgoal is a parametricity |
|
164 |
property that captures the the requirement that the function may destruct at |
|
165 |
most one constructor of input to produce one constructor of output. This subgoal |
|
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
166 |
can usually be discharged using the @{text transfer_prover} or |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
167 |
@{method transfer_prover_eq} proof method. The latter replaces equality relations |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
168 |
by their relator terms according to the theorem collection @{thm [source] relator_eq} |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
169 |
before it calles @{method transfer_prover}. |
62742 | 170 |
|
171 |
After registering @{const ssum} as a friend, we can use it in the corecursive |
|
172 |
call context, either inside or outside the constructor guard: |
|
173 |
\<close> |
|
174 |
||
175 |
corec fibA :: "nat stream" where |
|
176 |
"fibA = SCons 0 (ssum (SCons 1 fibA) fibA)" |
|
177 |
||
178 |
text \<open>\blankline\<close> |
|
179 |
||
180 |
corec fibB :: "nat stream" where |
|
181 |
"fibB = ssum (SCons 0 (SCons 1 fibB)) (SCons 0 fibB)" |
|
182 |
||
183 |
text \<open> |
|
184 |
Using the @{text "friend"} option, we can simultaneously define a function and |
|
185 |
register it as a friend: |
|
186 |
\<close> |
|
187 |
||
188 |
corec (friend) |
|
189 |
sprod :: "('a :: {plus,times}) stream \<Rightarrow> 'a stream \<Rightarrow> 'a stream" |
|
190 |
where |
|
191 |
"sprod xs ys = |
|
192 |
SCons (shd xs * shd ys) (ssum (sprod xs (stl ys)) (sprod (stl xs) ys))" |
|
193 |
||
194 |
text \<open>\blankline\<close> |
|
195 |
||
196 |
corec (friend) sexp :: "nat stream \<Rightarrow> nat stream" where |
|
197 |
"sexp xs = SCons (2 ^^ shd xs) (sprod (stl xs) (sexp xs))" |
|
198 |
||
199 |
text \<open> |
|
200 |
\noindent |
|
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
201 |
The parametricity subgoal is given to @{text transfer_prover_eq}. |
62742 | 202 |
|
203 |
The @{const sprod} and @{const sexp} functions provide shuffle product and |
|
204 |
exponentiation on streams. We can use them to define the stream of factorial |
|
205 |
numbers in two different ways: |
|
206 |
\<close> |
|
207 |
||
208 |
corec factA :: "nat stream" where |
|
209 |
"factA = (let zs = SCons 1 factA in sprod zs zs)" |
|
210 |
||
62756 | 211 |
text \<open>\blankline\<close> |
212 |
||
62742 | 213 |
corec factB :: "nat stream" where |
214 |
"factB = sexp (SCons 0 factB)" |
|
215 |
||
216 |
text \<open> |
|
62756 | 217 |
The arguments of friendly functions can be of complex types involving the |
62742 | 218 |
target codatatype. The following example defines the supremum of a finite set of |
219 |
streams by primitive corecursion and registers it as friendly: |
|
220 |
\<close> |
|
221 |
||
222 |
corec (friend) sfsup :: "nat stream fset \<Rightarrow> nat stream" where |
|
223 |
"sfsup X = SCons (Sup (fset (fimage shd X))) (sfsup (fimage stl X))" |
|
224 |
||
225 |
text \<open> |
|
226 |
\noindent |
|
62756 | 227 |
In general, the arguments may be any bounded natural functor (BNF) |
228 |
@{cite "isabelle-datatypes"}, with the restriction that the target codatatype |
|
229 |
(@{typ "nat stream"}) may occur only in a \emph{live} position of the BNF. For |
|
230 |
this reason, the following function, on unbounded sets, cannot be registered as |
|
231 |
a friend: |
|
62742 | 232 |
\<close> |
233 |
||
62756 | 234 |
primcorec ssup :: "nat stream set \<Rightarrow> nat stream" where |
62742 | 235 |
"ssup X = SCons (Sup (image shd X)) (ssup (image stl X))" |
236 |
||
62739 | 237 |
|
238 |
subsection \<open>Nested Corecursion |
|
239 |
\label{ssec:nested-corecursion}\<close> |
|
240 |
||
62742 | 241 |
text \<open> |
242 |
The package generally supports arbitrary codatatypes with multiple constructors |
|
243 |
and nesting through other type constructors (BNFs). Consider the following type |
|
244 |
of finitely branching Rose trees of potentially infinite depth: |
|
245 |
\<close> |
|
62739 | 246 |
|
62742 | 247 |
codatatype 'a tree = |
248 |
Node (lab: 'a) (sub: "'a tree list") |
|
249 |
||
250 |
text \<open> |
|
251 |
We first define the pointwise sum of two trees analogously to @{const ssum}: |
|
252 |
\<close> |
|
253 |
||
62756 | 254 |
corec (friend) tsum :: "('a :: plus) tree \<Rightarrow> 'a tree \<Rightarrow> 'a tree" where |
255 |
"tsum t u = |
|
256 |
Node (lab t + lab u) (map (\<lambda>(t', u'). tsum t' u') (zip (sub t) (sub u)))" |
|
62742 | 257 |
|
258 |
text \<open> |
|
259 |
\noindent |
|
260 |
Here, @{const map} is the standard map function on lists, and @{const zip} |
|
62756 | 261 |
converts two parallel lists into a list of pairs. The @{const tsum} function is |
62742 | 262 |
primitively corecursive. Instead of @{text "corec (friend)"}, we could also have |
263 |
used \keyw{primcorec} and @{command friend_of_corec}, as we did for |
|
264 |
@{const ssum}. |
|
265 |
||
62756 | 266 |
Once @{const tsum} is registered as friendly, we can use it in the corecursive |
267 |
call context of another function: |
|
62742 | 268 |
\<close> |
269 |
||
270 |
corec (friend) ttimes :: "('a :: {plus,times}) tree \<Rightarrow> 'a tree \<Rightarrow> 'a tree" where |
|
271 |
"ttimes t u = Node (lab t * lab u) |
|
62756 | 272 |
(map (\<lambda>(t', u'). tsum (ttimes t u') (ttimes t' u)) (zip (sub t) (sub u)))" |
62742 | 273 |
|
62747 | 274 |
text \<open> |
275 |
All the syntactic convenience provided by \keyw{primcorec} is also supported by |
|
276 |
@{command corec}, @{command corecursive}, and @{command friend_of_corec}. In |
|
277 |
particular, nesting through the function type can be expressed using |
|
278 |
@{text \<lambda>}-abstractions and function applications rather than through composition |
|
279 |
(@{term "op \<circ>"}, the map function for @{text \<Rightarrow>}). For example: |
|
280 |
\<close> |
|
281 |
||
282 |
codatatype 'a language = |
|
283 |
Lang (\<oo>: bool) (\<dd>: "'a \<Rightarrow> 'a language") |
|
284 |
||
285 |
text \<open>\blankline\<close> |
|
286 |
||
287 |
corec (friend) Plus :: "'a language \<Rightarrow> 'a language \<Rightarrow> 'a language" where |
|
288 |
"Plus r s = Lang (\<oo> r \<or> \<oo> s) (\<lambda>a. Plus (\<dd> r a) (\<dd> s a))" |
|
289 |
||
290 |
text \<open>\blankline\<close> |
|
291 |
||
292 |
corec (friend) Times :: "'a language \<Rightarrow> 'a language \<Rightarrow> 'a language" where |
|
293 |
"Times r s = Lang (\<oo> r \<and> \<oo> s) |
|
294 |
(\<lambda>a. if \<oo> r then Plus (Times (\<dd> r a) s) (\<dd> s a) else Times (\<dd> r a) s)" |
|
295 |
||
296 |
text \<open>\blankline\<close> |
|
297 |
||
298 |
corec (friend) Star :: "'a language \<Rightarrow> 'a language" where |
|
299 |
"Star r = Lang True (\<lambda>a. Times (\<dd> r a) (Star r))" |
|
300 |
||
301 |
text \<open>\blankline\<close> |
|
302 |
||
303 |
corec (friend) Inter :: "'a language \<Rightarrow> 'a language \<Rightarrow> 'a language" where |
|
304 |
"Inter r s = Lang (\<oo> r \<and> \<oo> s) (\<lambda>a. Inter (\<dd> r a) (\<dd> s a))" |
|
305 |
||
306 |
text \<open>\blankline\<close> |
|
307 |
||
308 |
corec (friend) PLUS :: "'a language list \<Rightarrow> 'a language" where |
|
309 |
"PLUS xs = Lang (\<exists>x \<in> set xs. \<oo> x) (\<lambda>a. PLUS (map (\<lambda>r. \<dd> r a) xs))" |
|
310 |
||
62742 | 311 |
|
312 |
subsection \<open>Mixed Recursion--Corecursion |
|
313 |
\label{ssec:mixed-recursion-corecursion}\<close> |
|
314 |
||
315 |
text \<open> |
|
316 |
It is often convenient to let a corecursive function perform some finite |
|
317 |
computation before producing a constructor. With mixed recursion--corecursion, a |
|
318 |
finite number of unguarded recursive calls perform this calculation before |
|
62756 | 319 |
reaching a guarded corecursive call. Intuitively, the unguarded recursive call |
320 |
can be unfolded to arbitrary finite depth, ultimately yielding a purely |
|
321 |
corecursive definition. An example is the @{term primes} function from Di |
|
322 |
Gianantonio and Miculan @{cite "di-gianantonio-miculan-2003"}: |
|
62742 | 323 |
\<close> |
324 |
||
325 |
corecursive primes :: "nat \<Rightarrow> nat \<Rightarrow> nat stream" where |
|
326 |
"primes m n = |
|
327 |
(if (m = 0 \<and> n > 1) \<or> coprime m n then |
|
328 |
SCons n (primes (m * n) (n + 1)) |
|
329 |
else |
|
330 |
primes m (n + 1))" |
|
331 |
apply (relation "measure (\<lambda>(m, n). |
|
332 |
if n = 0 then 1 else if coprime m n then 0 else m - n mod m)") |
|
333 |
apply (auto simp: mod_Suc intro: Suc_lessI) |
|
334 |
apply (metis One_nat_def coprime_Suc_nat gcd.commute gcd_red_nat) |
|
335 |
by (metis diff_less_mono2 lessI mod_less_divisor) |
|
336 |
||
337 |
text \<open> |
|
338 |
\noindent |
|
339 |
The @{command corecursive} command is a variant of @{command corec} that allows |
|
340 |
us to specify a termination argument for any unguarded self-call. |
|
341 |
||
62756 | 342 |
When called with @{text "m = 1"} and @{text "n = 2"}, the @{const primes} |
62742 | 343 |
function computes the stream of prime numbers. The unguarded call in the |
344 |
@{text else} branch increments @{term n} until it is coprime to the first |
|
345 |
argument @{term m} (i.e., the greatest common divisor of @{term m} and |
|
62756 | 346 |
@{term n} is @{text 1}). |
62742 | 347 |
|
348 |
For any positive integers @{term m} and @{term n}, the numbers @{term m} and |
|
62756 | 349 |
@{text "m * n + 1"} are coprime, yielding an upper bound on the number of times |
62742 | 350 |
@{term n} is increased. Hence, the function will take the @{text else} branch at |
351 |
most finitely often before taking the then branch and producing one constructor. |
|
62756 | 352 |
There is a slight complication when @{text "m = 0 \<and> n > 1"}: Without the first |
62742 | 353 |
disjunct in the @{text "if"} condition, the function could stall. (This corner |
62747 | 354 |
case was overlooked in the original example |
355 |
@{cite "di-gianantonio-miculan-2003"}.) |
|
62742 | 356 |
|
62747 | 357 |
In the following examples, termination is discharged automatically by |
358 |
@{command corec} by invoking @{method lexicographic_order}: |
|
62742 | 359 |
\<close> |
360 |
||
361 |
corec catalan :: "nat \<Rightarrow> nat stream" where |
|
362 |
"catalan n = |
|
363 |
(if n > 0 then ssum (catalan (n - 1)) (SCons 0 (catalan (n + 1))) |
|
364 |
else SCons 1 (catalan 1))" |
|
365 |
||
62756 | 366 |
text \<open>\blankline\<close> |
367 |
||
62747 | 368 |
corec collatz :: "nat \<Rightarrow> nat stream" where |
369 |
"collatz n = (if even n \<and> n > 0 then collatz (n div 2) |
|
370 |
else SCons n (collatz (3 * n + 1)))" |
|
371 |
||
62742 | 372 |
text \<open> |
373 |
A more elaborate case study, revolving around the filter function on lazy lists, |
|
63680 | 374 |
is presented in \<^file>\<open>~~/src/HOL/Corec_Examples/LFilter.thy\<close>. |
62742 | 375 |
\<close> |
376 |
||
377 |
||
378 |
subsection \<open>Self-Friendship |
|
379 |
\label{ssec:self-friendship}\<close> |
|
380 |
||
381 |
text \<open> |
|
62756 | 382 |
The package allows us to simultaneously define a function and use it as its own |
383 |
friend, as in the following definition of a ``skewed product'': |
|
62742 | 384 |
\<close> |
385 |
||
386 |
corec (friend) |
|
387 |
sskew :: "('a :: {plus,times}) stream \<Rightarrow> 'a stream \<Rightarrow> 'a stream" |
|
388 |
where |
|
389 |
"sskew xs ys = |
|
390 |
SCons (shd xs * shd ys) (sskew (sskew xs (stl ys)) (sskew (stl xs) ys))" |
|
391 |
||
392 |
text \<open> |
|
393 |
\noindent |
|
394 |
Such definitions, with nested self-calls on the right-hand side, cannot be |
|
395 |
separated into a @{command corec} part and a @{command friend_of_corec} part. |
|
396 |
\<close> |
|
62739 | 397 |
|
398 |
||
399 |
subsection \<open>Coinduction |
|
400 |
\label{ssec:coinduction}\<close> |
|
401 |
||
62742 | 402 |
text \<open> |
403 |
Once a corecursive specification has been accepted, we normally want to reason |
|
404 |
about it. The @{text codatatype} command generates a structural coinduction |
|
405 |
principle that matches primitively corecursive functions. For nonprimitive |
|
406 |
specifications, our package provides the more advanced proof principle of |
|
407 |
\emph{coinduction up to congruence}---or simply \emph{coinduction up-to}. |
|
408 |
||
409 |
The structural coinduction principle for @{typ "'a stream"}, called |
|
410 |
@{thm [source] stream.coinduct}, is as follows: |
|
411 |
% |
|
62747 | 412 |
\begin{indentblock} |
413 |
@{thm stream.coinduct[no_vars]} |
|
414 |
\end{indentblock} |
|
62742 | 415 |
% |
416 |
Coinduction allows us to prove an equality @{text "l = r"} on streams by |
|
417 |
providing a relation @{text R} that relates @{text l} and @{text r} (first |
|
418 |
premise) and that constitutes a bisimulation (second premise). Streams that are |
|
419 |
related by a bisimulation cannot be distinguished by taking observations (via |
|
420 |
the selectors @{const shd} and @{const stl}); hence they must be equal. |
|
421 |
||
422 |
The coinduction up-to principle after registering @{const sskew} as friendly is |
|
62747 | 423 |
available as @{thm [source] sskew.coinduct} and as one of the components of |
62756 | 424 |
the theorem collection @{thm [source] stream.coinduct_upto}: |
62742 | 425 |
% |
62747 | 426 |
\begin{indentblock} |
62756 | 427 |
@{thm sskew.coinduct[no_vars]} |
62747 | 428 |
\end{indentblock} |
62742 | 429 |
% |
430 |
This rule is almost identical to structural coinduction, except that the |
|
62756 | 431 |
corecursive application of @{term R} is generalized to |
432 |
@{term "stream.v5.congclp R"}. |
|
433 |
||
434 |
The @{const stream.v5.congclp} predicate is equipped with the following |
|
435 |
introduction rules: |
|
62745 | 436 |
|
437 |
\begin{indentblock} |
|
438 |
\begin{description} |
|
439 |
||
440 |
\item[@{thm [source] sskew.cong_base}\rm:] ~ \\ |
|
441 |
@{thm sskew.cong_base[no_vars]} |
|
442 |
||
443 |
\item[@{thm [source] sskew.cong_refl}\rm:] ~ \\ |
|
444 |
@{thm sskew.cong_refl[no_vars]} |
|
445 |
||
446 |
\item[@{thm [source] sskew.cong_sym}\rm:] ~ \\ |
|
447 |
@{thm sskew.cong_sym[no_vars]} |
|
448 |
||
449 |
\item[@{thm [source] sskew.cong_trans}\rm:] ~ \\ |
|
450 |
@{thm sskew.cong_trans[no_vars]} |
|
451 |
||
452 |
\item[@{thm [source] sskew.cong_SCons}\rm:] ~ \\ |
|
453 |
@{thm sskew.cong_SCons[no_vars]} |
|
454 |
||
455 |
\item[@{thm [source] sskew.cong_ssum}\rm:] ~ \\ |
|
456 |
@{thm sskew.cong_ssum[no_vars]} |
|
457 |
||
458 |
\item[@{thm [source] sskew.cong_sprod}\rm:] ~ \\ |
|
459 |
@{thm sskew.cong_sprod[no_vars]} |
|
460 |
||
461 |
\item[@{thm [source] sskew.cong_sskew}\rm:] ~ \\ |
|
462 |
@{thm sskew.cong_sskew[no_vars]} |
|
463 |
||
464 |
\end{description} |
|
465 |
\end{indentblock} |
|
466 |
% |
|
467 |
The introduction rules are also available as |
|
468 |
@{thm [source] sskew.cong_intros}. |
|
469 |
||
470 |
Notice that there is no introduction rule corresponding to @{const sexp}, |
|
471 |
because @{const sexp} has a more restrictive result type than @{const sskew} |
|
472 |
(@{typ "nat stream"} vs. @{typ "('a :: {plus,times}) stream"}. |
|
473 |
||
62756 | 474 |
The version numbers, here @{text v5}, distinguish the different congruence |
475 |
closures generated for a given codatatype as more friends are registered. As |
|
476 |
much as possible, it is recommended to avoid referring to them in proof |
|
477 |
documents. |
|
478 |
||
62745 | 479 |
Since the package maintains a set of incomparable corecursors, there is also a |
480 |
set of associated coinduction principles and a set of sets of introduction |
|
481 |
rules. A technically subtle point is to make Isabelle choose the right rules in |
|
482 |
most situations. For this purpose, the package maintains the collection |
|
483 |
@{thm [source] stream.coinduct_upto} of coinduction principles ordered by |
|
484 |
increasing generality, which works well with Isabelle's philosophy of applying |
|
485 |
the first rule that matches. For example, after registering @{const ssum} as a |
|
486 |
friend, proving the equality @{term "l = r"} on @{typ "nat stream"} might |
|
487 |
require coinduction principle for @{term "nat stream"}, which is up to |
|
488 |
@{const ssum}. |
|
489 |
||
490 |
The collection @{thm [source] stream.coinduct_upto} is guaranteed to be complete |
|
491 |
and up to date with respect to the type instances of definitions considered so |
|
492 |
far, but occasionally it may be necessary to take the union of two incomparable |
|
493 |
coinduction principles. This can be done using the @{command coinduction_upto} |
|
494 |
command. Consider the following definitions: |
|
62742 | 495 |
\<close> |
496 |
||
62747 | 497 |
codatatype ('a, 'b) tllist = |
498 |
TNil (terminal: 'b) |
|
499 |
| TCons (thd: 'a) (ttl: "('a, 'b) tllist") |
|
62745 | 500 |
|
62756 | 501 |
text \<open>\blankline\<close> |
502 |
||
62745 | 503 |
corec (friend) square_elems :: "(nat, 'b) tllist \<Rightarrow> (nat, 'b) tllist" where |
504 |
"square_elems xs = |
|
505 |
(case xs of |
|
506 |
TNil z \<Rightarrow> TNil z |
|
507 |
| TCons y ys \<Rightarrow> TCons (y ^^ 2) (square_elems ys))" |
|
508 |
||
62756 | 509 |
text \<open>\blankline\<close> |
510 |
||
62745 | 511 |
corec (friend) square_terminal :: "('a, int) tllist \<Rightarrow> ('a, int) tllist" where |
512 |
"square_terminal xs = |
|
513 |
(case xs of |
|
514 |
TNil z \<Rightarrow> TNil (z ^^ 2) |
|
515 |
| TCons y ys \<Rightarrow> TCons y (square_terminal ys))" |
|
62742 | 516 |
|
62745 | 517 |
text \<open> |
518 |
At this point, @{thm [source] tllist.coinduct_upto} contains three variants of the |
|
519 |
coinduction principles: |
|
520 |
% |
|
521 |
\begin{itemize} |
|
522 |
\item @{typ "('a, int) tllist"} up to @{const TNil}, @{const TCons}, and |
|
523 |
@{const square_terminal}; |
|
524 |
\item @{typ "(nat, 'b) tllist"} up to @{const TNil}, @{const TCons}, and |
|
525 |
@{const square_elems}; |
|
526 |
\item @{typ "('a, 'b) tllist"} up to @{const TNil} and @{const TCons}. |
|
527 |
\end{itemize} |
|
528 |
% |
|
529 |
The following variant is missing: |
|
530 |
% |
|
531 |
\begin{itemize} |
|
532 |
\item @{typ "(nat, int) tllist"} up to @{const TNil}, @{const TCons}, |
|
533 |
@{const square_elems}, and @{const square_terminal}. |
|
534 |
\end{itemize} |
|
535 |
% |
|
62756 | 536 |
To generate it without having to define a new function with @{command corec}, |
62745 | 537 |
we can use the following command: |
538 |
\<close> |
|
62742 | 539 |
|
62745 | 540 |
coinduction_upto nat_int_tllist: "(nat, int) tllist" |
541 |
||
542 |
text \<open> |
|
62747 | 543 |
\noindent |
62756 | 544 |
This produces the theorems |
545 |
% |
|
546 |
\begin{indentblock} |
|
547 |
@{thm [source] nat_int_tllist.coinduct_upto} \\ |
|
548 |
@{thm [source] nat_int_tllist.cong_intros} |
|
549 |
\end{indentblock} |
|
550 |
% |
|
551 |
(as well as the individually named introduction rules) and extends |
|
552 |
the dynamic collections @{thm [source] tllist.coinduct_upto} and |
|
62747 | 553 |
@{thm [source] tllist.cong_intros}. |
62745 | 554 |
\<close> |
62742 | 555 |
|
62739 | 556 |
|
557 |
subsection \<open>Uniqueness Reasoning |
|
558 |
\label{ssec:uniqueness-reasoning}\<close> |
|
559 |
||
62742 | 560 |
text \<open> |
62747 | 561 |
It is sometimes possible to achieve better automation by using a more |
562 |
specialized proof method than coinduction. Uniqueness principles maintain a good |
|
563 |
balance between expressiveness and automation. They exploit the property that a |
|
62756 | 564 |
corecursive definition is the unique solution to a fixpoint equation. |
62747 | 565 |
|
566 |
The @{command corec}, @{command corecursive}, and @{command friend_of_corec} |
|
567 |
commands generate a property @{text f.unique} about the function of interest |
|
568 |
@{term f} that can be used to prove that any function that satisfies |
|
62756 | 569 |
@{term f}'s corecursive specification must be equal to~@{term f}. For example: |
62747 | 570 |
\[@{thm ssum.unique[no_vars]}\] |
571 |
||
572 |
The uniqueness principles are not restricted to functions defined using |
|
573 |
@{command corec} or @{command corecursive} or registered with |
|
574 |
@{command friend_of_corec}. Suppose @{term "t x"} is an arbitrary term |
|
575 |
depending on @{term x}. The @{method corec_unique} proof method, provided by our |
|
576 |
tool, transforms subgoals of the form |
|
577 |
\[@{term "(\<forall>x. f x = H x f) \<Longrightarrow> f x = t x"}\] |
|
578 |
into |
|
579 |
\[@{term "\<forall>x. t x = H x t"}\] |
|
62756 | 580 |
The higher-order functional @{term H} must be such that @{term "f x = H x f"} |
581 |
would be a valid @{command corec} specification, but without nested self-calls |
|
582 |
or unguarded (recursive) calls. Thus, @{method corec_unique} proves uniqueness |
|
583 |
of @{term t} with respect to the given corecursive equation regardless of how |
|
584 |
@{term t} was defined. For example: |
|
62742 | 585 |
\<close> |
586 |
||
62747 | 587 |
lemma |
588 |
fixes f :: "nat stream \<Rightarrow> nat stream \<Rightarrow> nat stream" |
|
589 |
assumes "\<forall>xs ys. f xs ys = |
|
590 |
SCons (shd ys * shd xs) (ssum (f xs (stl ys)) (f (stl xs) ys))" |
|
591 |
shows "f = sprod" |
|
592 |
using assms |
|
593 |
proof corec_unique |
|
594 |
show "sprod = (\<lambda>xs ys :: nat stream. |
|
595 |
SCons (shd ys * shd xs) (ssum (sprod xs (stl ys)) (sprod (stl xs) ys)))" |
|
596 |
apply (rule ext)+ |
|
597 |
apply (subst sprod.code) |
|
598 |
by simp |
|
599 |
qed |
|
600 |
||
62756 | 601 |
text \<open> |
602 |
The proof method relies on some theorems generated by the package. If no function |
|
603 |
over a given codatatype has been defined using @{command corec} or |
|
604 |
@{command corecursive} or registered as friendly using @{command friend_of_corec}, |
|
605 |
the theorems will not be available yet. In such cases, the theorems can be |
|
606 |
explicitly generated using the command |
|
607 |
\<close> |
|
608 |
||
609 |
coinduction_upto stream: "'a stream" |
|
610 |
||
62739 | 611 |
|
612 |
section \<open>Command Syntax |
|
613 |
\label{sec:command-syntax}\<close> |
|
614 |
||
62742 | 615 |
subsection \<open>\keyw{corec} and \keyw{corecursive} |
62756 | 616 |
\label{ssec:corec-and-corecursive-syntax}\<close> |
62739 | 617 |
|
62742 | 618 |
text \<open> |
62747 | 619 |
\begin{matharray}{rcl} |
620 |
@{command_def "corec"} & : & @{text "local_theory \<rightarrow> local_theory"} \\ |
|
621 |
@{command_def "corecursive"} & : & @{text "local_theory \<rightarrow> proof(prove)"} |
|
622 |
\end{matharray} |
|
623 |
||
624 |
@{rail \<open> |
|
625 |
(@@{command corec} | @@{command corecursive}) target? \<newline> |
|
626 |
@{syntax cr_options}? fix @'where' prop |
|
627 |
; |
|
628 |
@{syntax_def cr_options}: '(' ((@{syntax plugins} | 'friend' | 'transfer') + ',') ')' |
|
629 |
\<close>} |
|
630 |
||
631 |
\medskip |
|
632 |
||
633 |
\noindent |
|
634 |
The @{command corec} and @{command corecursive} commands introduce a corecursive |
|
635 |
function over a codatatype. |
|
636 |
||
637 |
The syntactic entity \synt{target} can be used to specify a local context, |
|
638 |
\synt{fix} denotes name with an optional type signature, and \synt{prop} denotes |
|
639 |
a HOL proposition @{cite "isabelle-isar-ref"}. |
|
640 |
||
641 |
The optional target is optionally followed by a combination of the following |
|
642 |
options: |
|
643 |
||
644 |
\begin{itemize} |
|
645 |
\setlength{\itemsep}{0pt} |
|
646 |
||
647 |
\item |
|
648 |
The @{text plugins} option indicates which plugins should be enabled |
|
649 |
(@{text only}) or disabled (@{text del}). By default, all plugins are enabled. |
|
650 |
||
651 |
\item |
|
652 |
The @{text friend} option indicates that the defined function should be |
|
653 |
registered as a friend. This gives rise to additional proof obligations. |
|
654 |
||
655 |
\item |
|
656 |
The @{text transfer} option indicates that an unconditional transfer rule |
|
657 |
should be generated and proved @{text "by transfer_prover"}. The |
|
658 |
@{text "[transfer_rule]"} attribute is set on the generated theorem. |
|
659 |
\end{itemize} |
|
660 |
||
62756 | 661 |
The @{command corec} command is an abbreviation for @{command corecursive} |
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
662 |
with appropriate applications of @{method transfer_prover_eq} and |
62756 | 663 |
@{method lexicographic_order} to discharge any emerging proof obligations. |
62742 | 664 |
\<close> |
665 |
||
62739 | 666 |
|
62742 | 667 |
subsection \<open>\keyw{friend_of_corec} |
62756 | 668 |
\label{ssec:friend-of-corec-syntax}\<close> |
62739 | 669 |
|
62742 | 670 |
text \<open> |
62747 | 671 |
\begin{matharray}{rcl} |
672 |
@{command_def "friend_of_corec"} & : & @{text "local_theory \<rightarrow> proof(prove)"} |
|
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
673 |
\\ |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
674 |
@{attribute_def "friend_of_corec_simps"} & : & @{text "attribute"} |
62747 | 675 |
\end{matharray} |
676 |
||
677 |
@{rail \<open> |
|
678 |
@@{command friend_of_corec} target? \<newline> |
|
679 |
@{syntax foc_options}? fix @'where' prop |
|
680 |
; |
|
681 |
@{syntax_def foc_options}: '(' ((@{syntax plugins} | 'transfer') + ',') ')' |
|
682 |
\<close>} |
|
683 |
||
684 |
\medskip |
|
685 |
||
686 |
\noindent |
|
687 |
The @{command friend_of_corec} command registers a corecursive function as |
|
688 |
friendly. |
|
689 |
||
690 |
The syntactic entity \synt{target} can be used to specify a local context, |
|
691 |
\synt{fix} denotes name with an optional type signature, and \synt{prop} denotes |
|
692 |
a HOL proposition @{cite "isabelle-isar-ref"}. |
|
693 |
||
694 |
The optional target is optionally followed by a combination of the following |
|
695 |
options: |
|
696 |
||
697 |
\begin{itemize} |
|
698 |
\setlength{\itemsep}{0pt} |
|
699 |
||
700 |
\item |
|
701 |
The @{text plugins} option indicates which plugins should be enabled |
|
702 |
(@{text only}) or disabled (@{text del}). By default, all plugins are enabled. |
|
703 |
||
704 |
\item |
|
705 |
The @{text transfer} option indicates that an unconditional transfer rule |
|
706 |
should be generated and proved @{text "by transfer_prover"}. The |
|
707 |
@{text "[transfer_rule]"} attribute is set on the generated theorem. |
|
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
708 |
|
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
709 |
\item |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
710 |
The attribute @{attribute friend_of_corec_simps} declares naturality theorems |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
711 |
to be used by @{command friend_of_corec} and @{text "corec (friend)"} in deriving |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
712 |
the user specification from reduction to primitive corecursion. |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
713 |
Internally, they derive naturality theorems from the parametricity proof obligations |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
714 |
dischared by the user or the method @{method transfer_prover_eq}, but this derivation |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
715 |
fails if in the arguments of a higher-order constant a type variable occurs on both |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
716 |
sides of the function type constructor. In that case, the required naturality |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
717 |
theorem can be declared with @{attribute friend_of_corec_simps}. See |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
718 |
@{file "~~/src/HOL/Corec_Examples/Tests/Iterate_GPV.thy"} for an example. |
62747 | 719 |
\end{itemize} |
62742 | 720 |
\<close> |
62739 | 721 |
|
62742 | 722 |
subsection \<open>\keyw{coinduction_upto} |
62756 | 723 |
\label{ssec:coinduction-upto-syntax}\<close> |
62739 | 724 |
|
62742 | 725 |
text \<open> |
62747 | 726 |
\begin{matharray}{rcl} |
727 |
@{command_def "coinduction_upto"} & : & @{text "local_theory \<rightarrow> local_theory"} |
|
728 |
\end{matharray} |
|
729 |
||
730 |
@{rail \<open> |
|
731 |
@@{command coinduction_upto} target? name ':' type |
|
732 |
\<close>} |
|
733 |
||
734 |
\medskip |
|
735 |
||
736 |
\noindent |
|
737 |
The @{command coinduction_upto} generates a coinduction up-to rule for a given |
|
738 |
instance of a (possibly polymorphic) codatatype and notes the result with the |
|
739 |
specified prefix. |
|
740 |
||
741 |
The syntactic entity \synt{name} denotes an identifier and \synt{type} denotes a |
|
742 |
type @{cite "isabelle-isar-ref"}. |
|
62742 | 743 |
\<close> |
744 |
||
62739 | 745 |
|
746 |
section \<open>Generated Theorems |
|
747 |
\label{sec:generated-theorems}\<close> |
|
748 |
||
62742 | 749 |
text \<open> |
62756 | 750 |
The full list of named theorems generated by the package can be obtained by |
751 |
issuing the command \keyw{print_theorems} immediately after the datatype definition. |
|
752 |
This list excludes low-level theorems that reveal internal constructions. To |
|
753 |
make these accessible, add the line |
|
754 |
\<close> |
|
755 |
||
756 |
declare [[bnf_internals]] |
|
757 |
(*<*) |
|
758 |
declare [[bnf_internals = false]] |
|
759 |
(*>*) |
|
760 |
||
761 |
text \<open> |
|
762 |
In addition to the theorem listed below for each command provided by the |
|
763 |
package, all commands update the dynamic theorem collections |
|
764 |
||
765 |
\begin{indentblock} |
|
766 |
\begin{description} |
|
767 |
||
768 |
\item[@{text "t."}\hthm{coinduct_upto}] |
|
769 |
||
770 |
\item[@{text "t."}\hthm{cong_intros}] |
|
771 |
||
772 |
\end{description} |
|
773 |
\end{indentblock} |
|
774 |
% |
|
775 |
for the corresponding codatatype @{text t} so that they always contain the most |
|
776 |
powerful coinduction up-to principles derived so far. |
|
62742 | 777 |
\<close> |
62739 | 778 |
|
62742 | 779 |
|
780 |
subsection \<open>\keyw{corec} and \keyw{corecursive} |
|
62756 | 781 |
\label{ssec:corec-and-corecursive-theorems}\<close> |
62739 | 782 |
|
62742 | 783 |
text \<open> |
62756 | 784 |
For a function @{term f} over codatatype @{text t}, the @{command corec} and |
785 |
@{command corecursive} commands generate the following properties (listed for |
|
786 |
@{const sexp}, cf. Section~\ref{ssec:simple-corecursion}): |
|
787 |
||
788 |
\begin{indentblock} |
|
789 |
\begin{description} |
|
790 |
||
791 |
\item[@{text "f."}\hthm{code} @{text "[code]"}\rm:] ~ \\ |
|
792 |
@{thm sexp.code[no_vars]} \\ |
|
793 |
The @{text "[code]"} attribute is set by the @{text code} plugin |
|
794 |
@{cite "isabelle-datatypes"}. |
|
795 |
||
796 |
\item[@{text "f."}\hthm{coinduct} @{text "[consumes 1, case_names t, case_conclusion D\<^sub>1 \<dots> |
|
797 |
D\<^sub>n]"}\rm:] ~ \\ |
|
798 |
@{thm sexp.coinduct[no_vars]} |
|
799 |
||
800 |
\item[@{text "f."}\hthm{cong_intros}\rm:] ~ \\ |
|
801 |
@{thm sexp.cong_intros[no_vars]} |
|
802 |
||
803 |
\item[@{text "f."}\hthm{unique}\rm:] ~ \\ |
|
804 |
@{thm sexp.unique[no_vars]} \\ |
|
805 |
This property is not generated for mixed recursive--corecursive definitions. |
|
806 |
||
807 |
\item[@{text "f."}\hthm{inner_induct}\rm:] ~ \\ |
|
808 |
This property is only generated for mixed recursive--corecursive definitions. |
|
809 |
For @{const primes} (Section~\ref{ssec:mixed-recursion-corecursion}, it reads as |
|
810 |
follows: \\[\jot] |
|
811 |
@{thm primes.inner_induct[no_vars]} |
|
812 |
||
813 |
\end{description} |
|
814 |
\end{indentblock} |
|
815 |
||
816 |
\noindent |
|
817 |
The individual rules making up @{text "f.cong_intros"} are available as |
|
818 |
||
819 |
\begin{indentblock} |
|
820 |
\begin{description} |
|
821 |
||
822 |
\item[@{text "f."}\hthm{cong_base}] |
|
823 |
||
824 |
\item[@{text "f."}\hthm{cong_refl}] |
|
825 |
||
826 |
\item[@{text "f."}\hthm{cong_sym}] |
|
827 |
||
828 |
\item[@{text "f."}\hthm{cong_trans}] |
|
829 |
||
62816 | 830 |
\item[@{text "f."}\hthm{cong_C}@{text "\<^sub>1"}, \ldots, @{text "f."}\hthm{cong_C}@{text "\<^sub>n"}] ~ \\ |
62756 | 831 |
where @{text "C\<^sub>1"}, @{text "\<dots>"}, @{text "C\<^sub>n"} are @{text t}'s |
832 |
constructors |
|
833 |
||
62816 | 834 |
\item[@{text "f."}\hthm{cong_f}@{text "\<^sub>1"}, \ldots, @{text "f."}\hthm{cong_f}@{text "\<^sub>m"}] ~ \\ |
62756 | 835 |
where @{text "f\<^sub>1"}, @{text "\<dots>"}, @{text "f\<^sub>m"} are the available |
836 |
friends for @{text t} |
|
837 |
||
838 |
\end{description} |
|
839 |
\end{indentblock} |
|
62742 | 840 |
\<close> |
841 |
||
62739 | 842 |
|
62742 | 843 |
subsection \<open>\keyw{friend_of_corec} |
62756 | 844 |
\label{ssec:friend-of-corec-theorems}\<close> |
62739 | 845 |
|
62742 | 846 |
text \<open> |
62756 | 847 |
The @{command friend_of_corec} command generates the same theorems as |
848 |
@{command corec} and @{command corecursive}, except that it adds an optional |
|
849 |
@{text "friend."} component to the names to prevent potential clashes (e.g., |
|
850 |
@{text "f.friend.code"}). |
|
62742 | 851 |
\<close> |
62739 | 852 |
|
62742 | 853 |
|
854 |
subsection \<open>\keyw{coinduction_upto} |
|
62756 | 855 |
\label{ssec:coinduction-upto-theorems}\<close> |
62739 | 856 |
|
62742 | 857 |
text \<open> |
62756 | 858 |
The @{command coinduction_upto} command generates the following properties |
859 |
(listed for @{text nat_int_tllist}): |
|
860 |
||
861 |
\begin{indentblock} |
|
862 |
\begin{description} |
|
863 |
||
864 |
\item[\begin{tabular}{@ {}l@ {}} |
|
865 |
@{text "t."}\hthm{coinduct_upto} @{text "[consumes 1, case_names t,"} \\ |
|
866 |
\phantom{@{text "t."}\hthm{coinduct_upto} @{text "["}}@{text "case_conclusion D\<^sub>1 \<dots> |
|
867 |
D\<^sub>n]"}\rm: |
|
868 |
\end{tabular}] ~ \\ |
|
869 |
@{thm nat_int_tllist.coinduct_upto[no_vars]} |
|
870 |
||
871 |
\item[@{text "t."}\hthm{cong_intros}\rm:] ~ \\ |
|
872 |
@{thm nat_int_tllist.cong_intros[no_vars]} |
|
873 |
||
874 |
\end{description} |
|
875 |
\end{indentblock} |
|
876 |
||
877 |
\noindent |
|
878 |
The individual rules making up @{text "t.cong_intros"} are available |
|
879 |
separately as @{text "t.cong_base"}, @{text "t.cong_refl"}, etc.\ |
|
880 |
(Section~\ref{ssec:corec-and-corecursive-theorems}). |
|
62742 | 881 |
\<close> |
882 |
||
62739 | 883 |
|
884 |
section \<open>Proof Method |
|
885 |
\label{sec:proof-method}\<close> |
|
886 |
||
62742 | 887 |
subsection \<open>\textit{corec_unique} |
62739 | 888 |
\label{ssec:corec-unique}\<close> |
889 |
||
62742 | 890 |
text \<open> |
62756 | 891 |
The @{method corec_unique} proof method can be used to prove the uniqueness of |
892 |
a corecursive specification. See Section~\ref{ssec:uniqueness-reasoning} for |
|
893 |
details. |
|
62742 | 894 |
\<close> |
895 |
||
64380
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
896 |
subsection \<open>\textit{transfer_prover_eq} |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
897 |
\label{ssec:transfer-prover-eq}\<close> |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
898 |
|
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
899 |
text \<open> |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
900 |
The proof method @{method transfer_prover_eq} replaces the equality relation |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
901 |
@{term "op ="} with compound relator expressions according to |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
902 |
@{thm [source] relator_eq} before calling @{method transfer_prover} on the |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
903 |
current subgoal. It works better than plain @{method transfer_prover} on |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
904 |
the parametricity proof obligations of @{command corecursive} and |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
905 |
@{command friend_of_corec}, as they often contain equality relations on complex |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
906 |
types, which @{method transfer_prover} does not like. |
4b22e1268779
document transfer_prover_eq and friend_of_corec_simps
Andreas Lochbihler
parents:
63680
diff
changeset
|
907 |
\<close> |
62739 | 908 |
|
909 |
section \<open>Known Bugs and Limitations |
|
910 |
\label{sec:known-bugs-and-limitations}\<close> |
|
911 |
||
912 |
text \<open> |
|
913 |
This section lists the known bugs and limitations of the corecursion package at |
|
914 |
the time of this writing. |
|
915 |
||
916 |
\begin{enumerate} |
|
917 |
\setlength{\itemsep}{0pt} |
|
918 |
||
919 |
\item |
|
62756 | 920 |
\emph{Mutually corecursive codatatypes are not supported.} |
921 |
||
922 |
\item |
|
923 |
\emph{The signature of friend functions may not depend on type variables beyond |
|
924 |
those that appear in the codatatype.} |
|
925 |
||
926 |
\item |
|
927 |
\emph{The internal tactics may fail on legal inputs.} |
|
62739 | 928 |
|
62756 | 929 |
\item |
930 |
\emph{The @{text transfer} option is not implemented yet.} |
|
931 |
||
932 |
\item |
|
933 |
\emph{The constructor and destructor views offered by {\upshape\keyw{primcorec}} |
|
934 |
are not supported by @{command corec} and @{command corecursive}.} |
|
935 |
||
936 |
\item |
|
937 |
\emph{There is no mechanism for registering custom plugins.} |
|
938 |
||
939 |
\item |
|
940 |
\emph{The package does not interact well with locales.} |
|
62739 | 941 |
|
64383 | 942 |
\item |
943 |
\emph{The undocumented @{text corecUU_transfer} theorem is not as polymorphic as |
|
944 |
it could be.} |
|
945 |
||
946 |
\item |
|
947 |
\emph{All type variables occurring in the arguments of a friendly function must occur |
|
948 |
as direct arguments of the type constructor of the resulting type.} |
|
949 |
||
62739 | 950 |
\end{enumerate} |
951 |
\<close> |
|
952 |
||
953 |
end |