1 \documentstyle[12pt,a4,proof,iman,alltt]{article} |
1 \documentstyle[a4,proof,iman,extra,times]{llncs} |
2 \hyphenation{data-type} |
2 %Repetition in the two sentences that begin ``The powerset operator'' |
3 %CADE version should use 11pt and the Springer style |
|
4 \newif\ifCADE |
3 \newif\ifCADE |
5 \CADEfalse |
4 \CADEtrue |
6 |
5 |
7 \title{A Fixedpoint Approach to Implementing (Co)Inductive |
6 \title{A Fixedpoint Approach to Implementing\\ |
8 Definitions\thanks{Jim Grundy and Simon Thompson made detailed comments on |
7 (Co)Inductive Definitions\thanks{J. Grundy and S. Thompson made detailed |
9 a draft. Research funded by the SERC (grants GR/G53279, |
8 comments; the referees were also helpful. Research funded by |
10 GR/H40570) and by the ESPRIT Basic Research Action 6453 `Types'.}} |
9 SERC grants GR/G53279, GR/H40570 and by the ESPRIT Project 6453 |
11 |
10 `Types'.}} |
12 \author{{\em Lawrence C. Paulson}\\ |
11 |
13 Computer Laboratory, University of Cambridge} |
12 \author{Lawrence C. Paulson\\{\tt lcp@cl.cam.ac.uk}} |
|
13 \institute{Computer Laboratory, University of Cambridge, England} |
14 \date{\today} |
14 \date{\today} |
15 \setcounter{secnumdepth}{2} \setcounter{tocdepth}{2} |
15 \setcounter{secnumdepth}{2} \setcounter{tocdepth}{2} |
16 |
16 |
17 \def\picture #1 by #2 (#3){% pictures: width by height (name) |
|
18 \message{Picture #3} |
|
19 \vbox to #2{\hrule width #1 height 0pt depth 0pt |
|
20 \vfill \special{picture #3}}} |
|
21 |
|
22 |
|
23 \newcommand\sbs{\subseteq} |
17 \newcommand\sbs{\subseteq} |
24 \let\To=\Rightarrow |
18 \let\To=\Rightarrow |
25 |
19 |
26 |
20 |
27 %%%\newcommand\Pow{{\tt Pow}} |
21 \newcommand\pow{{\cal P}} |
28 \let\pow=\wp |
22 %%%\let\pow=\wp |
29 \newcommand\RepFun{{\tt RepFun}} |
23 \newcommand\RepFun{\hbox{\tt RepFun}} |
30 \newcommand\cons{{\tt cons}} |
24 \newcommand\cons{\hbox{\tt cons}} |
31 \def\succ{{\tt succ}} |
25 \def\succ{\hbox{\tt succ}} |
32 \newcommand\split{{\tt split}} |
26 \newcommand\split{\hbox{\tt split}} |
33 \newcommand\fst{{\tt fst}} |
27 \newcommand\fst{\hbox{\tt fst}} |
34 \newcommand\snd{{\tt snd}} |
28 \newcommand\snd{\hbox{\tt snd}} |
35 \newcommand\converse{{\tt converse}} |
29 \newcommand\converse{\hbox{\tt converse}} |
36 \newcommand\domain{{\tt domain}} |
30 \newcommand\domain{\hbox{\tt domain}} |
37 \newcommand\range{{\tt range}} |
31 \newcommand\range{\hbox{\tt range}} |
38 \newcommand\field{{\tt field}} |
32 \newcommand\field{\hbox{\tt field}} |
39 \newcommand\bndmono{\hbox{\tt bnd\_mono}} |
33 \newcommand\lfp{\hbox{\tt lfp}} |
40 \newcommand\lfp{{\tt lfp}} |
34 \newcommand\gfp{\hbox{\tt gfp}} |
41 \newcommand\gfp{{\tt gfp}} |
35 \newcommand\id{\hbox{\tt id}} |
42 \newcommand\id{{\tt id}} |
36 \newcommand\trans{\hbox{\tt trans}} |
43 \newcommand\trans{{\tt trans}} |
37 \newcommand\wf{\hbox{\tt wf}} |
44 \newcommand\wf{{\tt wf}} |
38 \newcommand\nat{\hbox{\tt nat}} |
45 \newcommand\wfrec{\hbox{\tt wfrec}} |
39 \newcommand\rank{\hbox{\tt rank}} |
46 \newcommand\nat{{\tt nat}} |
40 \newcommand\univ{\hbox{\tt univ}} |
47 \newcommand\natcase{\hbox{\tt nat\_case}} |
41 \newcommand\Vrec{\hbox{\tt Vrec}} |
48 \newcommand\transrec{{\tt transrec}} |
42 \newcommand\Inl{\hbox{\tt Inl}} |
49 \newcommand\rank{{\tt rank}} |
43 \newcommand\Inr{\hbox{\tt Inr}} |
50 \newcommand\univ{{\tt univ}} |
44 \newcommand\case{\hbox{\tt case}} |
51 \newcommand\Vrec{{\tt Vrec}} |
45 \newcommand\lst{\hbox{\tt list}} |
52 \newcommand\Inl{{\tt Inl}} |
46 \newcommand\Nil{\hbox{\tt Nil}} |
53 \newcommand\Inr{{\tt Inr}} |
47 \newcommand\Cons{\hbox{\tt Cons}} |
54 \newcommand\case{{\tt case}} |
|
55 \newcommand\lst{{\tt list}} |
|
56 \newcommand\Nil{{\tt Nil}} |
|
57 \newcommand\Cons{{\tt Cons}} |
|
58 \newcommand\lstcase{\hbox{\tt list\_case}} |
48 \newcommand\lstcase{\hbox{\tt list\_case}} |
59 \newcommand\lstrec{\hbox{\tt list\_rec}} |
49 \newcommand\lstrec{\hbox{\tt list\_rec}} |
60 \newcommand\length{{\tt length}} |
50 \newcommand\length{\hbox{\tt length}} |
61 \newcommand\listn{{\tt listn}} |
51 \newcommand\listn{\hbox{\tt listn}} |
62 \newcommand\acc{{\tt acc}} |
52 \newcommand\acc{\hbox{\tt acc}} |
63 \newcommand\primrec{{\tt primrec}} |
53 \newcommand\primrec{\hbox{\tt primrec}} |
64 \newcommand\SC{{\tt SC}} |
54 \newcommand\SC{\hbox{\tt SC}} |
65 \newcommand\CONST{{\tt CONST}} |
55 \newcommand\CONST{\hbox{\tt CONST}} |
66 \newcommand\PROJ{{\tt PROJ}} |
56 \newcommand\PROJ{\hbox{\tt PROJ}} |
67 \newcommand\COMP{{\tt COMP}} |
57 \newcommand\COMP{\hbox{\tt COMP}} |
68 \newcommand\PREC{{\tt PREC}} |
58 \newcommand\PREC{\hbox{\tt PREC}} |
69 |
59 |
70 \newcommand\quniv{{\tt quniv}} |
60 \newcommand\quniv{\hbox{\tt quniv}} |
71 \newcommand\llist{{\tt llist}} |
61 \newcommand\llist{\hbox{\tt llist}} |
72 \newcommand\LNil{{\tt LNil}} |
62 \newcommand\LNil{\hbox{\tt LNil}} |
73 \newcommand\LCons{{\tt LCons}} |
63 \newcommand\LCons{\hbox{\tt LCons}} |
74 \newcommand\lconst{{\tt lconst}} |
64 \newcommand\lconst{\hbox{\tt lconst}} |
75 \newcommand\lleq{{\tt lleq}} |
65 \newcommand\lleq{\hbox{\tt lleq}} |
76 \newcommand\map{{\tt map}} |
66 \newcommand\map{\hbox{\tt map}} |
77 \newcommand\term{{\tt term}} |
67 \newcommand\term{\hbox{\tt term}} |
78 \newcommand\Apply{{\tt Apply}} |
68 \newcommand\Apply{\hbox{\tt Apply}} |
79 \newcommand\termcase{{\tt term\_case}} |
69 \newcommand\termcase{\hbox{\tt term\_case}} |
80 \newcommand\rev{{\tt rev}} |
70 \newcommand\rev{\hbox{\tt rev}} |
81 \newcommand\reflect{{\tt reflect}} |
71 \newcommand\reflect{\hbox{\tt reflect}} |
82 \newcommand\tree{{\tt tree}} |
72 \newcommand\tree{\hbox{\tt tree}} |
83 \newcommand\forest{{\tt forest}} |
73 \newcommand\forest{\hbox{\tt forest}} |
84 \newcommand\Part{{\tt Part}} |
74 \newcommand\Part{\hbox{\tt Part}} |
85 \newcommand\TF{{\tt tree\_forest}} |
75 \newcommand\TF{\hbox{\tt tree\_forest}} |
86 \newcommand\Tcons{{\tt Tcons}} |
76 \newcommand\Tcons{\hbox{\tt Tcons}} |
87 \newcommand\Fcons{{\tt Fcons}} |
77 \newcommand\Fcons{\hbox{\tt Fcons}} |
88 \newcommand\Fnil{{\tt Fnil}} |
78 \newcommand\Fnil{\hbox{\tt Fnil}} |
89 \newcommand\TFcase{\hbox{\tt TF\_case}} |
79 \newcommand\TFcase{\hbox{\tt TF\_case}} |
90 \newcommand\Fin{{\tt Fin}} |
80 \newcommand\Fin{\hbox{\tt Fin}} |
91 \newcommand\QInl{{\tt QInl}} |
81 \newcommand\QInl{\hbox{\tt QInl}} |
92 \newcommand\QInr{{\tt QInr}} |
82 \newcommand\QInr{\hbox{\tt QInr}} |
93 \newcommand\qsplit{{\tt qsplit}} |
83 \newcommand\qsplit{\hbox{\tt qsplit}} |
94 \newcommand\qcase{{\tt qcase}} |
84 \newcommand\qcase{\hbox{\tt qcase}} |
95 \newcommand\Con{{\tt Con}} |
85 \newcommand\Con{\hbox{\tt Con}} |
96 \newcommand\data{{\tt data}} |
86 \newcommand\data{\hbox{\tt data}} |
97 |
87 |
98 \binperiod %%%treat . like a binary operator |
88 \binperiod %%%treat . like a binary operator |
99 |
89 |
100 \begin{document} |
90 \begin{document} |
101 \pagestyle{empty} |
91 %CADE%\pagestyle{empty} |
102 \begin{titlepage} |
92 %CADE%\begin{titlepage} |
103 \maketitle |
93 \maketitle |
104 \begin{abstract} |
94 \begin{abstract} |
105 Several theorem provers provide commands for formalizing recursive |
95 This paper presents a fixedpoint approach to inductive definitions. |
106 data\-types or inductively defined sets. This paper presents a new |
96 Instead of using a syntactic test such as `strictly positive,' the |
107 approach, based on fixedpoint definitions. It is unusually general: it |
97 approach lets definitions involve any operators that have been proved |
108 admits all provably monotone inductive definitions. It is conceptually |
98 monotone. It is conceptually simple, which has allowed the easy |
109 simple, which has allowed the easy implementation of mutual recursion and |
99 implementation of mutual recursion and other conveniences. It also |
110 other conveniences. It also handles coinductive definitions: simply |
100 handles coinductive definitions: simply replace the least fixedpoint by a |
111 replace the least fixedpoint by a greatest fixedpoint. This represents |
101 greatest fixedpoint. This represents the first automated support for |
112 the first automated support for coinductive definitions. |
102 coinductive definitions. |
113 |
103 |
114 The method has been implemented in Isabelle's formalization of ZF set |
104 The method has been implemented in Isabelle's formalization of ZF set |
115 theory. It should be applicable to any logic in which the Knaster-Tarski |
105 theory. It should be applicable to any logic in which the Knaster-Tarski |
116 Theorem can be proved. The paper briefly describes a method of |
106 Theorem can be proved. Examples include lists of $n$ elements, the |
117 formalizing non-well-founded data structures in standard ZF set theory. |
107 accessible part of a relation and the set of primitive recursive |
118 |
108 functions. One example of a coinductive definition is bisimulations for |
119 Examples include lists of $n$ elements, the accessible part of a relation |
109 lazy lists. \ifCADE\else Recursive datatypes are examined in detail, as |
120 and the set of primitive recursive functions. One example of a |
110 well as one example of a {\bf codatatype}: lazy lists. The appendices |
121 coinductive definition is bisimulations for lazy lists. \ifCADE\else |
111 are simple user's manuals for this Isabelle/ZF package.\fi |
122 Recursive datatypes are examined in detail, as well as one example of a |
|
123 {\bf codatatype}: lazy lists. The appendices are simple user's manuals |
|
124 for this Isabelle/ZF package.\fi |
|
125 \end{abstract} |
112 \end{abstract} |
126 % |
113 % |
127 \begin{center} Copyright \copyright{} \number\year{} by Lawrence C. Paulson |
114 %CADE%\bigskip\centerline{Copyright \copyright{} \number\year{} by Lawrence C. Paulson} |
128 \end{center} |
115 %CADE%\thispagestyle{empty} |
129 \thispagestyle{empty} |
116 %CADE%\end{titlepage} |
130 \end{titlepage} |
117 %CADE%\tableofcontents\cleardoublepage\pagestyle{headings} |
131 |
|
132 \tableofcontents |
|
133 \cleardoublepage |
|
134 \pagenumbering{arabic}\pagestyle{headings} |
|
135 |
118 |
136 \section{Introduction} |
119 \section{Introduction} |
137 Several theorem provers provide commands for formalizing recursive data |
120 Several theorem provers provide commands for formalizing recursive data |
138 structures, like lists and trees. Examples include Boyer and Moore's shell |
121 structures, like lists and trees. Examples include Boyer and Moore's shell |
139 principle~\cite{bm79} and Melham's recursive type package for the HOL |
122 principle~\cite{bm79} and Melham's recursive type package for the HOL |
153 using bisimulation relations to formalize equivalence of |
136 using bisimulation relations to formalize equivalence of |
154 processes~\cite{milner89} or lazy functional programs~\cite{abramsky90}. |
137 processes~\cite{milner89} or lazy functional programs~\cite{abramsky90}. |
155 Other examples include lazy lists and other infinite data structures; these |
138 Other examples include lazy lists and other infinite data structures; these |
156 are called {\bf codatatypes} below. |
139 are called {\bf codatatypes} below. |
157 |
140 |
158 Most existing implementations of datatype and inductive definitions accept |
141 Not all inductive definitions are meaningful. {\bf Monotone} inductive |
159 an artificially narrow class of inputs, and are not easily extended. The |
142 definitions are a large, well-behaved class. Monotonicity can be enforced |
160 shell principle and Coq's inductive definition rules are built into the |
143 by syntactic conditions such as `strictly positive,' but this could lead to |
161 underlying logic. Melham's packages derive datatypes and inductive |
144 monotone definitions being rejected on the grounds of their syntactic form. |
162 definitions from specialized constructions in higher-order logic. |
145 More flexible is to formalize monotonicity within the logic and allow users |
|
146 to prove it. |
163 |
147 |
164 This paper describes a package based on a fixedpoint approach. Least |
148 This paper describes a package based on a fixedpoint approach. Least |
165 fixedpoints yield inductive definitions; greatest fixedpoints yield |
149 fixedpoints yield inductive definitions; greatest fixedpoints yield |
166 coinductive definitions. The package is uniquely powerful: |
150 coinductive definitions. The package has several advantages: |
167 \begin{itemize} |
151 \begin{itemize} |
168 \item It accepts the largest natural class of inductive definitions, namely |
152 \item It allows reference to any operators that have been proved monotone. |
169 all that are provably monotone. |
153 Thus it accepts all provably monotone inductive definitions, including |
170 \item It accepts a wide class of datatype definitions. |
154 iterated definitions. |
|
155 \item It accepts a wide class of datatype definitions, though at present |
|
156 restricted to finite branching. |
171 \item It handles coinductive and codatatype definitions. Most of |
157 \item It handles coinductive and codatatype definitions. Most of |
172 the discussion below applies equally to inductive and coinductive |
158 the discussion below applies equally to inductive and coinductive |
173 definitions, and most of the code is shared. To my knowledge, this is |
159 definitions, and most of the code is shared. To my knowledge, this is |
174 the only package supporting coinductive definitions. |
160 the only package supporting coinductive definitions. |
175 \item Definitions may be mutually recursive. |
161 \item Definitions may be mutually recursive. |
181 transforms these rules into a mapping over sets, and attempts to prove that |
167 transforms these rules into a mapping over sets, and attempts to prove that |
182 the mapping is monotonic and well-typed. If successful, the package |
168 the mapping is monotonic and well-typed. If successful, the package |
183 makes fixedpoint definitions and proves the introduction, elimination and |
169 makes fixedpoint definitions and proves the introduction, elimination and |
184 (co)induction rules. The package consists of several Standard ML |
170 (co)induction rules. The package consists of several Standard ML |
185 functors~\cite{paulson91}; it accepts its argument and returns its result |
171 functors~\cite{paulson91}; it accepts its argument and returns its result |
186 as ML structures. |
172 as ML structures.\footnote{This use of ML modules is not essential; the |
|
173 package could also be implemented as a function on records.} |
187 |
174 |
188 Most datatype packages equip the new datatype with some means of expressing |
175 Most datatype packages equip the new datatype with some means of expressing |
189 recursive functions. This is the main thing lacking from my package. Its |
176 recursive functions. This is the main omission from my package. Its |
190 fixedpoint operators define recursive sets, not recursive functions. But |
177 fixedpoint operators define only recursive sets. To define recursive |
191 the Isabelle/ZF theory provides well-founded recursion and other logical |
178 functions, the Isabelle/ZF theory provides well-founded recursion and other |
192 tools to simplify this task~\cite{paulson-set-II}. |
179 logical tools~\cite{paulson-set-II}. |
193 |
180 |
194 {\bf Outline.} \S2 briefly introduces the least and greatest fixedpoint |
181 {\bf Outline.} Section~2 introduces the least and greatest fixedpoint |
195 operators. \S3 discusses the form of introduction rules, mutual recursion and |
182 operators. Section~3 discusses the form of introduction rules, mutual |
196 other points common to inductive and coinductive definitions. \S4 discusses |
183 recursion and other points common to inductive and coinductive definitions. |
197 induction and coinduction rules separately. \S5 presents several examples, |
184 Section~4 discusses induction and coinduction rules separately. Section~5 |
198 including a coinductive definition. \S6 describes datatype definitions, while |
185 presents several examples, including a coinductive definition. Section~6 |
199 \S7 draws brief conclusions. \ifCADE\else The appendices are simple user's |
186 describes datatype definitions. Section~7 presents related work. |
200 manuals for this Isabelle/ZF package.\fi |
187 Section~8 draws brief conclusions. \ifCADE\else The appendices are simple |
|
188 user's manuals for this Isabelle/ZF package.\fi |
201 |
189 |
202 Most of the definitions and theorems shown below have been generated by the |
190 Most of the definitions and theorems shown below have been generated by the |
203 package. I have renamed some variables to improve readability. |
191 package. I have renamed some variables to improve readability. |
204 |
192 |
205 \section{Fixedpoint operators} |
193 \section{Fixedpoint operators} |
215 bounded by~$D$ and monotone then both operators yield fixedpoints: |
203 bounded by~$D$ and monotone then both operators yield fixedpoints: |
216 \begin{eqnarray*} |
204 \begin{eqnarray*} |
217 \lfp(D,h) & = & h(\lfp(D,h)) \\ |
205 \lfp(D,h) & = & h(\lfp(D,h)) \\ |
218 \gfp(D,h) & = & h(\gfp(D,h)) |
206 \gfp(D,h) & = & h(\gfp(D,h)) |
219 \end{eqnarray*} |
207 \end{eqnarray*} |
220 These equations are instances of the Knaster-Tarski theorem, which states |
208 These equations are instances of the Knaster-Tarski Theorem, which states |
221 that every monotonic function over a complete lattice has a |
209 that every monotonic function over a complete lattice has a |
222 fixedpoint~\cite{davey&priestley}. It is obvious from their definitions |
210 fixedpoint~\cite{davey&priestley}. It is obvious from their definitions |
223 that $\lfp$ must be the least fixedpoint, and $\gfp$ the greatest. |
211 that $\lfp$ must be the least fixedpoint, and $\gfp$ the greatest. |
224 |
212 |
225 This fixedpoint theory is simple. The Knaster-Tarski theorem is easy to |
213 This fixedpoint theory is simple. The Knaster-Tarski Theorem is easy to |
226 prove. Showing monotonicity of~$h$ is trivial, in typical cases. We must |
214 prove. Showing monotonicity of~$h$ is trivial, in typical cases. We must |
227 also exhibit a bounding set~$D$ for~$h$. Sometimes this is trivial, as |
215 also exhibit a bounding set~$D$ for~$h$. Frequently this is trivial, as |
228 when a set of `theorems' is (co)inductively defined over some previously |
216 when a set of `theorems' is (co)inductively defined over some previously |
229 existing set of `formulae.' But defining the bounding set for |
217 existing set of `formulae.' Isabelle/ZF provides a suitable bounding set |
230 (co)datatype definitions requires some effort; see~\S\ref{univ-sec} below. |
218 for finitely branching (co)datatype definitions; see~\S\ref{univ-sec} |
231 |
219 below. Bounding sets are also called {\bf domains}. |
|
220 |
|
221 The powerset operator is monotone, but by Cantor's Theorem there is no |
|
222 set~$A$ such that $A=\pow(A)$. We cannot put $A=\lfp(D,\pow)$ because |
|
223 there is no suitable domain~$D$. But \S\ref{acc-sec} demonstrates |
|
224 that~$\pow$ is still useful in inductive definitions. |
232 |
225 |
233 \section{Elements of an inductive or coinductive definition}\label{basic-sec} |
226 \section{Elements of an inductive or coinductive definition}\label{basic-sec} |
234 Consider a (co)inductive definition of the sets $R_1$, \ldots,~$R_n$, in |
227 Consider a (co)inductive definition of the sets $R_1$, \ldots,~$R_n$, in |
235 mutual recursion. They will be constructed from previously existing sets |
228 mutual recursion. They will be constructed from domains $D_1$, |
236 $D_1$, \ldots,~$D_n$, respectively, which are called their {\bf domains}. |
229 \ldots,~$D_n$, respectively. The construction yields not $R_i\sbs D_i$ but |
237 The construction yields not $R_i\sbs D_i$ but $R_i\sbs D_1+\cdots+D_n$, where |
230 $R_i\sbs D_1+\cdots+D_n$, where $R_i$ is contained in the image of~$D_i$ |
238 $R_i$ is contained in the image of~$D_i$ under an |
231 under an injection. Reasons for this are discussed |
239 injection. Reasons for this are discussed |
|
240 elsewhere~\cite[\S4.5]{paulson-set-II}. |
232 elsewhere~\cite[\S4.5]{paulson-set-II}. |
241 |
233 |
242 The definition may involve arbitrary parameters $\vec{p}=p_1$, |
234 The definition may involve arbitrary parameters $\vec{p}=p_1$, |
243 \ldots,~$p_k$. Each recursive set then has the form $R_i(\vec{p})$. The |
235 \ldots,~$p_k$. Each recursive set then has the form $R_i(\vec{p})$. The |
244 parameters must be identical every time they occur within a definition. This |
236 parameters must be identical every time they occur within a definition. This |
245 would appear to be a serious restriction compared with other systems such as |
237 would appear to be a serious restriction compared with other systems such as |
246 Coq~\cite{paulin92}. For instance, we cannot define the lists of |
238 Coq~\cite{paulin92}. For instance, we cannot define the lists of |
247 $n$ elements as the set $\listn(A,n)$ using rules where the parameter~$n$ |
239 $n$ elements as the set $\listn(A,n)$ using rules where the parameter~$n$ |
248 varies. \S\ref{listn-sec} describes how to express this set using the |
240 varies. Section~\ref{listn-sec} describes how to express this set using the |
249 inductive definition package. |
241 inductive definition package. |
250 |
242 |
251 To avoid clutter below, the recursive sets are shown as simply $R_i$ |
243 To avoid clutter below, the recursive sets are shown as simply $R_i$ |
252 instead of $R_i(\vec{p})$. |
244 instead of $R_i(\vec{p})$. |
253 |
245 |
369 the easiest way to get the definition through! |
363 the easiest way to get the definition through! |
370 |
364 |
371 The result structure contains the introduction rules as the theorem list {\tt |
365 The result structure contains the introduction rules as the theorem list {\tt |
372 intrs}. |
366 intrs}. |
373 |
367 |
374 \subsection{The elimination rule} |
368 \subsection{The case analysis rule} |
375 The elimination rule, called {\tt elim}, performs case analysis: a |
369 The elimination rule, called {\tt elim}, performs case analysis. There is one |
376 case for each introduction rule. The elimination rule |
370 case for each introduction rule. The elimination rule |
377 for $\Fin(A)$ is |
371 for $\Fin(A)$ is |
378 \[ \infer{Q}{x\in\Fin(A) & \infer*{Q}{[x=\emptyset]} |
372 \[ \infer{Q}{x\in\Fin(A) & \infer*{Q}{[x=\emptyset]} |
379 & \infer*{Q}{[x=\{a\}\un b & a\in A &b\in\Fin(A)]_{a,b}} } |
373 & \infer*{Q}{[x=\{a\}\un b & a\in A &b\in\Fin(A)]_{a,b}} } |
380 \] |
374 \] |
381 This rule states that if $x\in\Fin(A)$ then either $x=\emptyset$ or else |
375 The subscripted variables $a$ and~$b$ above the third premise are |
|
376 eigenvariables, subject to the usual `not free in \ldots' proviso. |
|
377 The rule states that if $x\in\Fin(A)$ then either $x=\emptyset$ or else |
382 $x=\{a\}\un b$ for some $a\in A$ and $b\in\Fin(A)$; it is a simple consequence |
378 $x=\{a\}\un b$ for some $a\in A$ and $b\in\Fin(A)$; it is a simple consequence |
383 of {\tt unfold}. |
379 of {\tt unfold}. |
384 |
380 |
385 \ifCADE\typeout{****Omitting mk_cases from CADE version!}\else |
381 The package also returns a function for generating simplified instances of |
386 The package also returns a function {\tt mk\_cases}, for generating simplified |
382 the case analysis rule. It works for datatypes and for inductive |
387 instances of the elimination rule. However, {\tt mk\_cases} only works for |
383 definitions involving datatypes, such as an inductively defined relation |
388 datatypes and for inductive definitions involving datatypes, such as an |
384 between lists. It instantiates {\tt elim} with a user-supplied term then |
389 inductively defined relation between lists. It instantiates {\tt elim} |
385 simplifies the cases using freeness of the underlying datatype. The |
390 with a user-supplied term, then simplifies the cases using the freeness of |
386 simplified rules perform `rule inversion' on the inductive definition. |
391 the underlying datatype. |
387 Section~\S\ref{mkcases} presents an example. |
392 See \S\ref{mkcases} for an example. |
388 |
393 \fi |
|
394 |
389 |
395 \section{Induction and coinduction rules} |
390 \section{Induction and coinduction rules} |
396 Here we must consider inductive and coinductive definitions separately. |
391 Here we must consider inductive and coinductive definitions separately. |
397 For an inductive definition, the package returns an induction rule derived |
392 For an inductive definition, the package returns an induction rule derived |
398 directly from the properties of least fixedpoints, as well as a modified |
393 directly from the properties of least fixedpoints, as well as a modified |
474 sum and product for representing infinite data structures |
470 sum and product for representing infinite data structures |
475 (see~\S\ref{univ-sec}). Coinductive definitions use these variant sums and |
471 (see~\S\ref{univ-sec}). Coinductive definitions use these variant sums and |
476 products. |
472 products. |
477 |
473 |
478 The package derives an {\tt unfold} theorem similar to that for $\Fin(A)$. |
474 The package derives an {\tt unfold} theorem similar to that for $\Fin(A)$. |
479 Then it proves the theorem {\tt co\_induct}, which expresses that $\llist(A)$ |
475 Then it proves the theorem {\tt coinduct}, which expresses that $\llist(A)$ |
480 is the greatest solution to this equation contained in $\quniv(A)$: |
476 is the greatest solution to this equation contained in $\quniv(A)$: |
481 \[ \infer{x\in\llist(A)}{x\in X & X\sbs \quniv(A) & |
477 \[ \infer{x\in\llist(A)}{x\in X & X\sbs \quniv(A) & |
482 \infer*{z=\LNil\disj \bigl(\exists a\,l.\, |
478 \infer*{z=\LNil\disj \bigl(\exists a\,l.\, |
483 \begin{array}[t]{@{}l} |
479 z=\LCons(a,l) \conj a\in A \conj l\in X\un\llist(A) \bigr)} |
484 z=\LCons(a,l) \conj a\in A \conj{}\\ |
480 {[z\in X]_z}} |
485 l\in X\un\llist(A) \bigr) |
481 % \begin{array}[t]{@{}l} |
486 \end{array} }{[z\in X]_z}} |
482 % z=\LCons(a,l) \conj a\in A \conj{}\\ |
|
483 % l\in X\un\llist(A) \bigr) |
|
484 % \end{array} }{[z\in X]_z}} |
487 \] |
485 \] |
488 This rule complements the introduction rules; it provides a means of showing |
486 This rule complements the introduction rules; it provides a means of showing |
489 $x\in\llist(A)$ when $x$ is infinite. For instance, if $x=\LCons(0,x)$ then |
487 $x\in\llist(A)$ when $x$ is infinite. For instance, if $x=\LCons(0,x)$ then |
490 applying the rule with $X=\{x\}$ proves $x\in\llist(\nat)$. Here $\nat$ |
488 applying the rule with $X=\{x\}$ proves $x\in\llist(\nat)$. (Here $\nat$ |
491 is the set of natural numbers. |
489 is the set of natural numbers.) |
492 |
490 |
493 Having $X\un\llist(A)$ instead of simply $X$ in the third premise above |
491 Having $X\un\llist(A)$ instead of simply $X$ in the third premise above |
494 represents a slight strengthening of the greatest fixedpoint property. I |
492 represents a slight strengthening of the greatest fixedpoint property. I |
495 discuss several forms of coinduction rules elsewhere~\cite{paulson-coind}. |
493 discuss several forms of coinduction rules elsewhere~\cite{paulson-coind}. |
496 |
494 |
504 The definition of finite sets has been discussed extensively above. Here |
502 The definition of finite sets has been discussed extensively above. Here |
505 is the corresponding ML invocation (note that $\cons(a,b)$ abbreviates |
503 is the corresponding ML invocation (note that $\cons(a,b)$ abbreviates |
506 $\{a\}\un b$ in Isabelle/ZF): |
504 $\{a\}\un b$ in Isabelle/ZF): |
507 \begin{ttbox} |
505 \begin{ttbox} |
508 structure Fin = Inductive_Fun |
506 structure Fin = Inductive_Fun |
509 (val thy = Arith.thy addconsts [(["Fin"],"i=>i")]; |
507 (val thy = Arith.thy addconsts [(["Fin"],"i=>i")] |
510 val rec_doms = [("Fin","Pow(A)")]; |
508 val rec_doms = [("Fin","Pow(A)")] |
511 val sintrs = |
509 val sintrs = ["0 : Fin(A)", |
512 ["0 : Fin(A)", |
510 "[| a: A; b: Fin(A) |] ==> cons(a,b) : Fin(A)"] |
513 "[| a: A; b: Fin(A) |] ==> cons(a,b) : Fin(A)"]; |
511 val monos = [] |
514 val monos = []; |
512 val con_defs = [] |
515 val con_defs = []; |
513 val type_intrs = [empty_subsetI, cons_subsetI, PowI] |
516 val type_intrs = [empty_subsetI, cons_subsetI, PowI]; |
|
517 val type_elims = [make_elim PowD]); |
514 val type_elims = [make_elim PowD]); |
518 \end{ttbox} |
515 \end{ttbox} |
519 The parent theory is obtained from {\tt Arith.thy} by adding the unary |
516 We apply the functor {\tt Inductive\_Fun} to a structure describing the |
520 function symbol~$\Fin$. Its domain is specified as $\pow(A)$, where $A$ is |
517 desired inductive definition. The parent theory~{\tt thy} is obtained from |
521 the parameter appearing in the introduction rules. For type-checking, the |
518 {\tt Arith.thy} by adding the unary function symbol~$\Fin$. Its domain is |
522 package supplies the introduction rules: |
519 specified as $\pow(A)$, where $A$ is the parameter appearing in the |
|
520 introduction rules. For type-checking, the structure supplies introduction |
|
521 rules: |
523 \[ \emptyset\sbs A \qquad |
522 \[ \emptyset\sbs A \qquad |
524 \infer{\{a\}\un B\sbs C}{a\in C & B\sbs C} |
523 \infer{\{a\}\un B\sbs C}{a\in C & B\sbs C} |
525 \] |
524 \] |
526 A further introduction rule and an elimination rule express the two |
525 A further introduction rule and an elimination rule express the two |
527 directions of the equivalence $A\in\pow(B)\bimp A\sbs B$. Type-checking |
526 directions of the equivalence $A\in\pow(B)\bimp A\sbs B$. Type-checking |
528 involves mostly introduction rules. When the package returns, we can refer |
527 involves mostly introduction rules. |
529 to the $\Fin(A)$ introduction rules as {\tt Fin.intrs}, the induction rule |
528 |
530 as {\tt Fin.induct}, and so forth. |
529 ML is Isabelle's top level, so such functor invocations can take place at |
|
530 any time. The result structure is declared with the name~{\tt Fin}; we can |
|
531 refer to the $\Fin(A)$ introduction rules as {\tt Fin.intrs}, the induction |
|
532 rule as {\tt Fin.induct} and so forth. There are plans to integrate the |
|
533 package better into Isabelle so that users can place inductive definitions |
|
534 in Isabelle theory files instead of applying functors. |
|
535 |
531 |
536 |
532 \subsection{Lists of $n$ elements}\label{listn-sec} |
537 \subsection{Lists of $n$ elements}\label{listn-sec} |
533 This has become a standard example of an inductive definition. Following |
538 This has become a standard example of an inductive definition. Following |
534 Paulin-Mohring~\cite{paulin92}, we could attempt to define a new datatype |
539 Paulin-Mohring~\cite{paulin92}, we could attempt to define a new datatype |
535 $\listn(A,n)$, for lists of length~$n$, as an $n$-indexed family of sets. |
540 $\listn(A,n)$, for lists of length~$n$, as an $n$-indexed family of sets. |
536 But her introduction rules |
541 But her introduction rules |
537 \[ {\tt Niln}\in\listn(A,0) \qquad |
542 \[ \hbox{\tt Niln}\in\listn(A,0) \qquad |
538 \infer{{\tt Consn}(n,a,l)\in\listn(A,\succ(n))} |
543 \infer{\hbox{\tt Consn}(n,a,l)\in\listn(A,\succ(n))} |
539 {n\in\nat & a\in A & l\in\listn(A,n)} |
544 {n\in\nat & a\in A & l\in\listn(A,n)} |
540 \] |
545 \] |
541 are not acceptable to the inductive definition package: |
546 are not acceptable to the inductive definition package: |
542 $\listn$ occurs with three different parameter lists in the definition. |
547 $\listn$ occurs with three different parameter lists in the definition. |
543 |
548 |
544 \begin{figure} |
549 \begin{figure} |
545 \begin{small} |
550 \begin{ttbox} |
546 \begin{verbatim} |
|
547 structure ListN = Inductive_Fun |
551 structure ListN = Inductive_Fun |
548 (val thy = ListFn.thy addconsts [(["listn"],"i=>i")]; |
552 (val thy = ListFn.thy addconsts [(["listn"],"i=>i")] |
549 val rec_doms = [("listn", "nat*list(A)")]; |
553 val rec_doms = [("listn", "nat*list(A)")] |
550 val sintrs = |
554 val sintrs = |
551 ["<0,Nil> : listn(A)", |
555 ["<0,Nil>: listn(A)", |
552 "[| a: A; <n,l> : listn(A) |] ==> |
556 "[| a: A; <n,l>: listn(A) |] ==> <succ(n), Cons(a,l)>: listn(A)"] |
553 <succ(n), Cons(a,l)> : listn(A)"]; |
557 val monos = [] |
554 val monos = []; |
558 val con_defs = [] |
555 val con_defs = []; |
559 val type_intrs = nat_typechecks @ List.intrs @ [SigmaI] |
556 val type_intrs = nat_typechecks @ List.intrs @ [SigmaI]; |
|
557 val type_elims = [SigmaE2]); |
560 val type_elims = [SigmaE2]); |
558 \end{verbatim} |
561 \end{ttbox} |
559 \end{small} |
|
560 \hrule |
562 \hrule |
561 \caption{Defining lists of $n$ elements} \label{listn-fig} |
563 \caption{Defining lists of $n$ elements} \label{listn-fig} |
562 \end{figure} |
564 \end{figure} |
563 |
565 |
564 There is an obvious way of handling this particular example, which may suggest |
566 The Isabelle/ZF version of this example suggests a general treatment of |
565 a general approach to varying parameters. Here, we can take advantage of an |
567 varying parameters. Here, we use the existing datatype definition of |
566 existing datatype definition of $\lst(A)$, with constructors $\Nil$ |
568 $\lst(A)$, with constructors $\Nil$ and~$\Cons$. Then incorporate the |
567 and~$\Cons$. Then incorporate the number~$n$ into the inductive set itself, |
569 parameter~$n$ into the inductive set itself, defining $\listn(A)$ as a |
568 defining $\listn(A)$ as a relation. It consists of pairs $\pair{n,l}$ such |
570 relation. It consists of pairs $\pair{n,l}$ such that $n\in\nat$ |
569 that $n\in\nat$ and~$l\in\lst(A)$ and $l$ has length~$n$. In fact, |
571 and~$l\in\lst(A)$ and $l$ has length~$n$. In fact, $\listn(A)$ is the |
570 $\listn(A)$ turns out to be the converse of the length function on~$\lst(A)$. |
572 converse of the length function on~$\lst(A)$. The Isabelle/ZF introduction |
571 The Isabelle/ZF introduction rules are |
573 rules are |
572 \[ \pair{0,\Nil}\in\listn(A) \qquad |
574 \[ \pair{0,\Nil}\in\listn(A) \qquad |
573 \infer{\pair{\succ(n),\Cons(a,l)}\in\listn(A)} |
575 \infer{\pair{\succ(n),\Cons(a,l)}\in\listn(A)} |
574 {a\in A & \pair{n,l}\in\listn(A)} |
576 {a\in A & \pair{n,l}\in\listn(A)} |
575 \] |
577 \] |
576 Figure~\ref{listn-fig} presents the ML invocation. A theory of lists, |
578 Figure~\ref{listn-fig} presents the ML invocation. A theory of lists, |
824 directly~\cite{szasz93}. So she generalized primitive recursion to |
825 directly~\cite{szasz93}. So she generalized primitive recursion to |
825 tuple-valued functions. This modified the inductive definition such that |
826 tuple-valued functions. This modified the inductive definition such that |
826 each operation on primitive recursive functions combined just two functions. |
827 each operation on primitive recursive functions combined just two functions. |
827 |
828 |
828 \begin{figure} |
829 \begin{figure} |
829 \begin{small}\begin{verbatim} |
830 \begin{ttbox} |
830 structure Primrec = Inductive_Fun |
831 structure Primrec = Inductive_Fun |
831 (val thy = Primrec0.thy; |
832 (val thy = Primrec0.thy |
832 val rec_doms = [("primrec", "list(nat)->nat")]; |
833 val rec_doms = [("primrec", "list(nat)->nat")] |
833 val ext = None; |
834 val sintrs = |
834 val sintrs = |
835 ["SC : primrec", |
835 ["SC : primrec", |
836 "k: nat ==> CONST(k) : primrec", |
836 "k: nat ==> CONST(k) : primrec", |
837 "i: nat ==> PROJ(i) : primrec", |
837 "i: nat ==> PROJ(i) : primrec", |
838 "[| g: primrec; fs: list(primrec) |] ==> COMP(g,fs): primrec", |
838 "[| g: primrec; fs: list(primrec) |] ==> COMP(g,fs): primrec", |
839 "[| f: primrec; g: primrec |] ==> PREC(f,g): primrec"] |
839 "[| f: primrec; g: primrec |] ==> PREC(f,g): primrec"]; |
840 val monos = [list_mono] |
840 val monos = [list_mono]; |
841 val con_defs = [SC_def,CONST_def,PROJ_def,COMP_def,PREC_def] |
841 val con_defs = [SC_def,CONST_def,PROJ_def,COMP_def,PREC_def]; |
842 val type_intrs = pr0_typechecks |
842 val type_intrs = pr0_typechecks; |
|
843 val type_elims = []); |
843 val type_elims = []); |
844 \end{verbatim}\end{small} |
844 \end{ttbox} |
845 \hrule |
845 \hrule |
846 \caption{Inductive definition of the primitive recursive functions} |
846 \caption{Inductive definition of the primitive recursive functions} |
847 \label{primrec-fig} |
847 \label{primrec-fig} |
848 \end{figure} |
848 \end{figure} |
849 \def\fs{{\it fs}} |
849 \def\fs{{\it fs}} |
850 Szasz was using ALF, but Coq and HOL would also have problems accepting |
850 Szasz was using ALF, but Coq and HOL would also have problems accepting |
851 this definition. Isabelle's package accepts it easily since |
851 this definition. Isabelle's package accepts it easily since |
852 $[f_0,\ldots,f_{m-1}]$ is a list of primitive recursive functions and |
852 $[f_0,\ldots,f_{m-1}]$ is a list of primitive recursive functions and |
853 $\lst$ is monotonic. There are five introduction rules, one for each of |
853 $\lst$ is monotonic. There are five introduction rules, one for each of |
854 the five forms of primitive recursive function. Note the one for $\COMP$: |
854 the five forms of primitive recursive function. Let us examine the one for |
|
855 $\COMP$: |
855 \[ \infer{\COMP(g,\fs)\in\primrec}{g\in\primrec & \fs\in\lst(\primrec)} \] |
856 \[ \infer{\COMP(g,\fs)\in\primrec}{g\in\primrec & \fs\in\lst(\primrec)} \] |
856 The induction rule for $\primrec$ has one case for each introduction rule. |
857 The induction rule for $\primrec$ has one case for each introduction rule. |
857 Due to the use of $\lst$ as a monotone operator, the composition case has |
858 Due to the use of $\lst$ as a monotone operator, the composition case has |
858 an unusual induction hypothesis: |
859 an unusual induction hypothesis: |
859 \[ \infer*{P(\COMP(g,\fs))} |
860 \[ \infer*{P(\COMP(g,\fs))} |
863 structural induction on lists, yielding two subcases: either $\fs=\Nil$ or |
864 structural induction on lists, yielding two subcases: either $\fs=\Nil$ or |
864 else $\fs=\Cons(f,\fs')$, where $f\in\primrec$, $P(f)$, and $\fs'$ is |
865 else $\fs=\Cons(f,\fs')$, where $f\in\primrec$, $P(f)$, and $\fs'$ is |
865 another list of primitive recursive functions satisfying~$P$. |
866 another list of primitive recursive functions satisfying~$P$. |
866 |
867 |
867 Figure~\ref{primrec-fig} presents the ML invocation. Theory {\tt |
868 Figure~\ref{primrec-fig} presents the ML invocation. Theory {\tt |
868 Primrec0.thy} defines the constants $\SC$, etc.; their definitions |
869 Primrec0.thy} defines the constants $\SC$, $\CONST$, etc. These are not |
869 consist of routine list programming and are omitted. The Isabelle theory |
870 constructors of a new datatype, but functions over lists of numbers. Their |
870 goes on to formalize Ackermann's function and prove that it is not |
871 definitions, which are omitted, consist of routine list programming. In |
871 primitive recursive, using the induction rule {\tt Primrec.induct}. The |
872 Isabelle/ZF, the primitive recursive functions are defined as a subset of |
872 proof follows Szasz's excellent account. |
873 the function set $\lst(\nat)\to\nat$. |
873 |
874 |
874 ALF and Coq treat inductive definitions as datatypes, with a new |
875 The Isabelle theory goes on to formalize Ackermann's function and prove |
875 constructor for each introduction rule. This forced Szasz to define a |
876 that it is not primitive recursive, using the induction rule {\tt |
876 small programming language for the primitive recursive functions, and then |
877 Primrec.induct}. The proof follows Szasz's excellent account. |
877 define their semantics. But the Isabelle/ZF formulation defines the |
|
878 primitive recursive functions directly as a subset of the function set |
|
879 $\lst(\nat)\to\nat$. This saves a step and conforms better to mathematical |
|
880 tradition. |
|
881 |
878 |
882 |
879 |
883 \section{Datatypes and codatatypes}\label{data-sec} |
880 \section{Datatypes and codatatypes}\label{data-sec} |
884 A (co)datatype definition is a (co)inductive definition with automatically |
881 A (co)datatype definition is a (co)inductive definition with automatically |
885 defined constructors and a case analysis operator. The package proves that the |
882 defined constructors and a case analysis operator. The package proves that |
886 case operator inverts the constructors, and can also prove freeness theorems |
883 the case operator inverts the constructors and can prove freeness theorems |
887 involving any pair of constructors. |
884 involving any pair of constructors. |
888 |
885 |
889 |
886 |
890 \subsection{Constructors and their domain}\label{univ-sec} |
887 \subsection{Constructors and their domain}\label{univ-sec} |
891 Conceptually, our two forms of definition are distinct: a (co)inductive |
888 Conceptually, our two forms of definition are distinct. A (co)inductive |
892 definition selects a subset of an existing set, but a (co)datatype |
889 definition selects a subset of an existing set; a (co)datatype definition |
893 definition creates a new set. But the package reduces the latter to the |
890 creates a new set. But the package reduces the latter to the former. A |
894 former. A set having strong closure properties must serve as the domain |
891 set having strong closure properties must serve as the domain of the |
895 of the (co)inductive definition. Constructing this set requires some |
892 (co)inductive definition. Constructing this set requires some theoretical |
896 theoretical effort. Consider first datatypes and then codatatypes. |
893 effort, which must be done anyway to show that (co)datatypes exist. It is |
|
894 not obvious that standard set theory is suitable for defining codatatypes. |
897 |
895 |
898 Isabelle/ZF defines the standard notion of Cartesian product $A\times B$, |
896 Isabelle/ZF defines the standard notion of Cartesian product $A\times B$, |
899 containing ordered pairs $\pair{a,b}$. Now the $m$-tuple |
897 containing ordered pairs $\pair{a,b}$. Now the $m$-tuple |
900 $\pair{x_1,\ldots\,x_m}$ is the empty set~$\emptyset$ if $m=0$, simply |
898 $\pair{x_1,\ldots,x_m}$ is the empty set~$\emptyset$ if $m=0$, simply |
901 $x_1$ if $m=1$, and $\pair{x_1,\pair{x_2,\ldots\,x_m}}$ if $m\geq2$. |
899 $x_1$ if $m=1$ and $\pair{x_1,\pair{x_2,\ldots,x_m}}$ if $m\geq2$. |
902 Isabelle/ZF also defines the disjoint sum $A+B$, containing injections |
900 Isabelle/ZF also defines the disjoint sum $A+B$, containing injections |
903 $\Inl(a)\equiv\pair{0,a}$ and $\Inr(b)\equiv\pair{1,b}$. |
901 $\Inl(a)\equiv\pair{0,a}$ and $\Inr(b)\equiv\pair{1,b}$. |
904 |
902 |
905 A datatype constructor $\Con(x_1,\ldots\,x_m)$ is defined to be |
903 A datatype constructor $\Con(x_1,\ldots,x_m)$ is defined to be |
906 $h(\pair{x_1,\ldots\,x_m})$, where $h$ is composed of $\Inl$ and~$\Inr$. |
904 $h(\pair{x_1,\ldots,x_m})$, where $h$ is composed of $\Inl$ and~$\Inr$. |
907 In a mutually recursive definition, all constructors for the set~$R_i$ have |
905 In a mutually recursive definition, all constructors for the set~$R_i$ have |
908 the outer form~$h_{in}$, where $h_{in}$ is the injection described |
906 the outer form~$h_{in}$, where $h_{in}$ is the injection described |
909 in~\S\ref{mutual-sec}. Further nested injections ensure that the |
907 in~\S\ref{mutual-sec}. Further nested injections ensure that the |
910 constructors for~$R_i$ are pairwise distinct. |
908 constructors for~$R_i$ are pairwise distinct. |
911 |
909 |
922 contain non-well-founded objects. |
920 contain non-well-founded objects. |
923 |
921 |
924 To support codatatypes, Isabelle/ZF defines a variant notion of ordered |
922 To support codatatypes, Isabelle/ZF defines a variant notion of ordered |
925 pair, written~$\pair{a;b}$. It also defines the corresponding variant |
923 pair, written~$\pair{a;b}$. It also defines the corresponding variant |
926 notion of Cartesian product $A\otimes B$, variant injections $\QInl(a)$ |
924 notion of Cartesian product $A\otimes B$, variant injections $\QInl(a)$ |
927 and~$\QInr(b)$, and variant disjoint sum $A\oplus B$. Finally it defines |
925 and~$\QInr(b)$ and variant disjoint sum $A\oplus B$. Finally it defines |
928 the set $\quniv(A)$, which contains~$A$ and furthermore contains |
926 the set $\quniv(A)$, which contains~$A$ and furthermore contains |
929 $\pair{a;b}$, $\QInl(a)$ and $\QInr(b)$ for $a$, $b\in\quniv(A)$. In a |
927 $\pair{a;b}$, $\QInl(a)$ and $\QInr(b)$ for $a$, $b\in\quniv(A)$. In a |
930 typical codatatype definition with set parameters $A_1$, \ldots, $A_k$, a |
928 typical codatatype definition with set parameters $A_1$, \ldots, $A_k$, a |
931 suitable domain is $\quniv(A_1\un\cdots\un A_k)$. This approach using |
929 suitable domain is $\quniv(A_1\un\cdots\un A_k)$. This approach using |
932 standard ZF set theory\footnote{No reference is available. Variant pairs |
930 standard ZF set theory~\cite{paulson-final} is an alternative to adopting |
933 are defined by $\pair{a;b}\equiv (a+b) \equiv (\{0\}\times a) \un |
931 Aczel's Anti-Foundation Axiom~\cite{aczel88}. |
934 (\{1\}\times b)$, where $\times$ is the Cartesian product for standard |
|
935 ordered pairs. Now |
|
936 $\pair{a;b}$ is injective and monotonic in its two arguments. |
|
937 Non-well-founded constructions, such as infinite lists, are constructed |
|
938 as least fixedpoints; the bounding set typically has the form |
|
939 $\univ(a_1\un\cdots\un a_k)$, where $a_1$, \ldots, $a_k$ are specified |
|
940 elements of the construction.} |
|
941 is an alternative to adopting Aczel's Anti-Foundation |
|
942 Axiom~\cite{aczel88}. |
|
943 |
932 |
944 \subsection{The case analysis operator} |
933 \subsection{The case analysis operator} |
945 The (co)datatype package automatically defines a case analysis operator, |
934 The (co)datatype package automatically defines a case analysis operator, |
946 called {\tt$R$\_case}. A mutually recursive definition still has only one |
935 called {\tt$R$\_case}. A mutually recursive definition still has only one |
947 operator, whose name combines those of the recursive sets: it is called |
936 operator, whose name combines those of the recursive sets: it is called |
989 \end{itemize} |
978 \end{itemize} |
990 Codatatype definitions are treated in precisely the same way. They express |
979 Codatatype definitions are treated in precisely the same way. They express |
991 case operators using those for the variant products and sums, namely |
980 case operators using those for the variant products and sums, namely |
992 $\qsplit$ and~$\qcase$. |
981 $\qsplit$ and~$\qcase$. |
993 |
982 |
994 |
983 \medskip |
995 \ifCADE The package has processed all the datatypes discussed in my earlier |
984 |
996 paper~\cite{paulson-set-II} and the codatatype of lazy lists. Space |
985 \ifCADE The package has processed all the datatypes discussed in |
997 limitations preclude discussing these examples here, but they are |
986 my earlier paper~\cite{paulson-set-II} and the codatatype of lazy lists. |
998 distributed with Isabelle. |
987 Space limitations preclude discussing these examples here, but they are |
999 \typeout{****Omitting datatype examples from CADE version!} \else |
988 distributed with Isabelle. \typeout{****Omitting datatype examples from |
|
989 CADE version!} \else |
1000 |
990 |
1001 To see how constructors and the case analysis operator are defined, let us |
991 To see how constructors and the case analysis operator are defined, let us |
1002 examine some examples. These include lists and trees/forests, which I have |
992 examine some examples. These include lists and trees/forests, which I have |
1003 discussed extensively in another paper~\cite{paulson-set-II}. |
993 discussed extensively in another paper~\cite{paulson-set-II}. |
1004 |
994 |
1005 \begin{figure} |
995 \begin{figure} |
1006 \begin{ttbox} |
996 \begin{ttbox} |
1007 structure List = Datatype_Fun |
997 structure List = Datatype_Fun |
1008 (val thy = Univ.thy; |
998 (val thy = Univ.thy |
1009 val rec_specs = |
999 val rec_specs = [("list", "univ(A)", |
1010 [("list", "univ(A)", |
1000 [(["Nil"], "i"), |
1011 [(["Nil"], "i"), |
1001 (["Cons"], "[i,i]=>i")])] |
1012 (["Cons"], "[i,i]=>i")])]; |
1002 val rec_styp = "i=>i" |
1013 val rec_styp = "i=>i"; |
1003 val ext = None |
1014 val ext = None; |
1004 val sintrs = ["Nil : list(A)", |
1015 val sintrs = |
1005 "[| a: A; l: list(A) |] ==> Cons(a,l) : list(A)"] |
1016 ["Nil : list(A)", |
1006 val monos = [] |
1017 "[| a: A; l: list(A) |] ==> Cons(a,l) : list(A)"]; |
1007 val type_intrs = datatype_intrs |
1018 val monos = []; |
|
1019 val type_intrs = datatype_intrs; |
|
1020 val type_elims = datatype_elims); |
1008 val type_elims = datatype_elims); |
1021 \end{ttbox} |
1009 \end{ttbox} |
1022 \hrule |
1010 \hrule |
1023 \caption{Defining the datatype of lists} \label{list-fig} |
1011 \caption{Defining the datatype of lists} \label{list-fig} |
1024 |
1012 |
1025 \medskip |
1013 \medskip |
1026 \begin{ttbox} |
1014 \begin{ttbox} |
1027 structure LList = CoDatatype_Fun |
1015 structure LList = CoDatatype_Fun |
1028 (val thy = QUniv.thy; |
1016 (val thy = QUniv.thy |
1029 val rec_specs = |
1017 val rec_specs = [("llist", "quniv(A)", |
1030 [("llist", "quniv(A)", |
1018 [(["LNil"], "i"), |
1031 [(["LNil"], "i"), |
1019 (["LCons"], "[i,i]=>i")])] |
1032 (["LCons"], "[i,i]=>i")])]; |
1020 val rec_styp = "i=>i" |
1033 val rec_styp = "i=>i"; |
1021 val ext = None |
1034 val ext = None; |
1022 val sintrs = ["LNil : llist(A)", |
1035 val sintrs = |
1023 "[| a: A; l: llist(A) |] ==> LCons(a,l) : llist(A)"] |
1036 ["LNil : llist(A)", |
1024 val monos = [] |
1037 "[| a: A; l: llist(A) |] ==> LCons(a,l) : llist(A)"]; |
1025 val type_intrs = codatatype_intrs |
1038 val monos = []; |
|
1039 val type_intrs = codatatype_intrs; |
|
1040 val type_elims = codatatype_elims); |
1026 val type_elims = codatatype_elims); |
1041 \end{ttbox} |
1027 \end{ttbox} |
1042 \hrule |
1028 \hrule |
1043 \caption{Defining the codatatype of lazy lists} \label{llist-fig} |
1029 \caption{Defining the codatatype of lazy lists} \label{llist-fig} |
1044 \end{figure} |
1030 \end{figure} |
1195 {\tt tree\_forest\_case}(f,c,g) & \equiv & |
1178 {\tt tree\_forest\_case}(f,c,g) & \equiv & |
1196 \case(\split(f),\, \case(\lambda u.c, \split(g))) |
1179 \case(\split(f),\, \case(\lambda u.c, \split(g))) |
1197 \end{eqnarray*} |
1180 \end{eqnarray*} |
1198 |
1181 |
1199 \begin{figure} |
1182 \begin{figure} |
1200 \begin{small} |
1183 \begin{ttbox} |
1201 \begin{verbatim} |
|
1202 structure Data = Datatype_Fun |
1184 structure Data = Datatype_Fun |
1203 (val thy = Univ.thy; |
1185 (val thy = Univ.thy |
1204 val rec_specs = |
1186 val rec_specs = [("data", "univ(A Un B)", |
1205 [("data", "univ(A Un B)", |
1187 [(["Con0"], "i"), |
1206 [(["Con0"], "i"), |
1188 (["Con1"], "i=>i"), |
1207 (["Con1"], "i=>i"), |
1189 (["Con2"], "[i,i]=>i"), |
1208 (["Con2"], "[i,i]=>i"), |
1190 (["Con3"], "[i,i,i]=>i")])] |
1209 (["Con3"], "[i,i,i]=>i")])]; |
1191 val rec_styp = "[i,i]=>i" |
1210 val rec_styp = "[i,i]=>i"; |
1192 val ext = None |
1211 val ext = None; |
1193 val sintrs = |
1212 val sintrs = |
1194 ["Con0 : data(A,B)", |
1213 ["Con0 : data(A,B)", |
1195 "[| a: A |] ==> Con1(a) : data(A,B)", |
1214 "[| a: A |] ==> Con1(a) : data(A,B)", |
1196 "[| a: A; b: B |] ==> Con2(a,b) : data(A,B)", |
1215 "[| a: A; b: B |] ==> Con2(a,b) : data(A,B)", |
1197 "[| a: A; b: B; d: data(A,B) |] ==> Con3(a,b,d) : data(A,B)"] |
1216 "[| a: A; b: B; d: data(A,B) |] ==> Con3(a,b,d) : data(A,B)"]; |
1198 val monos = [] |
1217 val monos = []; |
1199 val type_intrs = datatype_intrs |
1218 val type_intrs = datatype_intrs; |
|
1219 val type_elims = datatype_elims); |
1200 val type_elims = datatype_elims); |
1220 \end{verbatim} |
1201 \end{ttbox} |
1221 \end{small} |
|
1222 \hrule |
1202 \hrule |
1223 \caption{Defining the four-constructor sample datatype} \label{data-fig} |
1203 \caption{Defining the four-constructor sample datatype} \label{data-fig} |
1224 \end{figure} |
1204 \end{figure} |
1225 |
1205 |
1226 \subsection{A four-constructor datatype} |
1206 \subsection{A four-constructor datatype} |
1303 \end{eqnarray*} |
1283 \end{eqnarray*} |
1304 For example, these rewrite $\Con_1(a)=\Con_1(b)$ to $a=b$ in four steps. |
1284 For example, these rewrite $\Con_1(a)=\Con_1(b)$ to $a=b$ in four steps. |
1305 |
1285 |
1306 The theorem list \verb|free_SEs| enables the classical |
1286 The theorem list \verb|free_SEs| enables the classical |
1307 reasoner to perform similar replacements. It consists of elimination rules |
1287 reasoner to perform similar replacements. It consists of elimination rules |
1308 to replace $\Con_0=c$ by $c=\Inl(\Inl(\emptyset))$, and so forth, in the |
1288 to replace $\Con_0=c$ by $c=\Inl(\Inl(\emptyset))$ and so forth, in the |
1309 assumptions. |
1289 assumptions. |
1310 |
1290 |
1311 Such incremental unfolding combines freeness reasoning with other proof |
1291 Such incremental unfolding combines freeness reasoning with other proof |
1312 steps. It has the unfortunate side-effect of unfolding definitions of |
1292 steps. It has the unfortunate side-effect of unfolding definitions of |
1313 constructors in contexts such as $\exists x.\Con_1(a)=x$, where they should |
1293 constructors in contexts such as $\exists x.\Con_1(a)=x$, where they should |
1314 be left alone. Calling the Isabelle tactic {\tt fold\_tac con\_defs} |
1294 be left alone. Calling the Isabelle tactic {\tt fold\_tac con\_defs} |
1315 restores the defined constants. |
1295 restores the defined constants. |
1316 \fi %CADE |
1296 \fi %CADE |
1317 |
1297 |
|
1298 \section{Related work}\label{related} |
|
1299 The use of least fixedpoints to express inductive definitions seems |
|
1300 obvious. Why, then, has this technique so seldom been implemented? |
|
1301 |
|
1302 Most automated logics can only express inductive definitions by asserting |
|
1303 new axioms. Little would be left of Boyer and Moore's logic~\cite{bm79} if |
|
1304 their shell principle were removed. With ALF the situation is more |
|
1305 complex; earlier versions of Martin-L\"of's type theory could (using |
|
1306 wellordering types) express datatype definitions, but the version |
|
1307 underlying ALF requires new rules for each definition~\cite{dybjer91}. |
|
1308 With Coq the situation is subtler still; its underlying Calculus of |
|
1309 Constructions can express inductive definitions~\cite{huet88}, but cannot |
|
1310 quite handle datatype definitions~\cite{paulin92}. It seems that |
|
1311 researchers tried hard to circumvent these problems before finally |
|
1312 extending the Calculus with rule schemes for strictly positive operators. |
|
1313 |
|
1314 Higher-order logic can express inductive definitions through quantification |
|
1315 over unary predicates. The following formula expresses that~$i$ belongs to the |
|
1316 least set containing~0 and closed under~$\succ$: |
|
1317 \[ \forall P. P(0)\conj (\forall x.P(x)\imp P(\succ(x))) \imp P(i) \] |
|
1318 This technique can be used to prove the Knaster-Tarski Theorem, but it is |
|
1319 little used in the HOL system. Melham~\cite{melham89} clearly describes |
|
1320 the development. The natural numbers are defined as shown above, but lists |
|
1321 are defined as functions over the natural numbers. Unlabelled |
|
1322 trees are defined using G\"odel numbering; a labelled tree consists of an |
|
1323 unlabelled tree paired with a list of labels. Melham's datatype package |
|
1324 expresses the user's datatypes in terms of labelled trees. It has been |
|
1325 highly successful, but a fixedpoint approach would have yielded greater |
|
1326 functionality with less effort. |
|
1327 |
|
1328 Melham's inductive definition package~\cite{camilleri92} uses |
|
1329 quantification over predicates, which is implicitly a fixedpoint approach. |
|
1330 Instead of formalizing the notion of monotone function, it requires |
|
1331 definitions to consist of finitary rules, a syntactic form that excludes |
|
1332 many monotone inductive definitions. |
|
1333 |
|
1334 The earliest use of least fixedpoints is probably Robin Milner's datatype |
|
1335 package for Edinburgh LCF~\cite{milner-ind}. Brian Monahan extended this |
|
1336 package considerably~\cite{monahan84}, as did I in unpublished |
|
1337 work.\footnote{The datatype package described in my LCF |
|
1338 book~\cite{paulson87} does {\it not\/} make definitions, but merely |
|
1339 asserts axioms. I justified this shortcut on grounds of efficiency: |
|
1340 existing packages took tens of minutes to run. Such an explanation would |
|
1341 not do today.} |
|
1342 LCF is a first-order logic of domain theory; the relevant fixedpoint |
|
1343 theorem is not Knaster-Tarski but concerns fixedpoints of continuous |
|
1344 functions over domains. LCF is too weak to express recursive predicates. |
|
1345 Thus it would appear that the Isabelle/ZF package is the first to be based |
|
1346 on the Knaster-Tarski Theorem. |
|
1347 |
|
1348 |
1318 \section{Conclusions and future work} |
1349 \section{Conclusions and future work} |
1319 The fixedpoint approach makes it easy to implement a powerful |
1350 Higher-order logic and set theory are both powerful enough to express |
1320 package for inductive and coinductive definitions. It is efficient: it |
1351 inductive definitions. A growing number of theorem provers implement one |
|
1352 of these~\cite{IMPS,saaltink-fme}. The easiest sort of inductive |
|
1353 definition package to write is one that asserts new axioms, not one that |
|
1354 makes definitions and proves theorems about them. But asserting axioms |
|
1355 could introduce unsoundness. |
|
1356 |
|
1357 The fixedpoint approach makes it fairly easy to implement a package for |
|
1358 (co)inductive definitions that does not assert axioms. It is efficient: it |
1321 processes most definitions in seconds and even a 60-constructor datatype |
1359 processes most definitions in seconds and even a 60-constructor datatype |
1322 requires only two minutes. It is also simple: the package consists of |
1360 requires only two minutes. It is also simple: the package consists of |
1323 under 1100 lines (35K bytes) of Standard ML code. The first working |
1361 under 1100 lines (35K bytes) of Standard ML code. The first working |
1324 version took under a week to code. |
1362 version took under a week to code. |
1325 |
1363 |
|
1364 In set theory, care is required to ensure that the inductive definition |
|
1365 yields a set (rather than a proper class). This problem is inherent to set |
|
1366 theory, whether or not the Knaster-Tarski Theorem is employed. We must |
|
1367 exhibit a bounding set (called a domain above). For inductive definitions, |
|
1368 this is often trivial. For datatype definitions, I have had to formalize |
|
1369 much set theory. I intend to formalize cardinal arithmetic and the |
|
1370 $\aleph$-sequence to handle datatype definitions that have infinite |
|
1371 branching. The need for such efforts is not a drawback of the fixedpoint |
|
1372 approach, for the alternative is to take such definitions on faith. |
|
1373 |
1326 The approach is not restricted to set theory. It should be suitable for |
1374 The approach is not restricted to set theory. It should be suitable for |
1327 any logic that has some notion of set and the Knaster-Tarski Theorem. |
1375 any logic that has some notion of set and the Knaster-Tarski Theorem. I |
1328 Indeed, Melham's inductive definition package for the HOL |
1376 intend to use the Isabelle/ZF package as the basis for a higher-order logic |
1329 system~\cite{camilleri92} implicitly proves this theorem. |
1377 one, using Isabelle/HOL\@. The necessary theory is already |
1330 |
|
1331 Datatype and codatatype definitions furthermore require a particular set |
|
1332 closed under a suitable notion of ordered pair. I intend to use the |
|
1333 Isabelle/ZF package as the basis for a higher-order logic one, using |
|
1334 Isabelle/HOL\@. The necessary theory is already |
|
1335 mechanized~\cite{paulson-coind}. HOL represents sets by unary predicates; |
1378 mechanized~\cite{paulson-coind}. HOL represents sets by unary predicates; |
1336 defining the corresponding types may cause complication. |
1379 defining the corresponding types may cause complications. |
1337 |
1380 |
1338 |
1381 |
1339 \bibliographystyle{plain} |
1382 \bibliographystyle{springer} |
1340 \bibliography{atp,theory,funprog,isabelle} |
1383 \bibliography{string-abbrv,atp,theory,funprog,isabelle} |
1341 %%%%%\doendnotes |
1384 %%%%%\doendnotes |
1342 |
1385 |
1343 \ifCADE\typeout{****Omitting appendices from CADE version!} |
1386 \ifCADE\typeout{****Omitting appendices from CADE version!} |
1344 \else |
1387 \else |
1345 \newpage |
1388 \newpage |