Slogan: Computation is successive approximation
Let us explore what properties domains (sets of data values) and functions on those domains must have to support recursive defintions. In the detour in Lecture 6, we informally showed how to construct the fixed-point of a function mapping sets to sets. In this lecture, we study this issue more rigorously in a general setting. Why does this question matter? It shows the boundaries of what can be expressed computationally. Much of mathematics lies outside the reach of computation.
We begin by reviewing a standard defintion from discrete mathematics.
A partial order is a set D together with a relation <= (which we will read as "approximates") on D (a subset of D x D) with the following three properties:
Some examples include:
A partial order does not have enough structure to support the general solution of fixed point equations. We need to add the following restriction. A chain C in a partial order (D,<=) is a (possibly empty) denumerable sequence c1, c2, ..., cn, ... such that
c1 <= c2 <= ... <= cn <= ...An upper bound for a chain C in (D,<=) is an element d in D such that ci <= d for all ci in C. A partial order (D,<=) is complete iff every chain C has a least upper bound. (An upper bound c* for C is least if c* approximates every upper bound for C.) We typically abbreviate the term complete partial order as cpo. Note that chain can be empty, implying that every cpo has a least element. We call this least element "bottom" and typically denote it bot. As we will see, bot corresponds to divergence.
Of the three examples of partial orders given above, only the first one is complete. In the partial order of finite alphabetic strings, a chain of the form
"a" <= "aa" <= "aaa" <= ...has no upper bound, much less a least upper bound. Similarly, in the partial order (N,<=), the chain
0 <= 1 <= 2 <= ...has no upper bound. In essence, these spaces are missing the "limit" points of chains of approximations.
Consider the function definition written in Scheme:
(define fact (lambda (n) (if (zero? n) 1 (* n (fact (sub1 n))))))We can construct a functional corresonding to this function that maps an estimate for the meaning of
fact
into
a better estimate:
(define FACT (lambda (fact) (lambda (n) (if (zero? n) 1 (* n (fact (sub1 n))))))
Given the empty function, FACT
constructs the partial
function {(0,1)} (that diverges everywhere except for returning 1 when
the input is 0).
All computable functions including FACT
are monotonic: if x <= y
then FACT(x)
approximates FACT(y)
. Given this
property and the property
that FACT
is continuous (all computable functions are
continuous), we can deduce (by repeatedly appealing to the monotonicity
of FACT):
empty <= FACT(empty) <= ... FACT(...FACT(emtpy)) <= ...The preceding sequence is clearly a chain. Hence, it must have a least upper bound which we write
fix(FACT)
because it is
least fixed
fixed-point of the functional FACT
. This function
the meaning of fact
determined by
the recursive definition above.
In general, every computable function mapping a cpo D to D has
a least fixed-point. Hence, we can interpret any recursive
definition as the least fixed-point of the corresponding
function.
D = Zbot + (D -> D)where
Zbot
is the integers augmented by bot, +
means the standard union operation except bottom elements are coalesced,
and (D -> D)
means the set of all strict
continuous functions
mapping D
into D
. (An function f mapping
the cpos D1, D2, ... Dn
into the cpo D0
is strict iff f(d1,d2,...,dn) =
bot
if any di
= bot.)
This equation can
be interpreted as a recursive definition of the domain D. We can
solve this equation by constructing a functional on domains and
taking its least fixed-point. But a lot of technical machinery
must be developed. First we have to show that the set of domains
forms a cpo. Then we have show that the +
and
->
operations (functions) on domains are continuous.
This deeper inquiry into the semantics of LC is the subject matter
of Comp 511.
cork@cs.rice.edu/ (adapted from shriram@cs.rice.edu)