A short while ago, we had CCA 2024
at Swansea, which I attended mostly because it was local and my
supervisor was giving a talk. The first day had a session dedicated to
the topic of Weihrauch reducibility, during which it
occurred to me that the definition of Weihrauch reducibility looked
suspiciously similar to the definition of a dependent lens and
that some of the operators on Weihrauch degrees should just
be known constructions on polynomials. She agreed, telling
me that Weihrauch problems are the polynomials in the category of
partitioned assemblies over the PCA filtered by .
I've written this attempt to answer
the question: “What the hell does that even mean?”.
Warning, to read
this post you must be over 18 years old or accompanied by a trained
category theorist.
What is Weihrauch Reducibility?
Reducibility is a fundamental concept in computability and complexity
theory. A problem is reducible to a problem if a solution to
can be used to solve . In a fire, a practical minded engineer
might grab a fire extinguisher and put it out; a computer scientist
might instead give the fire extinguisher to the engineer, thus
reducing the problem to one with a known solution.
A simple type
of reduction is that is reducible to if there
is an algorithm that decides that may call out to as a
subroutine. Computer scientists have refined this reduction to allow
only polynomial many calls
to , or even
a single call to .
Today we are interested in the following definitions:
A represented space is a pair of a set and a
surjective partial function .
Let , , , be represented spaces and let , be partial
multi-valued functions. Then is Weihrauch reducible to ,
if there are computable partial functions such that for all with , and for all with
, .
The upshot of the definition of Weihrauch reducible is that you have a
“forward map” that converts inputs for to inputs for , you
solve your problem , then convert your output of to an
output of using a “backward map” . When using the backward
map, you also get to use the original input. This is summarised in the
diagram below.
If you’ve seen lenses or other bidirectional mathematical structures,
you get excited when you see things like this. However, as usual with
computer science, there is a bunch of plumbing required to make
everything fit, starting with a trip into realisability.
What is a PCA?
I will not be giving an in-depth treatment of Categorical
Realisability, but for an introduction to the topic, you can read
Tom
de Jong's notes from a course
that I had the pleasure of attending at
MGS this year.
A PCA, or Partial Combinatory Algebra if you're not into the whole
brevity thing, is a set of “combinators” and a partial operator
called “application”, , plus two special
combinators called and satisfying a few axioms. We will not
dwell on this, because we have a lot to get through, but these and
are the combinators you would get from a process called
bracket
abstraction in the untyped lambda calculus. They are “combinatorially
complete” which means any term built out of application, variables,
and elements of can be expressed solely through application and
and .
There are lots of examples of PCAs, from the trivial
to the not-so-trivial
untyped lambda calculus. We will skip Kleene's first model to his
second model .
What is Kleene's Second Model?
Kleene's Second model is the PCA that corresponds to Type 2
Computability, which is the setting for much of Computable Analysis in
general and Weihrauch Reducibility in particular. So, what is type 2
computability?
A partial function is type 2
computable if there is a Turing machine that given on its input tape, eventually writes all of to its
(write only) output tape, and diverges otherwise.
There are a few things to notice. First, we will usually
view these functions as sequences of
natural numbers. Second, we are taking the whole space of functions
as our input, which means that some of our inputs are not
computable; this is intentional. Finally, a consequence of this
definition is that our function is continuous, in that will be
written to the output tape after finite time after inspecting only a
finite prefix of the input.
To form a PCA, we want to take as our set of objects and
define a multiplication map. It's a little fiddly, e.g., see section 1.4.3
of van Oosten's book, but I will provide a short explanation based on
a nice answer on
mathoverflow.
Fix a function . We will instead view this
as a function , by
uncurrying and fixing an isomorphism .
The first step is to define a partial map by repeatedly running
on an input sequence , increasing each time,
until we get a non- answer . If this happens, return
it; if the loop never terminates or diverges on some input,
return . That is, we keep asking for more of until we
have enough for to compute the answer.
It turns out that every continuous partial function
is equal to such an for some .
Now we can define multiplication by , provided the right side is defined for all .
There is a (non-runnable) Haskell pseudo-implementation provided below for the people who prefer code to prose.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Finally, is the sub-PCA of where all elements
are recursive
What is the Category ?
Assemblies
Now that we understand PCAs, we can define the notions of assembly and tracking, then form a category from
assembly maps. The following definitions come straight from Tom's notes.
An assembly over a PCA is a set together with a
relation such that
for all , there exists at least one element with .
For assemblies and , we say that an element tracks a function if for all , , if , then is defined
and .
An assembly map from an assembly to an assembly is a
function that is tracked by some element.
The standard analogy is to think of as telling us
that is an implementation of in the PCA and that trackers
implement their respective functions in the PCA.
Assembly maps form a category , since the identity function can be
tracked by the element , and composition of
functions is tracked by composition of trackers in a suitable sense.
Again, I defer to Tom's notes in the desire to save space and time.
Specialising these notions to , we get that represented spaces
are the same thing as assemblies and an element that
tracks a function is a realiser for it.
However, the category just described would not be fully faithful to
the notion of Type 2 Computability if you just instantiated it on
either or . This is because, as mentioned earlier,
in Type 2 we want our computation to be performed by Turing machines,
but to allow the sequences on our input tapes to be arbitrary, and
hence possibly uncomputable. This suggests that the objects of our
category should be assemblies on , but that our trackers
should be required to come from the sub-assembly . This
would give us a category .
Partitioned Assemblies
The next important definition is that of a partitioned assembly. This
is simply an assembly where each element of the set is realised by a
unique element of the PCA.
In Computable Analysis, it is common to work with directly
rather than with represented sets. In this setting, you can think of
elements of as coding themselves one-to-one. I'm sure it's clear how to do it, but I will do it for completeness.
Given a problem , we set , and define a new problem
by .
Further, these problems are equivalent (Weihrauch reducible to
one another) by taking the identity function as the forward map and
the second projection as the backward map.
Finally, we can say that is the category of partitioned
assemblies over , where each map is tracked by an element of
. Hopefully you agree by now that this is an appropriate
category for handling Weihrauch reducibility, but there is one last
snag to deal with.
Weihrauch Problems are Bundles
The definition of reducibility above relates partial
multi-valued functions (a.k.a. problems) to each other.
However, the maps in our category are tracked functions,
so they are not a good fit. What gives?
Another way of viewing a problem is as a family
of sets where . In the language of dependent types, we might say there is a type
family indexed by and form a dependent sum . This type has a projection function,
which maps “answers” to the “instance” of the problem they solve.
Since we have defined it using dependent types, the projection map is
total and tracked, which means is an arrow in .
Such maps are known as bundles.
One final thing to note about is that it is not necessarily
surjective; specifically, its image is . It is typical in computable analysis
to assume that all problem instances have solutions, but everything I will say below also
works in the non-total case.
That's all very well and good but what about Lenses?
When I think of lenses, I normally think of the , the
category of polynomial functors, where
(dependent) lens is just another name for a natural transformation. However,
this category is defined in terms of rather than .
The good news is that Gambino & Kock worked out the theory of
polynomial functors back in 2010 for arbitrary locally cartesian closed
categories; the bad news is that is not locally
cartesian closed (only weakly so).
In the rest of this section, we will borrow enough of Gambino & Kock
to try and justify the “is a lens” claim.
Polynomials
A polynomial over a locally cartesian
closed category with a terminal object is a diagram in of shape:
The intent of this definition is to capture the concept of a -indexed
family of polynomials in -many variables. In the case of a single
polynomial in one variable, we can specialise this by taking , where is the terminal object. Thus, a polynomial is “just”
an arrow . More specifically, taking
the dependently typed view from earlier, a problem / polynomial
given by a type and its projection function
.
Polynomial Functors
In a locally cartesian closed category, we would then go on to define
a polynomial functor
as the composite
where is pullback along ,
is the “Dependent Sum” functor and is the
“Dependent Product” functor. The first adjunction is well-defined in any
category with pullbacks. The second adjunction, on the other hand, is only
defined in a locally cartesian-closed category. Since Pasm isn't an LCCC,
we will skip on and not worry about what all this means. Maybe another day…
Lenses
So we don't have an LCCC, but we do have pullbacks in and
this will turn out to be enough to define lenses. First, we will blithely
skip about ten pages further along in G&K's paper to this lovely theorem.
Every strong natural transformation between polynomial
functors is represented in an essentially unique way by a diagram like:
Now, this is something we can work with. This diagram expresses that
morphisms between polynomial functors have a vertical-cartesian
factorisation system. Again, we don't need to worry too much about
what that means here except to note that a cartesian natural
transformation is one whose naturality squares are all pullbacks.
Now, let's simplify the diagram using and viewing
problems , as bundles.
If we wanted to fill in this diagram in such that both
squares commute, what work would we need to do?
has pullbacks, so once we have an arrow we'd have the
bottom square. What would such a pullback look like? The construction
of pullbacks in is exactly like that in (except for
some additional information about realisers and arrows being tracked),
so we can take with the obvious
morphisms and .
Now that we know , we can determine what needs to be true of the
remaining arrow for the top square
to commute.
Let , , then , so for some . In
other words, , is a map .
I claim that these and are the same as those from
earlier but recast in the new language. First, since
we are working with partitioned assemblies, we take all the coding maps
to be the identity. Next, we view a problem
as a bundle
and recall that the image of is . Then saying that
a computable function takes to
is the same as saying that the lower half of
the diagram is a pullback square. Finally, the requirement that
implies that is the same as
saying that implies
. Looking only at the second
arguments, we see that this means we require a function
.
Finally, we can make the following definitions.
A Weihrauch problem P is an epimorphism arrow in . An Extended Weihrauch Problem in an arrow in
Given (extended) problems , in . Then f is
Weihrauch Reducible to , , if there exists arrows
,
such that the following diagram commutes:
Wrapping up
So, we've managed to give another definition of Weihrauch
Reducibility, but this note is already too long, so I'll have to leave
a few things on the table. First, I haven't argued that these form
a category of problems, of which the poset of Weihrauch degrees should
be the skeleton. Second, I never showed that various
operators on degrees correspond to familiar operators on polynomials.
Lastly, I should mention my supervisors's most recent
preprint, where she discusses the notion of extended Weihrauch reducibility.
Thanks must go, firstly, to my supervisor, Cécilia Pradic, for putting up with all the
questions necessary for me to understand this topic. I
should also thank the members of the Computable Analysis group at
Swansea (Arno Pauly, Manlio Valenti, Eike Neumann), for what little I
know about Weihrauch reducibility. I would have been in a bad place to
even start this writeup if I hadn't attended Tom de Jong's Categorical
Realisability course at MGS. Finally, thanks to the people I talked to
at
SPLV
that were interested, since otherwise I might never have bothered to
write it up.