Content uploaded by Venanzio Capretta
Author content
All content in this area was uploaded by Venanzio Capretta
Content may be subject to copyright.
Computation by Prophecy
Ana Bove1and Venanzio Capretta2
1Department of Computer Science and Engineering
Chalmers University of Technology,
412 96 G¨oteborg, Sweden
Tel.: +46-31-7721020, Fax: +46-31-7723663
bove@chalmers.se
2Computer Science Institute (iCIS),
Radboud University Nijmegen,
Tel.: +31-24-3652631, Fax: +31-24-3652525
venanzio@cs.ru.nl
Abstract. We describe a new method to represent (partial) recursive
functions in type theory. For every recursive definition, we define a
co-inductive type of prophecies that characterises the traces of the com-
putation of the function. The structure of a prophecy is a possibly infinite
tree, which is coerced by linearisation to a type of partial results defined
by applying the delay monad to the co-domain of the function. Using
induction on a weight relation defined on the prophecies, we can reason
about them and prove that the formal type-theoretic version of the recur-
sive function, resulting from the present method, satisfies the recursive
equations of the original function. The advantages of this technique over
the method previously developed by the authors via a special-purpose
accessibility (domain) predicate are: there is no need of extra logical ar-
guments in the definition of the recursive function; the function can be
applied to any element in its domain, regardless of termination prop-
erties; we obtain a type of partial recursive functions between any two
given types; and composition of recursive functions can be easily defined.
1 Introduction
The implementation of general recursive functions in type theory has received
wide attention in the last decade, and several methods to implement recursive
algorithms and reason about them have been described in the literature.
We give a survey of different approaches in the related work section of a
previous article [6]. After the publication of that paper, the type-theory based
proof assistant Coq [14,3] has been extended with a new feature to define total
recursive functions that expands the native structural recursion. The feature
Function (based on the work by Balaa and Bertot [1]) facilitates the definition of
total functions that have a well-founded relation associated to them. In addition,
the tactic functional induction (based on the work by Barthe and Courtieu
[2]) has been added to the system, providing induction principles that follow
the definition of structurally recursive functions. These contributions enlarge
S. Ronchi Della Rocca (Ed.): TLCA 2007, LNCS 4583, pp. 70–83, 2007.
c
Springer-Verlag Berlin Heidelberg 2007
Computation by Prophecy 71
the class of total recursive functions that can be studied in Coq.Thereare,
however, functions that lay outside the reach of these new features, for example,
all strictly partial recursive functions. Our main goal in this work is to provide
a good general type-theoretic treatment of recursive computations (partial or
not).
We have previously worked on two methods to tackle this issue. The first
method [6,4,7] consists in characterising the inputs on which the function ter-
minates by an inductive (domain) predicate easily defined from the recursive
equations, and then defining the function itself by recursion on the proof that
the input argument satisfies this domain predicate. The second method [8] con-
sists in defining co-inductive types of partial elements and implementing general
recursive functions by co-recursion on these types.
Both methods have pros and cons.
The first method has two main advantages. First, the type-theoretic equa-
tions defining the function are almost identical to the recursive equations in a
functional programming language, except that the former require proof terms
for the domain predicate as additional arguments. Second, it is easy to reason
about a function formalised with this method by induction on its domain pred-
icate. A disadvantage is that the application of a function to a certain input
always requires a proof that the input satisfies the domain predicate defined for
the function; as a consequence, the function can only be applied to arguments
for which we know how to construct such a proof.
On the other hand, a function formalised with the second method requires
no additional logical arguments in its definition and, hence, the function can be
applied even to arguments for which it might not terminate. The main disad-
vantage is that reasoning about functions formalised in this way is much more
involved than with the first method.
Here, we show a new way of representing general recursive functions in in-
tensional type theory, where we adapt some of the ideas of the first method
to facilitate the definition of functions with the second one and the subsequent
reasoning about their formalisation. In other words, we propose a co-inductive
version of the Bove/Capretta method.
Throughout this paper we will use a generalisation of the Fibonacci function
as a running example to illustrate the notions we are presenting. This algorithm
is defined as follows:
F:N→N
F0=a
F1=b+c∗F(g0)
F(S(Sn)) = F(gn)+F(g(Sn)).
where a,band care natural numbers and g:N→N. We can get the standard
Fibonacci sequence by letting a=1,b=1,c= 0, and letting gbe the identity
function.
Observe that the totality of Fdepends on the definition of g:withthesame
choices of a,b,c, but choosing for gthe successor function, we obtain a function
that is defined in 0 but diverges for any other value.
72 A. Bove and V. Capretta
This paper is organised as follows. In Section 2, we recall how to define a
recursive function with the inductive Bove/Capretta method. Sections 3 and
4 present, respectively, the prophecies, that is, the co-inductive version of the
Bove/Capretta method, and their evaluation procedure. In Section 5, we show
the validity of this new method. Finally, Section 6 presents some conclusions.
We have formalised the running example in the proof assistant Coq.Asan
additional example, we have also formalised the quicksort algorithm using the
method we present here. The files of both formalisations are available on the
web at the address: http://www.cs.ru.nl/~venanzio/Coq/prophecy.html.
2 Overview of the Bove/Capretta Method
We outline the general steps of the inductive Bove/Capretta method by showing
how an algorithm defined by general recursive equations can be formalised in
type theory.
Let fbe a recursive function defined by a series of (non-overlapping) equa-
tions. We assume that the informal definition of the function has the following
form: f:A→B
···
fp=e[(fp
1),...,(fp
n)]
···
where “fp=···” is one of the recursive equations defining f.Thetermpis
a pattern, possibly containing variables that can occur in the right-hand side of
the equation. The right-hand side is an expression e, recursively calling fon the
arguments p1,...,p
n.
For an ar gument amatching the pattern p, there are three phases in the com-
putation of (fa): first, from the argument a, the recursive arguments a1,...,a
n
are computed; then, the program fis recursively applied to these arguments;
and finally, the results of the recursive calls are fed into the operator eto obtain
the final result. This three-steps process is general and can be used to give a
very abstract notion of computable function [9].
We recall that the Bove/Capretta method consists in characterising the do-
main of a function by an inductive predicate with (in principle) one constructor
for each of the equations defining the function1. The constructor corresponding
to each equation takes as parameters assumptions stating that the recursive ar-
guments in the equation satisfy the domain predicate. The general form of the
domain predicate for the function faboveisasfollows:
Df:A→Prop
···
dp:(Γp)(Dfp1)→···→(Dfpn)→(Dfp)
···
1Equations with a case-expression on their right-hand side can give raise to sev-
eral constructors. See [6] for a more detailed explanation on how to handle these
equations.
Computation by Prophecy 73
where Γpis a context local to the equation, comprising the variables that occur
in p.
For our example we have
DF:N→Prop
d0:(DF0)
d1:(DF(g0)) →(DF1)
dS:(n:N)(DF(gn)) →(DF(g(Sn))) →(DF(S(Sn)))
The type-theoretic version of ftakes as an extra argument a proof that the
input satisfies the domain predicate, and it is defined by structural recursion on
this extra argument:
f:(y:A)(Dfy)→B
···
fp(dp−→
xh
1··· hn)=e[(fp
1h1),...,(fp
nhn)]
···
For the Ffunction we get:
F:(m:N)(DFm)→N
F0d0=a
F1(d1h)=b+c∗(F(g0) h)
F(S(Sn)) (dSnh
1h2)=F(gn)h1+F(g(Sn)) h2
For a complete description of this method and for more examples of its appli-
cation, the reader is referred to [6,4,7].
3 Views and Prophecies
We can consider an alternative representation of the domain Dfof fwhere we
ignore the elements of Aaltogether. Below we present the general form of this
new domain type which we call Af, and its corresponding instance for the F
function which we call NF.
Af:Typ e
···
cp:Γp→Af→···→Af
ntimes
→Af
···
NF:Typ e
c0:NF
c1:NF→NF
cS:N→NF→NF→NF
Using the terminology of [12], we call Afaview of the domain.
We now formalise fas a function on this new type:
f:Af→B
···
f(cp−→
xt
1··· tn)=e[(ft1),...,(ftn)]
···
74 A. Bove and V. Capretta
The variables in Γpare still required as parameters of the constructor cp,even
if they do not occur in the arguments of the branches, since they may occur in
the operator e.
For our example we obtain
F:NF→N
Fc0=a
F(c1h)=b+c∗(Fh)
F(cSnh
1h2)=Fh1+Fh2
We can see Afas the type of abstract inputs for the function f.Itiseasyto
obtain the elements in Affrom the elements of Asatisfying Df:
ıf:(y:A)(Dfy)→Af
···
ıfp(dp−→
xh
1···hn)=cp−→
x(ıfp1h1)···(ıfpnhn)
···
The reverse direction is however not possible, since elements in Afcan be con-
structed in an arbitrary way, completely disconnected from the behaviour of the
function f. The possible projections of those elements in Ahave absolutely no
reason to satisfy Df. Consider for example the element (cS10 c0c0) for our
example of the function F.
We now try to dualise the inductive Bove/Capretta method by using a
co-inductive approach. The idea is that, instead of defining an inductive char-
acterisation of the domain, we define a co-inductive characterisation of the
co-domain of the function:
CoInductive Bf:Typ e
···
be:Γe→Bf→···→Bf
ntimes →Bf
···
where Γeis the context comprising the variables occurring free in e. In principle,
Γecould coincide with Γp; however, some of the variables in the pattern pmay
not be needed for the computation of eand hence, they could be omitted in Γe2.
Observe that the definition of Bfis identical to that of Afexcept for the
contexts appearing in the equations of both definitions, and for the fact that it
is a co-inductive definition instead of an inductive one.
The co-inductive characterisation of the co-domain of Fis defined as
CoInductive NF:Typ e
f0:NF
f1:NF→NF
fS:NF→NF→NF.
2Actually, in some cases, not even all the variables that are free in eneed to be
included in Γe; for example, the Natural argument nis omitted from the constructor
fSin the definition of NF.
Computation by Prophecy 75
We now give a version of fthat has Bfas co-domain:
f:A→Bf
···
fp=be−→
x(fp1)···(fpn)
···
This definition is sound because the co-recursive calls (fp1),...,(fpn)are
guarded by the constructor be(see [11] for further reading on this issue).
We can see Bfasthetypeofabstract outputs in the same way we saw Afas
the type of abstract inputs. In a certain sense, the elements of Bfare a prediction
of the structure of the result. For this reason we will call them prophecies.
The version of Fusing a co-inductive co-domain is
F:N→NF
F0=f0
F1=f1(F(g0))
F(S(Sn)) = fS(F(gn)) (F(g(Sn)).
4 Evaluating the Prophecies
The relation between Bfand Bis not very clear: since the elements of Bfmay
represent infinite computations, they do not always correspond to elements of
B. Instead, we can find a correspondence between Bfand the type of partial
elements of Bdefined in [8] as:
CoInductive Bν:Typ e
return:B→Bν
step:Bν→Bν
Following [8], we use the notations bfor (return b)andx for (step x). The
definition above means that an element of Bνcan be either a finite sequence of
steps followed by the return of a value of B, or an infinite sequence of steps.
So Bνrepresents the partial elements of B.
Our goal is then to represent the program fin type theory as a function
with type A→Bν. To accomplish this, we need to define an evaluation oper-
ator evaluatef:Bf→Bν.NoticethatBfhas a tree structure, since elements
constructed by becorrespond to nodes of branching degree n, while Bνhas a
linear structure given by a sequence of steps. The problem consists in linearis-
ing a tree or, in computational terms, sequentialising a parallel computation. To
achieve this, we create a stack of calls and we execute them sequentially. Every
call, when evaluated, can in turn generate new calls that are added to the stack.
The stack is represented by a vector. The empty vector is denoted by .We
use the notation x1,...,x
n;−→
vto denote the vector whose first nelements are
x1,...,x
nand whose elements from the (n+1)th on are given by the vector −→
v.
In the case where −→
vis the empty vector, we simply write x1,...,x
n.Inwhat
follows, Akrepresents the type of vectors of elements in Awith length k.
76 A. Bove and V. Capretta
The evaluation operator also has an extra parameter: a function that will
compute the final result from the results of the recursive calls on the elements
in the stack. This is similar to continuation-passing programming [13].
The co-recursive evaluation function θf, defined below, performs the sequen-
tialisation we just mentioned. The function is defined by cases on the length of
the vector and, when the vector is not empty, by cases on its first element.
θf:(k:N)(Bf)k→(Bk→B)→Bν
θf0h=h
···
θf(Sk)(be−→
xy1···yn); −→
vh=(θf(n+k)y1,...,y
n;−→
vh)
where hz1,...,z
n;−→
u=he[z1,...,z
n]; −→
u
···
Notice that the recursive call in the function θfare guarded by the constructor
, hence this is a valid co-fixpoint definition.
In our running example for the function Fwe obtain:
θF:(k:N)(NF)k→(Nk→N)→Nν
θF0h=h
θF(Sk)f0;−→
vh=(θFk−→
vh
)
where h−→
u=ha;−→
u
θF(Sk)(f1y); −→
vh=(θF(Sk)y;−→
vh)
where hz;−→
u=h(b+c∗z); −→
u
θF(Sk)(fSy1y2); −→
vh=(θF(2 + k)y1,y
2;−→
vh)
where hz1,z
2;−→
u=h(z1+z2); −→
u
The evaluation function, both in its general form and its instantiation for our
example, is defined as follows:
evaluatef:Bf→Bν
evaluatefy=θf1y(λz.z)evaluateF:NF→Nν
evaluateFy=θF1y(λz.z)
where λz.z denotes the function giving the only element of a vector of length
one.
Finally, we define the desired functions fand F:
f:A→Bν
fx=evaluatef(fx)F:N→Nν
Fn=evaluateF(Fn).
5 Validity of the Prophecy Method
We want to prove that the formal version of the function fdefined with the
prophecy method is a correct implementation of the informal recursive function.
Specifically, we want to prove the validity of the equations defining the function.
Remember that fmay return an element consisting of infinite computation
steps when applied to certain inputs. The inductive relation (defined in [8])
Computation by Prophecy 77
Value :Aν→A→Prop, for which we use the notation ( ↓), characterises ter-
minating computations. The expression (x↓a) states that the element xof Aν
converges to the value ain A. Its inductive definition has two rules:
a↓a
x↓a
x↓a.
We now formulate the recursive equations in terms of ( ↓) and we prove
that our implementation of the function satisfies them.
For each non-recursive equation fp=ain the informal definition of f,where
amay contain occurrences of the variables in Γbut no recursive calls to f,we
would like to show that the formal version of fsatisfies
∀−→
x:Γ, f p ↓a;
where −→
xare the variables defined in the context Γ, and for each recursive
equation of the form fp=e[(fp
1),...,(fp
n)] in the informal definition of f,
we would like to show that its formalisation is such that
∀−→
x:Γ, ∀r1,...,r
n:B,(fp
1)↓r1→···→(fp
n)↓rn→(fp)↓e[r1,...,r
n].
For our example function F, we want to prove the following three statements
(F0) ↓a,
∀m:N,(F(g0)) ↓m→(F1) ↓(b+c∗m),
∀n, m1,m
2:N,(F(gn)) ↓m1→(F(g(Sn))) ↓m2→
(F(S(Sn)))) ↓(m1+m2).
On the road to proving these results, let us consider more closely the meaning
of prophecies. A prophecy can be seen as the tree representation of the compu-
tation of the result of an expression. That is, it would be the computation trace,
if parallel evaluation were allowed. For example the prophecy
be−→
xy1···yn
specifies a parallel computation in which we first evaluate the subtrees y1,...,y
n
and, if all these computations terminate giving r1,...,r
nas result, respectively,
then we obtain the output by computing the expression e[r1,...,r
n].
Recall that, since types of partial elements like Bνrepresent computations in
a sequential model, we could not directly define the evaluation of a prophecy fol-
lowing the above intuition, but we needed to use the sequentialising operator θf.
We can characterise the behaviour of (θfk−→
vh) as follows:
(evaluatefvi) converges for every prophecy viin the vector −→
v:(Bf)k
if and only if (θfk−→
vh) converges; moreover, in case they converge, if
zi:Bis the value of (evaluatefvi)for0ik,then(hz1,...,z
k)is
the value of (θfk−→
vh).
78 A. Bove and V. Capretta
The characterisation of θfis described in the following lemma, where the
inductive relation (−→
v−→
u)expressesthat(evaluatefvi)↓uifor 0 ik,
where viis the ith element of −→
v:(Bf)kand uiis the ith element of −→
u:Bk.
Lemma 1
∀k:N,∀−→
v:(Bf)k,∀h:Bk→B, ∀b:B,
(θfk−→
vh)↓b←→ ∃−→
u:Bk,(−→
v−→
u)∧(h−→
u=b).
In order to prove Lemma 1 we define a weight on prophecies and vectors of
prophecies. Intuitively, the weight of a finite prophecy indicates the size of the
prophecy. The weight of a prophecy, when defined, must be a positive natural
number. Moreover, the weight of a tree-structured prophecy ywill only be defined
if the weights of all its children are defined. In addition, the weight of yhas to
be strictly greater than the sum of the weights of its children.
Since prophecies need not be well-founded trees, it is not possible to define
their weights by a total function. Instead, the weight of a prophecy is defined
as an inductive relation Wght :Bf→N→Prop with a constructor for each
constructor in the set of prophecies. For each constant constructor b:Bf,there
is a weight constructor of the form
wghtb:Wght b 1,
and for each non-constant constructor be:Γe→
ntimes
Bf→···→Bf→Bf,thereis
a weight constructor of the form
−→
x:Γeh1:Wght y1w1··· hn:Wght ynwn
wghtbe−→
xh1···hn:Wght (be−→
xy1···yn)(S(w1+···+wn)).
The weight of a vector of prophecies is the sum of the weights of its elements
plus its length, and it is given by an inductive relation
Weight :(k:N)(Bf)k→N→Prop defined as follows:
weight0:Weight 0 0
hy:Wght yw
yhv:Weight k−→
vw
v
weightSkh
yhv:Weight (Sk)y;−→
v(S(wy+wv)).
The statement of Lemma 1 can now be restrained to those vectors of prophe-
cies that have a weight. This makes it easier to prove the lemma by applying
course-of-value induction on the weight of the vector. Later, in lemmas 3 and 5,
we show that the restriction can be relaxed because all converging prophecies
have a weight.
Lemma 2
∀w:N,∀k:N,∀−→
v:(Bf)k,Weight k−→
vw→
∀h:Bk→B,∀b:B, (θfk−→
vh)↓b←→ ∃−→
u:Bk,(−→
v−→
u)∧(h−→
u=b).
Computation by Prophecy 79
Proof. By course-of-value induction on the weight wand cases on k. Recall that
the value of kdetermines the structure of the vector v.Whenvis not empty, we
also perform cases on its first element.
If k=0,then−→
v=. By definition of θf,wehave(θf0h)=h
and, therefore, it must be that b=(h)and−→
u=. Hence, the statement is
true.
If k=(Sk)then−→
v=y;−→
v. We now perform case analysis on y.
Let ybe a leaf. We know that the vector −→
vmust have a weight wand
moreover, wmust be strictly smaller than w,w<w. Both directions of the
lemma can now be easily proved by induction hypothesis on the weight w,and
by definition of the functions θfand evaluatef.
Let yhave a tree structure, that is, y=(be−→
xy1···yn). Given h, by definition
of θfwe get
θf(Sk)(be−→
xy1···yn); −→
vh=(θf(n+k)y1,...,y
n;−→
vh)
with (hz1,...,z
n;−→
u)=he[z1,...,z
n]; −→
u. Hence, for any given b,wehave
the equivalence
(θf(Sk)−→
vh)↓b←→ (θf(n+k)y1,...,y
n;−→
vh)↓b. (1)
The new vector of prophecies has a smaller weight than the original one, since
we replaced the first element in the vector by all its children. That is, there is a
weight wsuch that (Weight (n+k)y1,...,y
n;−→
vw)andw<w. Therefore
we can apply the induction hypothesis to w,h
and band obtain that
(θf(n+k)y1,...,y
n;−→
vh)↓b←→
∃z1,...,z
n;−→
u:Bn+k,(y1,...,y
n;−→
vz1,...,z
n;−→
u)∧
(hz1,...,z
n;−→
u=b).
(2)
In addition, the weight of y1,...,y
nis strictly smaller than the weight of the
vector −→
v, so we can apply the inductive hypothesis again with the continuation
h=λz1,...,z
n.e[z1,...,z
n]toobtain
∀b:B, (θfny1,...,y
n(λz1,...,z
n.e[z1,...,z
n])) ↓b←→
∃−→
z:Bn,(y1,...,y
n−→
z)∧((λz1,...,z
n.e[z1,...,z
n]) −→
z=b).
(3)
Now we prove the main statement.
In the direction from left to right, let us assume (θf(Sk)−→
vh)↓b. By the
equivalence in (1), we have that (θf(n+k)y1,...,y
n;−→
vh)↓b. Now, by
the instantiated induction hypothesis in (2), we know that there exists a vector
z1,...,z
n;−→
uwith the stated properties. In particular, (evaluatefyi)↓zifor
0in, and hence y1,...,y
nz1,...,z
n.
Let z=e[z1···zn]; we claim that z;−→
uis the vector satisfying the conclusion
of the the lemma. We need to prove that
(y;−→
vz;−→
u)∧(hz;−→
u=b),
80 A. Bove and V. Capretta
which amounts to proving that (evaluatefy)↓z, since the rest follows from the
equivalence in (2). By definition of evaluatef, we need to prove that
(θf1(be−→
xy
1···yn)(λz.z)) ↓e[z1···zn].
By unfolding the definition of θf, we obtain that this statement is equivalent to
the following:
(θfny1,...,y
n(λz1,...,z
n.e[z1,...,z
n])) ↓e[z1···zn].(4)
We now instantiate (3) with b=e[z1···zn], and we apply the right-to-left
direction of the resulting equivalence with the vector z1,...,z
nand the corre-
sponding proofs of the needed hypotheses. We obtain then a proof of the claim
in (4).
In the direction from right to left, assume that
∃z;−→
u:Bk,(y;−→
vz;−→
u)∧(hz;−→
u=b).
Then (evaluatefy)↓zand, since y=(be−→
xy
1···yn), by the definitions of
evaluatefand θf, we can apply the left-to-right direction of (3) with b=z.Thus,
there exists a vector z1,...,z
nsuch that (evaluatefyi)↓zifor 0 in,and
e[z1···zn]=z.
We can now use the right-to-left direction of (2) with the vector
z1,...,z
n;−→
uand the corresponding proofs of the needed hypotheses.
Finally, the equivalence in (1) allows us to conclude that
(θf(Sk)y;−→
vh)↓b.
In the next three lemmas, we show that all converging prophecies have a weight.
This allows us to eliminate the weight constraint in Lemma 2, which in turn,
easily allows us to obtain a proof of Lemma 1.
Lemma 3
∀k:N,∀−→
v:(Bf)k,∀h:Bk→B, ∀b:B,
(θfk−→
vh↓b)→∃w, Weight k−→
vw.
Proof. By induction on the structure of the proof of (θfk−→
vh)↓b,andby
cases on the vector and, when the vector is not empty, on its first element.
Lemma 4
∀y:Bf,∀b:B,(evaluatefy)↓b→∃w, Wght yw.
Proof. By definition of the operator evaluatefand Lemma 3.
Lemma 5
∀k:N,∀−→
v:(Bf)k,∀−→
u:(B)k,(−→
v−→
u)→∃w, Weight k−→
vw.
Computation by Prophecy 81
Proof. By induction on k, using Lemma 4 on each of the elements in the vec-
tor −→
v.
Finally, we are in the position of proving the validity of the equations defining
the function f. Proving the validity of non-recursive equations is immediate: we
only need to reduce the functions fand then evaluatefto obtain the desired
result. The validity of the recursive equations can be proved by using Lemma 1.
Theorem 1 (Validity of Recursive Equations)
∀−→
x:Γ, ∀r1,...,r
n:B,(fp
1)↓r1→···→(fp
n)↓rn→(fp)↓e[r1,...,r
n].
Proof. Assume that (fp
i)↓ri,for1in. By definition of fthis means that
evaluatef(fpi)↓ri. Unfolding definitions, we have that:
fp=evaluatef(fp)
=θf1(fp)(λz.z)
=θf1be−→
x(fp1)···(fpn)(λz.z)
=(θfn(fp1),···,(fpn)λz1,...,z
n.e[z1,...,z
n]).
The conclusion easily follows now by applying the second constructor of the
inductive relation ( ↓) and the right-to-left direction of Lemma 1.
In the specific case of the function F, Theorem 1 gives the validity of the equations
presented in page 77.
When reasoning about recursive functions, an inversion principle given by the
converse of Theorem 1 may be useful.
Theorem 2 (Inversion Principle for Recursive Equations)
∀−→
x:Γ, ∀b:B,(fp)↓b→
∃r1,...,r
n:B,(fp
1)↓r1∧···∧(fp
n)↓rn∧b=e[r1,...,r
n].
Proof. By the left-to-right direction of Lemma 1.
6 Conclusions
This article describes a new method to represent (partial) recursive functions in
type theory. It combines ideas from our previous work on the subject, namely,
the one characterising the inputs on which a function terminates by an induc-
tive (domain) predicate [6,4,7], and the one implementing recursive functions by
co-recursion on co-inductive types of partial elements [8].
Given the recursive equations for a computable function f:A→B, we define
a co-inductive set Bfof prophecies representing the traces of the computation
of the function. This set is the dual of the predicate defining the domain of
the function as described in [6]. It is easy to define a formal recursive function
f:A→Bfreturning prophecies as output. The type-theoretic version of the
82 A. Bove and V. Capretta
original function is then a function whose co-domain is the set Bνof partial
elements as studied in [8]. This function is defined by linearising the prophecy
obtained from the formal recursive function f. The linearisation is done by an
operator θfwith two parameters: a stack of recursive calls and a continuation
function that will compute, when possible, the final result.
We prove that a function formalised in type theory with this new method
satisfies all the equations (recursive or not) of its informal version.
We illustrate the method on a toy example, a generalisation Fof the Fibonacci
function. The development for Fhas been fully formalised in the proof assistant
Coq [14,3]. In addition, we also performed a complete formalisation of the quick-
sort algorithm following this method, and of the proofs stating the validity of the
equations for the algorithm. The files of both formalisations are available on the
web at the address: http://www.cs.ru.nl/~venanzio/Coq/prophecy.html.
At the moment, the method has been tested just on simple recursive programs,
that is, not nested or mutually recursive. The formalisation of mutually recursive
functions usually presents no major problems in systems like Coq, but on the
other hand, nested functions are not trivial to formalise. Already our previous
work (using the domain predicates) on nested recursive functions [5] could not
directly be translated into Coq because the proof assistant lacks support for
inductive-recursive definitions, as described by Dybjer in [10].
As can be seen from the proofs, the method is general and can be adapted to
every simple recursive program. However, we have yet to formalise the mecha-
nisation process and therefore, the user must go through the tedious but trivial
process of adapting definitions and proofs. It would be desirable, in a future
stage, to fully automatise the definitions of the set of prophecies, of the function
θf, and the related proofs from the set of (recursive) equations given by the user.
As mentioned before, this technique has several advantages over the method
we have previously developed via a special-purpose accessibility (domain) predi-
cate [6,4,7]; namely, there is no need of extra logical arguments in the definition
of the recursive function; the function can be applied to any element in its do-
main, regardless of termination properties; we obtain a type of partial recursive
functions between any two given types; and composition of recursive functions
can be easily defined through the usual composition of monadic function (see [8]
for further reading on this point).
References
1. Balaa, A., Bertot, Y.: Fonctions r´ecursives g´en´erales par it´eration en th´eorie des
types. Journ´ees Francophones des Langages Applicatifs - JFLA02, INRIA (January
2002)
2. Barthe, G., Courtieu, P.: Efficient reasoning about executable specifications in Coq.
In: Carre˜no, V.A., Mu˜noz, C.A., Tahar, S. (eds.) TPHOLs 2002. LNCS, vol. 2410,
pp. 20–23. Springer, Heidelberg (2002)
3. Bertot, Y., Cast´eran, P.: Interactive Theorem Proving and Program Development.
Coq’Art: The Calculus of Inductive Constructions. Springer, Berlin Heidelberg
(2004)
Computation by Prophecy 83
4. Bove, A.: General recursion in type theory. In: Geuvers, H., Wiedijk, F. (eds.)
TYPES 2002. LNCS, vol. 2646, pp. 39–58. Springer, Heidelberg (2003)
5. Bove, A., Capretta, V.: Nested general recursion and partiality in type theory. In:
Boulton, R.J., Jackson, P.B. (eds.) TPHOLs 2001. LNCS, vol. 2152, pp. 121–135.
Springer, Heidelberg (2001)
6. Bove, A., Capretta, V.: Modelling general recursion in type theory. Mathematical
Structures in Computer Science 15(4), 671–708 (2005)
7. Bove, A., Capretta, V.: Recursive functions with higher order domains. In: Urzy-
czyn, P. (ed.) TLCA 2005. LNCS, vol. 3461, pp. 116–130. Springer, Heidelberg
(2005)
8. Capretta, V.: General recursion via coinductive types. Logical Methods in Com-
puter Science 1(2), 1–18 (2005)
9. Capretta, V., Uustalu, T., Vene, V.: Recursive coalgebras from comonads. Infor-
mation and Computation 204(4), 437–468 (2006)
10. Dybjer, P.: A general formulation of simultaneous inductive-recursive definitions
in type theory. Journal of Symbolic Logic, vol. 65(2) (2000)
11. Gim´enez, E.: Codifying guarded definitions with recursive schemes. In: Smith, J.,
Dybjer, P., Nordstr¨om, B. (eds.) TYPES 1994. LNCS, vol. 996, pp. 39–59. Springer,
Heidelberg (1995)
12. McBride, C., McKinna, J.: The view from the left. Journal of Functional Program-
ming 14(1), 69–111 (2004)
13. Reynolds, J.C.: The discoveries of continuations. Lisp. and Symbolic Computa-
tion 6(3–4), 233–248 (1993)
14. The Coq Development Team. LogiCal Project. The Coq Proof Assistant. Reference
Manual. Version 8. INRIA (2004) Available at the web page
http://pauillac.inria.fr/coq/coq-eng.html