https://wiki.haskell.org/api.php?action=feedcontributions&user=Michiexile&feedformat=atomHaskellWiki - User contributions [en]2024-03-28T15:40:55ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=User:Michiexile/MATH198&diff=36339User:Michiexile/MATH1982010-07-24T05:51:12Z<p>Michiexile: </p>
<hr />
<div>==Course overview==<br />
<br />
Page is the background material for the Fall 2009 lecture course MATH198[http://coursework.stanford.edu/homepage/F09/F09-MATH-198-01.html] on Category Theory and Functional Programming that I gave at Stanford University.<br />
<br />
Single unit course. 10 lectures. Each lecture is Wednesday 4.15-5.05 in 380F.<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 1]]<br />
** Category: Definition and examples.<br />
** Concrete categories.<br />
*** Set.<br />
*** Various categories capturing linear algebra.<br />
** Small categories.<br />
*** Partial orders.<br />
*** Monoids.<br />
*** Finite groups.<br />
** Haskell-Curry isomorphism.<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 2]]<br />
** Special morphisms<br />
*** Epimorphism.<br />
*** Monomorphism.<br />
*** Isomorphism.<br />
*** Endomorphism.<br />
*** Automorphism.<br />
** Special objects<br />
*** Initial. <br />
*** Terminal. <br />
*** Null.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 3]]<br />
** Functors.<br />
** Category of categories.<br />
** Natural transformations.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 4]]<br />
** Products, coproducts.<br />
** The power of dualization.<br />
** The algebra of datatypes<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 5]]<br />
** Limits, colimits.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 6]]<br />
** Equalizers, coequalizers.<br />
** Pushouts/pullbacks<br />
** Adjunctions.<br />
** Free and forgetful.<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 7]]<br />
** Monoid objects.<br />
** Monads.<br />
** Triples.<br />
** Kleisli category.<br />
** Monad factorization.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 8]]<br />
** Algebras over monads<br />
** Algebras over endofunctors<br />
** Initial algebras and recursion<br />
** Lambek's lemma<br />
<br />
* [[User:Michiexile/MATH198/Lecture 9]]<br />
** Catamorphisms<br />
** Anamorphisms<br />
** Hylomorphisms<br />
** Metamorphisms<br />
** Paramorphisms<br />
** Apomorphisms<br />
** Properties of adjunctions, examples of adjunctions<br />
<br />
* [[User:Michiexile/MATH198/Lecture 10]]<br />
** Power objects<br />
** Classifying objects<br />
** Topoi<br />
** Internal logic</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_2&diff=32219User:Michiexile/MATH198/Lecture 22009-12-07T06:10:53Z<p>Michiexile: </p>
<hr />
<div>This lecture covers material occurring in Awodey sections 2.1-2.4. <br />
<br />
===Morphisms and objects===<br />
<br />
Some morphisms and some objects are special enough to garner special names that we will use regularly.<br />
<br />
In morphisms, the important properties are<br />
* cancellability - the categorical notion corresponding to properties we use when solving, e.g., equations over <math>\mathbb N</math>:<br />
::<math>3x = 3y \Rightarrow x = y</math><br />
:See also Wikipedia [http://en.wikipedia.org/wiki/Cancellation_property], where the relevant definitions and some interesting keywords occur. The article is technical and terse, though.<br />
* existence of inverses - which is stronger than cancellability. If there are inverses around, this implies cancellability, by applying the inverse to remove the common factor. Cancellability, however, does not imply that inverses exist: we can cancel the 3 above, but this does not imply the existence of <math>1/3\in\mathbb N</math>.<br />
<br />
Thus, we'll talk about isomorphisms - which have two-sided inverses, monomorphisms and epimorphisms - which have cancellability properties, and split morphisms - which are mono's and epi's with correspodning one-sided inverses. We'll talk about what these concepts - defined in terms of equationsolving with arrows - apply to more familiar situations. And we'll talk about how the semantics of some of the more wellknown ideas in mathematics are captured by these notions.<br />
<br />
For objects, the properties are interesting in what happens to homsets with the special object as source or target. An empty homset is pretty boring, and a ''large'' homset is pretty boring. The real power, we find, is when ''all'' homsets with the specific source or target are singleton sets. This allows us to formulate the idea of a 0 in categorical terms, as well as capturing the roles of the empty set and of elements of sets - all using only arrows.<br />
<br />
===Isomorphisms===<br />
<br />
An arrow <math>f:A\to B</math> in a category <math>C</math> is an ''isomorphism'' if it has a twosided inverse <math>g</math>. In other words, we require the existence of a <math>g:B\to A</math> such that <math>fg=1_B</math> and <math>gf=1_A</math>. <br />
<br />
====In Set====<br />
<br />
In a category of sets with structure with morphisms given by functions that respect the set structure, isomorphism are bijections respecting the structure. In the category of sets, the isomorphisms are bijections.<br />
<br />
In wikipedia: [http://en.wikipedia.org/wiki/Bijection]<br />
<br />
====Representative subcategories====<br />
<br />
Very many mathematical properties and invariants are interesting because they hold for objects regardless of how, exactly, the object is built. As an example, most set theoretical properties are concerned with how large the set is, but not what the elements really are.<br />
<br />
If all we care about are our objects up to isomorphisms, and how they relate to each other - we might as well restrict ourselves to one object for each isomorphism class of objects.<br />
<br />
Doing this, we get a ''representative subcategory'': a subcategory such that every object of the supercategory is isomorphic to some object in the subcategory. <br />
<br />
The representative subcategory ends up being a more categorically interesting concept than the idea of a wide subcategory: it doesn't hit every object in the category, but it hits every object worth hitting in order to capture all the structure.<br />
<br />
'''Example''' The category of finite sets has a representative subcategory given by all sets <math>[n]=\{1,\ldots,n\}</math>.<br />
<br />
====Groupoids====<br />
<br />
A ''groupoid'' is a category where ''all'' morphisms are isomorphisms. The name originates in that a groupoid with one object is a bona fide group; so that groupoids are the closest equivalent, in one sense, of groups as categories.<br />
<br />
A very rich starting point is the wikipedia page [http://en.wikipedia.org/wiki/Groupoid]. In the categorical definition on this page, the difference to a category is in the existence and properties of the function inv.<br />
<br />
===Monomorphisms===<br />
<br />
We say that an arrow <math>f</math> is ''left cancellable'' if for any arrows <math>g_1,g_2</math> we can show <math>fg_1 = fg_2 \Rightarrow g_1=g_2</math>. In other words, it is left cancellable, if we can remove it from the far left of any equation involving arrows.<br />
<br />
We call a left cancellable arrow in a category a ''monomorphism''.<br />
<br />
====In Set====<br />
<br />
Left cancellability means that if, when we do first <math>g_1</math> and then <math>f</math> we get the same as when we do first <math>g_2</math> and then <math>f</math>, then we had equality already before we followed with <math>f</math>.<br />
<br />
In other words, when we work with functions on sets, <math>f</math> doesn't introduce relations that weren't already there. Anything non-equal before we apply <math>f</math> remains non-equal in the image. This, translated to formulae gives us the well-known form for ''injectivity'':<br />
::<math>x\neq y\Rightarrow f(x)\neq f(y)</math> or moving out the negations,<br />
::<math>f(x)=f(y) \Rightarrow x=y</math>.<br />
<br />
In Wikipedia: [http://en.wikipedia.org/wiki/Injective_function].<br />
<br />
====Subobjects====<br />
<br />
Consider the subset <math>\{1,2\}\subset\{1,2,3\}</math>. This is the image of an accordingly chosen injective map from any 2-element set into <math>\{1,2,3\}</math>. Thus, if we want to translate the idea of a subset into categorical language, it is not enough talking about monomorphisms, though the fact that inclusion is an injection indicates that we are on the right track. <br />
<br />
The trouble that remains is that we do not want to view <math>\{1,2\}</math> as different subsets when it occurs as an image of the 2-element set <math>\{1,2\}</math> or when it occurs as an image of the 2-element set <math>\{5,6\}</math>. So we need some way of figuring out how to catch these situations and parry for them.<br />
<br />
We'll say that a morphism <math>f</math> ''factors through'' a morphism <math>g</math> if there is some morphism <math>h</math> such that <math>f=gh</math>.<br />
<br />
We can also talk about a morphism <math>f:A\to C</math> factoring through an ''object'' <math>B</math> by requiring the existence of morphisms <math>g:A\to B, h:B\to C</math> that compose to <math>f</math>.<br />
<br />
Now, we can form an equivalence relation on monomorphisms into an object <math>A</math>, by saying <math>f\sim g</math> if <math>f</math> factors through <math>g</math> and <math>g</math> factors through <math>f</math>. The arrows implied by the factoring are inverse to each other, and the source objects of equivalent arrows are isomorphic.<br />
<br />
Equipped with this equivalence relation, we define a ''subobject'' of an object <math>A</math> to be an equivalence class of monomorphisms.<br />
<br />
Wikipedia has an accurate exposition [http://en.wikipedia.org/wiki/Subobject].<br />
<br />
===Epimorphisms===<br />
<br />
''Right cancellability'', by duality, is the implication<br />
:<math>g_1f = g_2f \Rightarrow g_1 = g_2</math><br />
The name, here comes from that we can remove the right cancellable <math>f</math> from the right of any equation it is involved in.<br />
<br />
A right cancellable arrow in a category is an ''epimorphism''.<br />
<br />
====In Set====<br />
<br />
For epimorphims the interpretation in set functions is that whatever <math>f</math> does, it doesn't hide any part of the things <math>g_1</math> and <math>g_2</math> do. So applying <math>f</math> first doesn't influence the total available scope <math>g_1</math> and <math>g_2</math> have.<br />
<br />
In Wikipedia: [http://en.wikipedia.org/wiki/Surjective_function].<br />
<br />
===More on factoring===<br />
<br />
In Set, and in many other categories, any morphism can be expressed by a factorization of the form <math>f=ip</math> where <math>i</math> is a monomorphism and <math>p</math> is an epimorphism. For instance, in Set, we know that a function is surjective onto its image, which in turn is a subset of the domain, giving a factorization into an epimorphism - the projection onto the image - followed by a monomorphism - the inclusion of the image into the domain.<br />
<br />
A generalization of this situation is sketched out on the Wikipedia page for Factorization systems [http://en.wikipedia.org/wiki/Factorization_system]. <br />
----<br />
<br />
Note that in Set, every morphisms that is both a mono and an epi is immediately an isomorphism. We shall see in the homework that the converse does not necessarily hold.<br />
<br />
===Initial and Terminal objects===<br />
<br />
An object <math>0</math> is ''initial'' if for every other object <math>C</math>, there is a unique morphism <math>0\to C</math>. Dually, an object <math>1</math> is ''terminal'' if there is a unique morphism <math>C\to 1</math>.<br />
<br />
First off, we note that the uniqueness above makes initial and terminal objects unique up to isomorphism whenever they exist: we shall perform the proof for one of the cases, the other is almost identical.<br />
<br />
'''Proposition''' Initial (terminal) objects are unique up to isomorphism.<br />
<br />
'''Proof''': Suppose <math>C</math> and <math>C'</math> are both initial (terminal). Then there is a unique arrow <math>C\to C'</math> and a unique arrow <math>C'\to C</math>. The compositions of these arrows are all endoarrows of one or the other. Since ''all'' arrows from (to) an initial (terminal) objects are unique, these compositions have to be the identity arrows. Hence the arrows we found between the two objects are isomorphisms. QED.<br />
<br />
* In Sets, the empty set is initial, and any singleton set is terminal.<br />
* In the category of Vector spaces, the single element vector space 0 is both initial and terminal. <br />
<br />
On Wikipedia, there is a terse definition, and a good range of examples and properties: [http://en.wikipedia.org/wiki/Initial_and_terminal_objects].<br />
<br />
Note that terminal objects are sometimes called ''final'', and are as such used in the formal logic specification of algebraic structures.<br />
<br />
====Zero objects====<br />
<br />
This last example is worth taking up in higher detail. We call an object in a category a ''zero object'' if it is simultaneously initial and terminal. <br />
<br />
Some categories exhibit a richness of structure similar to the category of vectorspaces: all kernels exist (nullspaces), homsets are themselves abelian groups (or even vectorspaces), et.c. With the correct amount of richness, the category is called an ''Abelian category'', and forms the basis for ''homological algebra'', where techniques from topology are introduced to study algebraic objects.<br />
<br />
One of the core requirements for an Abelian category is the existence of zero objects in it: if a category does have a zero object <math>0</math>, then for any <math>Hom(A,B)</math>, the composite <math>A\to 0\to B</math> is a uniquely determined member of the homset, and the addition on the homsets of an Abelian category has this particular morphism as its identity element.<br />
<br />
====Pointless sets and generalized elements====<br />
<br />
Arrows to initial objects and from terminal objects are interesting too - and as opposed to the arrows from initial and to the terminals, there is no guarantee for these arrows to be uniquely determined. Let us start with arrows <math>A\to 0</math> into initial objects.<br />
<br />
In the category of sets, such an arrow only exists if <math>A</math> is already the empty set.<br />
<br />
In the category of all monoids, with monoid homomorphisms, we have a zero object, so such an arrow is uniquely determined.<br />
<br />
For arrows <math>1\to A</math>, however, the situation is significantly more interesting. Let us start with the situation in Set. <math>1</math> is some singleton set, hence a function from <math>1</math> picks out one element as its image. Thus, at least in Set, we get an isomorphism of sets <math>A = Hom(1,A)</math>.<br />
<br />
As with so much else here, we build up a general definition by analogy to what we see happening in the category of sets. Thus, we shall say that a ''global element'', or a ''point'', or a ''constant'' of an object <math>A</math> in a category with terminal objects is a morphism <math>x:1\to A</math>.<br />
<br />
This allows us to talk about elements without requiring our objects to even be sets to begin with, and thus reduces everything to a matter of just morphisms. This approach is fruitful both in topology and in Haskell, and is sometimes called ''pointless''.<br />
<br />
The important point here is that we can replace ''function application'' <math>f(x)</math> by the already existing and studied ''function composition''. If a constant <math>x</math> is just a morphism <math>x:1\to A</math>, then the value <math>f(x)</math> is just the composition <math>f\circ x:1\to A\to B</math>. Note, also, that since <math>1</math> is terminal, it has exactly one point.<br />
<br />
In the idealized Haskell category, we have the same phenomenon for constants, but slightly disguised: a global constant is 0-ary function. Thus the type declaration<br />
<haskell><br />
x :: a<br />
</haskell><br />
can be understood as syntactic sugar for the type declaration<br />
<haskell><br />
x :: () -> a<br />
</haskell><br />
thus reducing everything to function types. <br />
<br />
----<br />
<br />
Similarly to the ''global'' elements, it may be useful to talk about ''variable elements'', by which we mean non-specified arrows <math>f:T\to A</math>. Allowing <math>T</math> to range over all objects, and <math>f</math> to range over all morphisms into <math>A</math>, we are able to recover some of the element-centered styles of arguments we are used to. We say that <math>f</math> is ''parametried over <math>T</math>''.<br />
<br />
Using this, it turns out that <math>f</math> is a monomorphism if for any variable elements <math>x,y:T\to A</math>, if <math>x\neq y</math> then <math>f\circ x\neq f\circ y</math>.<br />
<br />
===Internal and external hom===<br />
<br />
If <math>f:B\to C</math>, then <math>f</math> induces a set function <math>Hom(A,f):Hom(A,B)\to Hom(A,C)</math> through <math>Hom(A,f)(g) = f\circ g</math>. Similarly, it induces a set function <math>Hom(f,A):Hom(C,A)\to Hom(<br />
B,A)</math> through <math>Hom(f,A)(g) = g\circ f</math>.<br />
<br />
Using this, we have an occasionally enlightening <br />
<br />
'''Proposition''' An arrow <math>f:B\to C</math> is<br />
# a monomorphism if and only if <math>Hom(A,f)</math> is injective for every object <math>A</math>.<br />
# an epimorphism if and only if <math>Hom(f,A)</math> is injective for every object <math>A</math>.<br />
# a split monomorphism if and only if <math>Hom(f,A)</math> is surjective for every object <math>A</math>.<br />
# a split epimorphism if and only if <math>Hom(A,f)</math> is surjective for every object <math>A</math>.<br />
# an isomorphism if and only if any one of the following equivalent conditions hold:<br />
## it is both a split epi and a mono.<br />
## it is both an epi and a split mono.<br />
## <math>Hom(A,f)</math> is bijective for every <math>A</math>.<br />
## <math>Hom(f,A)</math> is bijective for every <math>A</math>.<br />
<br />
----<br />
<br />
For any <math>A,B</math> in a category, the homset is a ''set'' of morphisms between the objects. For many categories, though, homsets may end up being objects of that category as well. <br />
<br />
As an example, the set of all linear maps between two fixed vector spaces is itself a vector space.<br />
<br />
Alternatively, the function type <hask>a -> b</hask> is an actual Haskell type, and captures the morphisms of the idealized Haskell category.<br />
<br />
We shall return to this situation later, when we are better equipped to give a formal scaffolding to the idea of having elements in objects in a category act as morphisms. For now, we shall introduce the notations <math>[A\to B]</math> or <math>B^A</math> to denote the ''internal'' hom - where the morphisms between two objects live as an object of the category. This distinguishes <math>B^A</math> from <math>Hom(A,B)</math>.<br />
<br />
To gain a better understanding of the choice of notation, it is worth noting that <math>|Hom_{Set}(A,B)|=|B|^{|A|}</math>.<br />
<br />
===Homework===<br />
<br />
Passing mark requires at least 4 of 11.<br />
<br />
# Suppose <math>g,h</math> are two-sided inverses to <math>f</math>. Prove that <math>g=h</math>.<br />
# (requires some familiarity with analysis) There is a category with object <math>\mathbb R</math> (or even all smooth manifolds) and with morphisms smooth (infinitely differentiable) functions <math>f:\mathbb R\to\mathbb R</math>. Prove that being a bijection does not imply being an isomorphisms. Hint: What about <math>x\mapsto x^3?</math>. Wikipedia definition of smoothness: [http://en.wikipedia.org/wiki/Smooth_function]. Moral of the definition is that all derivatives and derivatives of derivatives, et.c. are everywhere finite and continuous.<br />
# (try to do this if you don't do 2) In the category of posets, with order-preserving maps as morphisms, show that not all bijective homomorphisms are isomorphisms. See the notes for [[User:Michiexile/MATH198/Lecture 1|Lecture 1]] for details on posets and order-preserving maps, as well as wikipedia links.<br />
# Consider the partially ordered set <math>P</math> as a category. Prove: every arrow is both monic and epic. Is every arrow thus an isomorphism?<br />
# What are the terminal and initial objects in a poset? Give an example each of a poset that has both, either and none. Give an example of a poset that has a zero object.<br />
# What are the terminal and initial objects in the category with objects graphs and morphisms graph homomorphisms? Definition of a graph and a graph homomorphism occurred in [[User:Michiexile/MATH198/Lecture 1|Lecture 1]].<br />
# Prove that if a category has one zero object, then all initial and all terminal objects are all isomorphic and they are all zero objects. <br />
# Prove that the composition of two monomorphisms is a monomorphism and that the composition of two epimorphisms is an epimorphism. If <math>g\circ f</math> is monic, do any of <math>g,f</math> have to be monic? If the composition is epic, do any of the factors have to be epic?<br />
# Verify that the equivalence relation used in defining subobjects really is an equivalence relation. Further verify that this fixes the motivating problem. <br />
# Describe a representative subcategory each of:<br />
#* The category of vectorspaces over the reals.<br />
#* The category formed by the preordered set of the integers <math>\mathbb Z</math> and the order relation <math>a\leq b</math> if <math>a|b</math>. Recall that a preordered set is a set <math>P</math> equipped with a relation <math>\leq</math> that fulfills transitivity and reflexivity, but not necessarily anti-symmetry.<br />
# * An arrow <math>f:A\to A</math> in a category <math>C</math> is an ''idempotent'' if <math>f\circ f = f</math>. We say that <math>f</math> is a ''split idempotent'' if there is some <math>g:A\to B, h:B\to A</math> such that <math>h\circ g=f</math> and <math>g\circ h=1_B</math>. Show that in Set, <math>f</math> is idempotent if and only if its image equals its set of fixed points. Show that every idempotent in Set is split. Give an example of a category with a non-split idempotent.</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=32079User:Michiexile/MATH198/Lecture 102009-12-02T18:21:17Z<p>Michiexile: </p>
<hr />
<div>This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional programming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that opens up for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. (Note that by admitting several universes, we arrive at a ''typed'' predicate logic, with basically no extra work.)<br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
We can now proceed to define all the familiar logic connectives one by one, using the topos setting. While doing this, we shall introduce the notation <math>t_A: A\to\Omega</math> for the morphism <math>t_A = A\to 1\to^{true}\Omega</math> that takes on the value ''true'' on all of A. We note that with this convention, <math>\chi_{A_0}</math>, the characteristic morphism of a subobject, is the arrow such that <math>\chi_{A_0}\circ i = t_{A_0}</math>.<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously.<br />
<br />
We may define <math>true\times true: 1\to\Omega\times\Omega</math>, a subobject of <math>\Omega\times\Omega</math>. Being a subobject, this has a characteristic arrow <math>\wedge:\Omega\times\Omega\to\Omega</math>, that we call the ''conjunction arrow''.<br />
<br />
Now, we may define <math>\chi_P\times\chi_Q:U\to\Omega\times\Omega</math> for subobjects <math>P,Q\subseteq U</math> - and we take their composition <math>\wedge\circ\chi_P\times\chi_Q</math> to be the characteristic arrow of the subobject <math>P\wedge Q</math>.<br />
<br />
And, indeed, this results in a topoidal version of intersection of subobjects.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1: \Omega_1\to\Omega\times\Omega</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v, w: U\to\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[U\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = (\Rightarrow)\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^U\subseteq U\times\Omega^U</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For elements <math>x\times h: 1\to U\times\Omega^U</math>, we write <math>x\in^U h</math> for <math>x\times h\in\in^U</math>. Yielding a subset of the product <math>U\times\Omega^U</math>, this is readily interpretable as a relation relating things in <math>U</math> with subsets of <math>U</math>, so that for any <math>x,h</math> we can answer whether <math>x\in^Uh</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>U</math>, the maximal subobject of <math>U</math> is <math>U</math> itself, embedded with <math>1_U</math> into itself. There is an arrow <math>\tau_U:1\to\Omega^U</math> represents this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_U:\Omega^U\to\Omega</math> that takes a given subobject of <math>U</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_R</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:[[Image:ToposFalsumDerivation.png]]<br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples: Sheaves, topology and time sheaves====<br />
<br />
The first interesting example of a topos is the category of (small enough) sets; in some sense clear already since we've been modelling our axioms and workflows pretty closely on the theory of sets.<br />
<br />
Generating logic and set theory in the topos of sets, we get a theory that captures several properties of ''intuitionistic logic''; such as the lack of Boolean negation, of exclusion of the third, and of double negation rules.<br />
<br />
For the more interesting examples, however, we shall introduce the concepts of ''topology'' and of ''sheaf'':<br />
<br />
'''Definition''' A (set-valued) ''presheaf'' on a category <math>C</math> is a contravariant functor <math>E: C^{op}\to Set</math>.<br />
<br />
Presheaves occur all over the place in geometry and topology - and occasionally in computer science too: There is a construction in which a functor <math>A\to Set</math> for a discrete small category <math>A</math> identified with its underlying set of objects as a set, corresponds to the data type of ''bags'' of elements from <math>A</math> - for <math>a\in A</math>, the image <math>F(a)</math> denotes the multiplicity of <math>a</math> in the bag.<br />
<br />
'''Theorem''' The category of all presheaves (with natural transformations as the morphisms) on a category <math>C</math> form a topos.<br />
<br />
'''Example''' Pick a category on the shape<br />
:[[Image:GraphsAsPresheaves.png]]<br />
A contravariant functor on this category is given by a pair of sets <math>G_0, G_1</math> and a pair of function <math>source, target: G_1\to G_0</math>. Identities are sent to identities.<br />
<br />
The category of presheaves on this category, thus, is the category of graphs. Thus graphs form a topos.<br />
<br />
The subobject classifier in the category of graphs is a graph with two nodes: in and out, and five arrows:<br />
:<math>in \to^{all} in</math><br />
:<math>in \to^{both} in</math><br />
:<math>in \to^{source} out</math><br />
:<math>out \to^{target} in</math><br />
:<math>out \to^{neither} out</math><br />
Now, given a subgraph <math>H \leq G</math>, we define a function <math>\chi_H:G\to\Omega</math> by sending nodes to in or out dependent on their membership. For an arrow <math>a</math>, we send it to all if the arrow is in <math>H</math>, and otherwise we send it to both/source/target/neither according to where its source and target reside.<br />
<br />
To really get into sheaves, though, we introduce more structure - specifically, we define what we mean by a ''topology'':<br />
<br />
'''Definition''' Suppose <math>P</math> is a partially ordered set. We call <math>P</math> a ''complete Heyting algebra'' if<br />
* There is a top element <math>1</math> such that <math>x\leq 1 \forall x\in P</math>.<br />
* Any two elements <math>x, y</math> have an infimum (greatest lower bound) <math>x\wedge y</math>.<br />
* Every subset <math>Q\subseteq P</math> has a supremum (least upper bound) <math>\bigvee_{p\in P} p</math>.<br />
* <math>x\wedge(\bigvee y_i) = \bigvee x\wedge y_i</math><br />
<br />
Note that for the partial order by inclusion of a family of subsets of a given set, being a complete Heyting algebra is the same as being a topology in the classical sense - you can take finite unions and any intersections of open sets and still get an open set. <br />
<br />
If <math>\{x_i\}</math> is a subset with supremum <math>x</math>, and <math>E</math> is a presheaf, we get functions <math>e_i:E(x)\to E(x_i)</math> from functoriality. We can summarize all these <math>e_i</math> into <math>e = \prod_i e_i: E(x)\to\prod_i E(x_i)</math>.<br />
<br />
Furthermore, functoriality gives us families of functions <math>c_{ij}: E(x_i)\to E(x_i\wedge x_j)</math> and <math>d_{ij}: E(x_j)\to E(x_i\wedge x_j)</math>. These can be collected into <math>c: \prod_i E(x_i)\to\prod_{ij}E(x_i\wedge x_j)</math> and <math>d:\prod_j E(x_j)\to\prod_{ij}E(x_i\wedge x_j)</math>.<br />
<br />
'''Definition''' A presheaf <math>E</math> on a Heyting algebra is called a ''sheaf'' if it satisfies:<br />
:<math>x = \bigvee x_i</math><br />
implies that <br />
:[[Image:SheafEqualizer.png]]<br />
is an equalizer. If you have seen sheaves before, you may recognize this as the covering axiom.<br />
<br />
In other words, <math>E</math> is a sheaf if whenever <math>x=\bigvee x_i</math> and <math>c(\alpha) = d(\alpha)</math>, then there is some <math>\bar\alpha</math> such that <math>\alpha = e(\bar\alpha)</math>.<br />
<br />
'''Theorem''' The category of sheaves on a Heyting algebra is a topos.<br />
<br />
For context, we can think of sheaves over Heyting algebras as sets in a logic with an expanded notion of truth. Our Heyting algebra is the collection of truth values, and the sheaves are the fuzzy sets with fuzziness introduced by the Heyting algebra.<br />
<br />
Recalling that subsets and predicates are viewed as the same thing, we can view the set <math>E(p)</math> as the part of the fuzzy set <math>E</math> that is at least <math>p</math> true.<br />
<br />
As it turns out, to really make sense of this approach, we realize that ''equality'' is a predicate as well - and thus can hold or not depending on the truth value we use.<br />
<br />
'''Definition''' Let <math>P</math> be a complete Heyting algebra. A ''<math>P</math>-valued set'' is a pair <math>(S,\sigma)</math> of a set <math>S</math> and a function <math>\sigma: S\to P</math>. A ''category of fuzzy sets'' is a category of <math>P</math>-valued sets. A morphism <math>f:(S,\sigma)\to(T,\tau)</math> of <math>P</math>-valued sets is a function <math>f:S\to T</math> such that <math>\tau\circ f = \sigma</math>.<br />
<br />
From these definitions emerges a fuzzy set theory where all components of it being a kind of set theory emerges from the topoidal approach above. Thus, say, subsets in a fuzzy sense are just monics, thus are injective on the set part, and such that the valuation, on the image of the injection, increases from the previous valuation: <math>(T,\tau)\subseteq(S,\sigma)</math> if <math>T\subseteq S</math> and <math>\sigma|_T = \tau</math>.<br />
<br />
To get to topoi, though, there are a few matters we need to consider. First, we may well have several versions of the empty set - either a bona fide empty set, or just a set where every element is never actually there. This issue is minor. Much more significant though, is that while we can easily make <math>(S,\sigma)</math> give rise to a presheaf, by defining<br />
:<math>E(x) = \{s\in S: \sigma(s)\geq x\}</math><br />
this definition will not yield a sheaf. The reason for this boils down to <math>E(0) = S \neq 1</math>. We can fix this, though, by adjoining another element - <math>\bot</math> - to <math>P</math> giving <math>P^+</math>. The new element <math>\bot</math> is imbued with two properties: it is smaller, in <math>P^+</math>, than any other element, and it is mapped, by <math>E</math> to <math>1</math>.<br />
<br />
'''Theorem''' The construction above gives a fuzzy set <math>(S,\sigma)</math> the structure of a sheaf on the augmented Heyting algebra.<br />
<br />
'''Corollary''' The category of fuzzy sets for a Heyting algebra <math>P</math> forms a topos.<br />
<br />
'''Final note''' While this construction allows us to make ''membership'' a fuzzy concept, we're not really done fuzzy-izing sets. There are two fundamental predicates on sets: equality and membership. While fuzzy set theory, classically, only allows us to make one of these fuzzy, topos theory allows us - rather easily - to make both these predicates fuzzy. Not only that, but membership reduces - with the power object construction - to equality testing, by which the fuzzy set theory ends up somewhat inconsistent in its treatment of the predicates.<br />
<br />
===Literature===<br />
<br />
At this point, I would warmly recommend the interested reader to pick up one, or more, of:<br />
* Steve Awodey: Category Theory<br />
* Michael Barr & Charles Wells: Categories for Computing Science<br />
* Colin McLarty: Elementary Categories, Elementary Toposes<br />
<br />
or for more chewy books<br />
* Peter T. Johnstone: Sketches of an Elephant: a Topos Theory compendium<br />
* Michael Barr & Charles Wells: Toposes, Triples and Theories<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# Prove the relations showing that <math>\leq_1</math> is indeed a partial order on <math>[U\to\Omega]</math>.<br />
# Prove the universal quantifier theorem.<br />
# The ''extension'' of a formula <math>\phi</math> over a list of variables <math>x</math> is the sub-object of the product of domains <math>A_1\times\dots\times A_n</math> for the variables <math>x_1,\dots,x_n=x</math> classified by the interpretation of <math>\phi</math> as a morphism <math>A_1\times\dots\times A_n\to\Omega</math>. A formula is ''true'' if it classifies the entire product. A ''sequent'', written <math>\Gamma:\phi</math> is the statement that using the set of formulae <math>\Gamma</math> we may prove <math>\phi</math>, or in other words that the intersection of the extensions of the formulae in <math>\Gamma</math> is contained in the extension of <math>\phi</math>. If a sequent <math>\Gamma:\phi</math> is true, we say that <math>\Gamma</math> ''entails'' <math>\phi</math>. (some of the questions below are almost embarrassingly immediate from the definitions given above. I include them anyway, so that a ''catalogue'' of sorts of topoidal logic inferences is included here)<br />
## Prove the following entailments:<br />
### Trivial sequent: <math>\phi:\phi</math><br />
### True: <math>:true</math> (note that true classifies the entire object)<br />
### False: <math>false:\phi</math> (note that false classifies the global minimum in thepreorder of subobjects)<br />
## Prove the following inference rules:<br />
### Implication: <math>\Gamma,\phi:\psi</math> is equivalent to <math>\Gamma:\phi\Rightarrow\psi</math>.<br />
### Thinning: <math>\Gamma:\phi</math> implies <math>\Gamma,\psi:\phi</math><br />
### Cut: <math>\Gamma,\psi:\phi</math> and <math>\Gamma:\psi</math> imply <math>\Gamma:\phi</math> if every variable free in <math>\psi</math> is free in <math>\Gamma</math> or in <math>\phi</math>.<br />
### Negation: <math>\Gamma, \phi: false</math> is equivalent (implications both ways) to <math>\Gamma: \neg\phi</math>.<br />
### Conjunction: <math>\Gamma:\phi</math> and <math>\Gamma:\psi</math> together are equivalent to <math>\Gamma:\phi\wedge\psi</math>.<br />
### Disjunction: <math>\Gamma,\phi:\theta</math> and <math>\Gamma,\psi:\theta</math> together imply <math>\Gamma, \phi\vee\psi: \theta</math>.<br />
### Universal: <math>\Gamma:\phi</math> is equivalent to <math>\Gamma:\forall x.\phi</math> if <math>x</math> is not free in <math>\Gamma</math>.<br />
### Existential: <math>\Gamma,\phi: \psi</math> is equivalent to <math>\Gamma,\exists x.\phi:\psi</math> if <math>x</math> is not free in <math>\Gamma</math> or <math>\psi</math>.<br />
### Equality: <math>:q=q</math>.<br />
### Biconditional: <math>(v\Rightarrow w)\wedge(w\Rightarrow v):v=w</math>. We usually write <math>v\Leftrightarrow w</math> for <math>v=w</math> if <math>v,w:A\to\Omega</math>.<br />
### Product: <math>p_1u = p_1u', p_2u = p_2u' : u = u'</math> for <math>u,u'\in A\times B</math>.<br />
### Product revisited: <math>:(p_1(s\times s')=s)\wedge(p_2(s\times s')=s')</math>.<br />
### Extensionality: <math>\forall x\in A. f(x) = g(x) : f = g</math> for <math>f,g\in[A\to B]</math>.<br />
### Comprehension: <math>(\lambda x\in A. s)x = s</math> for <math>x\in A</math>.<br />
## Prove the following results from the above entailments and inferences -- or directly from the topoidal logic mindset:<br />
### <math>:\neg(\phi\wedge\neg\phi)</math>.<br />
### <math>:\phi\Rightarrow\neg\neg\phi</math>.<br />
### <math>:\neg(\phi\vee\psi)\Rightarrow(\neg\phi\wedge\neg\psi)</math>.<br />
### <math>:(\neg\phi\wedge\neg\psi)\Rightarrow\neg(\phi\wedge\psi)</math>.<br />
### <math>:(\neg\phi\vee\neg\psi)\Rightarrow\neg(\phi\vee\psi)</math>.<br />
### <math>\phi\wedge(\theta\vee\psi)</math> is equivalent to <math>(\phi\wedge\theta)\vee(\phi\wedge\psi)</math>.<br />
### <math>\forall x.\neg\phi</math> is equivalent to <math>\neg\exists x.\phi</math>.<br />
### <math>\exists x\phi\Rightarrow\neg\forall x.\neg\phi</math>.<br />
### <math>\exists x\neg\phi\Rightarrow\neg\forall x.\phi</math>.<br />
### <math>\forall x\phi\Rightarrow\neg\exists x.\neg\phi</math>.<br />
### <math>\phi:\psi</math> implies <math>\neg\psi:\neg\phi</math>.<br />
### <math>\phi:\psi\Rightarrow\phi</math>.<br />
### <math>\phi\Rightarrow\not\phi:\not\phi</math>.<br />
### <math>\not\phi\vee\psi:\phi\Rightarrow\psi</math> (but not the converse!).<br />
### <math>\neg\neg\neg\phi</math> is equivalent to <math>\neg\phi</math>.<br />
### <math>(\phi\wedge\psi)\Rightarrow\theta</math> is equivalent to <math>\phi\Rightarrow(\psi\Rightarrow\theta)</math> (currying!).<br />
## Using the Boolean negation rule: <math>\Gamma,\neg\phi:false</math> is equivalent to <math>\Gamma:\phi</math>, prove the following additional results:<br />
### <math>\neg\neg\phi:\phi</math>.<br />
### <math>:\phi\vee\neg\phi</math>.<br />
## Show that either of the three rules above, together with the original negation rule, implies the Boolean negation rule.<br />
### The converses of the three existential/universal/negation implications above.<br />
## The restrictions introduced for the cut rule above block the deduction of an entailment <math>:\forall x.\phi\Rightarrow\exists x.\phi</math>. The issue at hand is that <math>A</math> might not actually have members; so choosing one is not a sound move. Show that this entailment can be deduced from the premise <math>\exists x\in A. x=x</math>.<br />
## Show that if we extend our ruleset by the quantifier negation rule <math>\forall x\Leftrightarrow \neg\exists x.\neg</math>, then we can derive the entailment <math>:\forall w: w=t \vee w = false</math>. From this derive <math>:\phi\vee\neg\phi</math> and hence conclude that this extension gets us Boolean logic again.<br />
# A ''topology'' on a topos <math>E</math> is an arrow <math>j:\Omega\to\Omega</math> such that <math>j\circ true=true</math>, <math>j\circ j=j<math> and <math>j\circ\wedge = \wedge\circ j\times j</math>. For a subobject <math>S\subseteq A</math> with characteristic arrow <math>\chi_S:A\to\Omega</math>, we define its <math>j</math>-closure as the subobject <math>\bar S\subseteq A</math> classified by <math>j\circ\chi_S</math>.<br />
## Prove:<br />
### <math>S\subseteq\bar S</math>.<br />
### <math>\bar S = \bar{\bar S}</math>.<br />
### <math>\bar{S\cap T} = \bar S\cap\bar T</math>.<br />
### <math>S\subseteq T</math> implies <math>\bar S\subseteq\bar T</math>.<br />
### <math>\bar{f^{-1}(S)} = f^{-1}(\bar S)</math>.<br />
## We define <math>S</math> to be <math>j</math>-closed if <math>S=\bar S</math>. It is <math>j</math>-dense if <math>\bar S=A</math>. These terms are chosen due to correspondences to classical pointset topology for the topos of sheaves over some space. For a logical standpoint, it is more helpful to look at <math>j</math> as a modality operator: "''it is <math>j</math>-locally true that''" Given any <math>u:1\to\Omega</math>, prove that the following are topologies:<br />
### <math>(u\to -): \Omega\to\Omega</math> (the ''open topology'', where such a <math>u</math> in a sheaf topos ends up corresponding to an open subset of the underlying space, and the formulae picked out are true on at least all of that subset).<br />
### <math>u\vee -): \Omega\to\Omega</math> (the closed topology, where a formula is true if its disjunction with <math>u</math> is true -- corresponding to formulae holding over at least the closed set complementing the subset picked out)<br />
### <math>\neg\neg: \Omega\to\Omega</math>. This may, depending on the topos, end up being interpreted as ''true so far as global elements are concerned'', or ''not false on any open set'', or other interpretations.<br />
### <math>1_\Omega</math>.<br />
## For a topos <math>E</math> with a topology <math>j</math>, we define an object <math>A</math> to be a ''sheaf'' iff for every <math>X</math> and every <math>j</math>-dense subobject <math>S\subseteq X</math> and every <math>f:S\to A</math> there is a unique <math>g:X\to A</math> with <math>f=g\circ s</math>. In other words, <math>A</math> is an object that cannot see the difference between <math>j</math>-dense subobjects and objects. We write <math>E_j</math> for the full subcategory of <math>j</math>-sheaves. <br />
### Prove that any object is a sheaf for <math>1_\Omega</math>.<br />
### Prove that a subobject is dense for <math>\neg\neg</math> iff its negation is empty. Show that <math>true+false:1+1\to\Omega</math> is dense for this topology. Conclude that <math>1+1</math> is dense in <math>\Omega_{\neg\neg}</math> and thus that <math>E_{\neg\neg}</math> is Boolean.</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=32078User:Michiexile/MATH198/Lecture 102009-12-02T18:20:20Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional programming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that opens up for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. (Note that by admitting several universes, we arrive at a ''typed'' predicate logic, with basically no extra work.)<br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
We can now proceed to define all the familiar logic connectives one by one, using the topos setting. While doing this, we shall introduce the notation <math>t_A: A\to\Omega</math> for the morphism <math>t_A = A\to 1\to^{true}\Omega</math> that takes on the value ''true'' on all of A. We note that with this convention, <math>\chi_{A_0}</math>, the characteristic morphism of a subobject, is the arrow such that <math>\chi_{A_0}\circ i = t_{A_0}</math>.<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously.<br />
<br />
We may define <math>true\times true: 1\to\Omega\times\Omega</math>, a subobject of <math>\Omega\times\Omega</math>. Being a subobject, this has a characteristic arrow <math>\wedge:\Omega\times\Omega\to\Omega</math>, that we call the ''conjunction arrow''.<br />
<br />
Now, we may define <math>\chi_P\times\chi_Q:U\to\Omega\times\Omega</math> for subobjects <math>P,Q\subseteq U</math> - and we take their composition <math>\wedge\circ\chi_P\times\chi_Q</math> to be the characteristic arrow of the subobject <math>P\wedge Q</math>.<br />
<br />
And, indeed, this results in a topoidal version of intersection of subobjects.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1: \Omega_1\to\Omega\times\Omega</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v, w: U\to\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[U\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = (\Rightarrow)\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^U\subseteq U\times\Omega^U</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For elements <math>x\times h: 1\to U\times\Omega^U</math>, we write <math>x\in^U h</math> for <math>x\times h\in\in^U</math>. Yielding a subset of the product <math>U\times\Omega^U</math>, this is readily interpretable as a relation relating things in <math>U</math> with subsets of <math>U</math>, so that for any <math>x,h</math> we can answer whether <math>x\in^Uh</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>U</math>, the maximal subobject of <math>U</math> is <math>U</math> itself, embedded with <math>1_U</math> into itself. There is an arrow <math>\tau_U:1\to\Omega^U</math> represents this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_U:\Omega^U\to\Omega</math> that takes a given subobject of <math>U</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_R</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:[[Image:ToposFalsumDerivation.png]]<br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples: Sheaves, topology and time sheaves====<br />
<br />
The first interesting example of a topos is the category of (small enough) sets; in some sense clear already since we've been modelling our axioms and workflows pretty closely on the theory of sets.<br />
<br />
Generating logic and set theory in the topos of sets, we get a theory that captures several properties of ''intuitionistic logic''; such as the lack of Boolean negation, of exclusion of the third, and of double negation rules.<br />
<br />
For the more interesting examples, however, we shall introduce the concepts of ''topology'' and of ''sheaf'':<br />
<br />
'''Definition''' A (set-valued) ''presheaf'' on a category <math>C</math> is a contravariant functor <math>E: C^{op}\to Set</math>.<br />
<br />
Presheaves occur all over the place in geometry and topology - and occasionally in computer science too: There is a construction in which a functor <math>A\to Set</math> for a discrete small category <math>A</math> identified with its underlying set of objects as a set, corresponds to the data type of ''bags'' of elements from <math>A</math> - for <math>a\in A</math>, the image <math>F(a)</math> denotes the multiplicity of <math>a</math> in the bag.<br />
<br />
'''Theorem''' The category of all presheaves (with natural transformations as the morphisms) on a category <math>C</math> form a topos.<br />
<br />
'''Example''' Pick a category on the shape<br />
:[[Image:GraphsAsPresheaves.png]]<br />
A contravariant functor on this category is given by a pair of sets <math>G_0, G_1</math> and a pair of function <math>source, target: G_1\to G_0</math>. Identities are sent to identities.<br />
<br />
The category of presheaves on this category, thus, is the category of graphs. Thus graphs form a topos.<br />
<br />
The subobject classifier in the category of graphs is a graph with two nodes: in and out, and five arrows:<br />
:<math>in \to^{all} in</math><br />
:<math>in \to^{both} in</math><br />
:<math>in \to^{source} out</math><br />
:<math>out \to^{target} in</math><br />
:<math>out \to^{neither} out</math><br />
Now, given a subgraph <math>H \leq G</math>, we define a function <math>\chi_H:G\to\Omega</math> by sending nodes to in or out dependent on their membership. For an arrow <math>a</math>, we send it to all if the arrow is in <math>H</math>, and otherwise we send it to both/source/target/neither according to where its source and target reside.<br />
<br />
To really get into sheaves, though, we introduce more structure - specifically, we define what we mean by a ''topology'':<br />
<br />
'''Definition''' Suppose <math>P</math> is a partially ordered set. We call <math>P</math> a ''complete Heyting algebra'' if<br />
* There is a top element <math>1</math> such that <math>x\leq 1 \forall x\in P</math>.<br />
* Any two elements <math>x, y</math> have an infimum (greatest lower bound) <math>x\wedge y</math>.<br />
* Every subset <math>Q\subseteq P</math> has a supremum (least upper bound) <math>\bigvee_{p\in P} p</math>.<br />
* <math>x\wedge(\bigvee y_i) = \bigvee x\wedge y_i</math><br />
<br />
Note that for the partial order by inclusion of a family of subsets of a given set, being a complete Heyting algebra is the same as being a topology in the classical sense - you can take finite unions and any intersections of open sets and still get an open set. <br />
<br />
If <math>\{x_i\}</math> is a subset with supremum <math>x</math>, and <math>E</math> is a presheaf, we get functions <math>e_i:E(x)\to E(x_i)</math> from functoriality. We can summarize all these <math>e_i</math> into <math>e = \prod_i e_i: E(x)\to\prod_i E(x_i)</math>.<br />
<br />
Furthermore, functoriality gives us families of functions <math>c_{ij}: E(x_i)\to E(x_i\wedge x_j)</math> and <math>d_{ij}: E(x_j)\to E(x_i\wedge x_j)</math>. These can be collected into <math>c: \prod_i E(x_i)\to\prod_{ij}E(x_i\wedge x_j)</math> and <math>d:\prod_j E(x_j)\to\prod_{ij}E(x_i\wedge x_j)</math>.<br />
<br />
'''Definition''' A presheaf <math>E</math> on a Heyting algebra is called a ''sheaf'' if it satisfies:<br />
:<math>x = \bigvee x_i</math><br />
implies that <br />
:[[Image:SheafEqualizer.png]]<br />
is an equalizer. If you have seen sheaves before, you may recognize this as the covering axiom.<br />
<br />
In other words, <math>E</math> is a sheaf if whenever <math>x=\bigvee x_i</math> and <math>c(\alpha) = d(\alpha)</math>, then there is some <math>\bar\alpha</math> such that <math>\alpha = e(\bar\alpha)</math>.<br />
<br />
'''Theorem''' The category of sheaves on a Heyting algebra is a topos.<br />
<br />
For context, we can think of sheaves over Heyting algebras as sets in a logic with an expanded notion of truth. Our Heyting algebra is the collection of truth values, and the sheaves are the fuzzy sets with fuzziness introduced by the Heyting algebra.<br />
<br />
Recalling that subsets and predicates are viewed as the same thing, we can view the set <math>E(p)</math> as the part of the fuzzy set <math>E</math> that is at least <math>p</math> true.<br />
<br />
As it turns out, to really make sense of this approach, we realize that ''equality'' is a predicate as well - and thus can hold or not depending on the truth value we use.<br />
<br />
'''Definition''' Let <math>P</math> be a complete Heyting algebra. A ''<math>P</math>-valued set'' is a pair <math>(S,\sigma)</math> of a set <math>S</math> and a function <math>\sigma: S\to P</math>. A ''category of fuzzy sets'' is a category of <math>P</math>-valued sets. A morphism <math>f:(S,\sigma)\to(T,\tau)</math> of <math>P</math>-valued sets is a function <math>f:S\to T</math> such that <math>\tau\circ f = \sigma</math>.<br />
<br />
From these definitions emerges a fuzzy set theory where all components of it being a kind of set theory emerges from the topoidal approach above. Thus, say, subsets in a fuzzy sense are just monics, thus are injective on the set part, and such that the valuation, on the image of the injection, increases from the previous valuation: <math>(T,\tau)\subseteq(S,\sigma)</math> if <math>T\subseteq S</math> and <math>\sigma|_T = \tau</math>.<br />
<br />
To get to topoi, though, there are a few matters we need to consider. First, we may well have several versions of the empty set - either a bona fide empty set, or just a set where every element is never actually there. This issue is minor. Much more significant though, is that while we can easily make <math>(S,\sigma)</math> give rise to a presheaf, by defining<br />
:<math>E(x) = \{s\in S: \sigma(s)\geq x\}</math><br />
this definition will not yield a sheaf. The reason for this boils down to <math>E(0) = S \neq 1</math>. We can fix this, though, by adjoining another element - <math>\bot</math> - to <math>P</math> giving <math>P^+</math>. The new element <math>\bot</math> is imbued with two properties: it is smaller, in <math>P^+</math>, than any other element, and it is mapped, by <math>E</math> to <math>1</math>.<br />
<br />
'''Theorem''' The construction above gives a fuzzy set <math>(S,\sigma)</math> the structure of a sheaf on the augmented Heyting algebra.<br />
<br />
'''Corollary''' The category of fuzzy sets for a Heyting algebra <math>P</math> forms a topos.<br />
<br />
'''Final note''' While this construction allows us to make ''membership'' a fuzzy concept, we're not really done fuzzy-izing sets. There are two fundamental predicates on sets: equality and membership. While fuzzy set theory, classically, only allows us to make one of these fuzzy, topos theory allows us - rather easily - to make both these predicates fuzzy. Not only that, but membership reduces - with the power object construction - to equality testing, by which the fuzzy set theory ends up somewhat inconsistent in its treatment of the predicates.<br />
<br />
===Literature===<br />
<br />
At this point, I would warmly recommend the interested reader to pick up one, or more, of:<br />
* Steve Awodey: Category Theory<br />
* Michael Barr & Charles Wells: Categories for Computing Science<br />
* Colin McLarty: Elementary Categories, Elementary Toposes<br />
<br />
or for more chewy books<br />
* Peter T. Johnstone: Sketches of an Elephant: a Topos Theory compendium<br />
* Michael Barr & Charles Wells: Toposes, Triples and Theories<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# Prove the relations showing that <math>\leq_1</math> is indeed a partial order on <math>[U\to\Omega]</math>.<br />
# Prove the universal quantifier theorem.<br />
# The ''extension'' of a formula <math>\phi</math> over a list of variables <math>x</math> is the sub-object of the product of domains <math>A_1\times\dots\times A_n</math> for the variables <math>x_1,\dots,x_n=x</math> classified by the interpretation of <math>\phi</math> as a morphism <math>A_1\times\dots\times A_n\to\Omega</math>. A formula is ''true'' if it classifies the entire product. A ''sequent'', written <math>\Gamma:\phi</math> is the statement that using the set of formulae <math>\Gamma</math> we may prove <math>\phi</math>, or in other words that the intersection of the extensions of the formulae in <math>\Gamma</math> is contained in the extension of <math>\phi</math>. If a sequent <math>\Gamma:\phi</math> is true, we say that <math>\Gamma</math> ''entails'' <math>\phi</math>. (some of the questions below are almost embarrassingly immediate from the definitions given above. I include them anyway, so that a ''catalogue'' of sorts of topoidal logic inferences is included here)<br />
## Prove the following entailments:<br />
### Trivial sequent: <math>\phi:\phi</math><br />
### True: <math>:true</math> (note that true classifies the entire object)<br />
### False: <math>false:\phi</math> (note that false classifies the global minimum in thepreorder of subobjects)<br />
## Prove the following inference rules:<br />
### Implication: <math>\Gamma,\phi:\psi</math> is equivalent to <math>\Gamma:\phi\Rightarrow\psi</math>.<br />
### Thinning: <math>\Gamma:\phi</math> implies <math>\Gamma,\psi:\phi</math><br />
### Cut: <math>\Gamma,\psi:\phi</math> and <math>\Gamma:\psi</math> imply <math>\Gamma:\phi</math> if every variable free in <math>\psi</math> is free in <math>\Gamma</math> or in <math>\phi</math>.<br />
### Negation: <math>\Gamma, \phi: false</math> is equivalent (implications both ways) to <math>\Gamma: \neg\phi</math>.<br />
### Conjunction: <math>\Gamma:\phi</math> and <math>\Gamma:\psi</math> together are equivalent to <math>\Gamma:\phi\wedge\psi</math>.<br />
### Disjunction: <math>\Gamma,\phi:\theta</math> and <math>\Gamma,\psi:\theta</math> together imply <math>\Gamma, \phi\vee\psi: \theta</math>.<br />
### Universal: <math>\Gamma:\phi</math> is equivalent to <math>\Gamma:\forall x.\phi</math> if <math>x</math> is not free in <math>\Gamma</math>.<br />
### Existential: <math>\Gamma,\phi: \psi</math> is equivalent to <math>\Gamma,\exists x.\phi:\psi</math> if <math>x</math> is not free in <math>\Gamma</math> or <math>\psi</math>.<br />
### Equality: <math>:q=q</math>.<br />
### Biconditional: <math>(v\Rightarrow w)\wedge(w\Rightarrow v):v=w</math>. We usually write <math>v\Leftrightarrow w</math> for <math>v=w</math> if <math>v,w:A\to\Omega</math>.<br />
### Product: <math>p_1u = p_1u', p_2u = p_2u' : u = u'</math> for <math>u,u'\in A\times B</math>.<br />
### Product revisited: <math>:(p_1(s\times s')=s)\wedge(p_2(s\times s')=s')</math>.<br />
### Extensionality: <math>\forall x\in A. f(x) = g(x) : f = g</math> for <math>f,g\in[A\to B]</math>.<br />
### Comprehension: <math>(\lambda x\in A. s)x = s</math> for <math>x\in A</math>.<br />
## Prove the following results from the above entailments and inferences -- or directly from the topoidal logic mindset:<br />
### <math>:\neg(\phi\wedge\neg\phi)</math>.<br />
### <math>:\phi\Rightarrow\neg\neg\phi</math>.<br />
### <math>:\neg(\phi\vee\psi)\Rightarrow(\neg\phi\wedge\neg\psi)</math>.<br />
### <math>:(\neg\phi\wedge\neg\psi)\Rightarrow\neg(\phi\wedge\psi)</math>.<br />
### <math>:(\neg\phi\vee\neg\psi)\Rightarrow\neg(\phi\vee\psi)</math>.<br />
### <math>\phi\wedge(\theta\vee\psi)</math> is equivalent to <math>(\phi\wedge\theta)\vee(\phi\wedge\psi)</math>.<br />
### <math>\forall x.\neg\phi</math> is equivalent to <math>\neg\exists x.\phi</math>.<br />
### <math>\exists x\phi\Rightarrow\neg\forall x.\neg\phi</math>.<br />
### <math>\exists x\neg\phi\Rightarrow\neg\forall x.\phi</math>.<br />
### <math>\forall x\phi\Rightarrow\neg\exists x.\neg\phi</math>.<br />
### <math>\phi:\psi</math> implies <math>\neg\psi:\neg\phi</math>.<br />
### <math>\phi:\psi\Rightarrow\phi</math>.<br />
### <math>\phi\Rightarrow\not\phi:\not\phi</math>.<br />
### <math>\not\phi\vee\psi:\phi\Rightarrow\psi</math> (but not the converse!).<br />
### <math>\neg\neg\neg\phi</math> is equivalent to <math>\neg\phi</math>.<br />
### <math>(\phi\wedge\psi)\Rightarrow\theta</math> is equivalent to <math>\phi\Rightarrow(\psi\Rightarrow\theta)</math> (currying!).<br />
## Using the Boolean negation rule: <math>\Gamma,\neg\phi:false</math> is equivalent to <math>\Gamma:\phi</math>, prove the following additional results:<br />
### <math>\neg\neg\phi:\phi</math>.<br />
### <math>:\phi\vee\neg\phi</math>.<br />
## Show that either of the three rules above, together with the original negation rule, implies the Boolean negation rule.<br />
### The converses of the three existential/universal/negation implications above.<br />
## The restrictions introduced for the cut rule above block the deduction of an entailment <math>:\forall x.\phi\Rightarrow\exists x.\phi</math>. The issue at hand is that <math>A</math> might not actually have members; so choosing one is not a sound move. Show that this entailment can be deduced from the premise <math>\exists x\in A. x=x</math>.<br />
## Show that if we extend our ruleset by the quantifier negation rule <math>\forall x\Leftrightarrow \neg\exists x.\neg</math>, then we can derive the entailment <math>:\forall w: w=t \vee w = false</math>. From this derive <math>:\phi\vee\neg\phi</math> and hence conclude that this extension gets us Boolean logic again.<br />
# A ''topology'' on a topos <math>E</math> is an arrow <math>j:\Omega\to\Omega</math> such that <math>j\circ true=true</math>, <math>j\circ j=j<math> and <math>j\circ\wedge = \wedge\circ j\times j</math>. For a subobject <math>S\subseteq A</math> with characteristic arrow <math>\chi_S:A\to\Omega</math>, we define its <math>j</math>-closure as the subobject <math>\bar S\subseteq A</math> classified by <math>j\circ\chi_S</math>.<br />
## Prove:<br />
### <math>S\subseteq\bar S</math>.<br />
### <math>\bar S = \bar{\bar S}</math>.<br />
### <math>\bar{S\cap T} = \bar S\cap\bar T</math>.<br />
### <math>S\subseteq T</math> implies <math>\bar S\subseteq\bar T</math>.<br />
### <math>\bar{f^{-1}(S)} = f^{-1}(\bar S)</math>.<br />
## We define <math>S</math> to be <math>j</math>-closed if <math>S=\bar S</math>. It is <math>j</math>-dense if <math>\bar S=A</math>. These terms are chosen due to correspondences to classical pointset topology for the topos of sheaves over some space. For a logical standpoint, it is more helpful to look at <math>j</math> as a modality operator: "''it is <math>j</math>-locally true that''" Given any <math>u:1\to\Omega</math>, prove that the following are topologies:<br />
### <math>(u\to -): \Omega\to\Omega</math> (the ''open topology'', where such a <math>u</math> in a sheaf topos ends up corresponding to an open subset of the underlying space, and the formulae picked out are true on at least all of that subset).<br />
### <math>u\vee -): \Omega\to\Omega</math> (the closed topology, where a formula is true if its disjunction with <math>u</math> is true -- corresponding to formulae holding over at least the closed set complementing the subset picked out)<br />
### <math>\neg\neg: \Omega\to\Omega</math>. This may, depending on the topos, end up being interpreted as ''true so far as global elements are concerned'', or ''not false on any open set'', or other interpretations.<br />
### <math>1_\Omega</math>.<br />
## For a topos <math>E</math> with a topology <math>j</math>, we define an object <math>A</math> to be a ''sheaf'' iff for every <math>X</math> and every <math>j</math>-dense subobject <math>S\subseteq X</math> and every <math>f:S\to A</math> there is a unique <math>g:X\to A</math> with <math>f=g\circ s</math>. In other words, <math>A</math> is an object that cannot see the difference between <math>j</math>-dense subobjects and objects. We write <math>E_j</math> for the full subcategory of <math>j</math>-sheaves. <br />
### Prove that any object is a sheaf for <math>1_\Omega</math>.<br />
### Prove that a subobject is dense for <math>\neg\neg</math> iff its negation is empty. Show that <math>true+false:1+1\to\Omega</math> is dense for this topology. Conclude that <math>1+1</math> is dense in <math>\Omega_{\neg\neg}</math> and thus that <math>E_{\neg\neg}</math> is Boolean.</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=32053User:Michiexile/MATH198/Lecture 102009-12-01T15:22:09Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional programming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that opens up for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. (Note that by admitting several universes, we arrive at a ''typed'' predicate logic, with basically no extra work.)<br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
We can now proceed to define all the familiar logic connectives one by one, using the topos setting. While doing this, we shall introduce the notation <math>t_A: A\to\Omega</math> for the morphism <math>t_A = A\to 1\to^{true}\Omega</math> that takes on the value ''true'' on all of A. We note that with this convention, <math>\chi_{A_0}</math>, the characteristic morphism of a subobject, is the arrow such that <math>\chi_{A_0}\circ i = t_{A_0}</math>.<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously.<br />
<br />
We may define <math>true\times true: 1\to\Omega\times\Omega</math>, a subobject of <math>\Omega\times\Omega</math>. Being a subobject, this has a characteristic arrow <math>\wedge:\Omega\times\Omega\to\Omega</math>, that we call the ''conjunction arrow''.<br />
<br />
Now, we may define <math>\chi_P\times\chi_Q:U\to\Omega\times\Omega</math> for subobjects <math>P,Q\subseteq U</math> - and we take their composition <math>\wedge\circ\chi_P\times\chi_Q</math> to be the characteristic arrow of the subobject <math>P\wedge Q</math>.<br />
<br />
And, indeed, this results in a topoidal version of intersection of subobjects.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1: \Omega_1\to\Omega\times\Omega</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v, w: U\to\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[U\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = (\Rightarrow)\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^U\subseteq U\times\Omega^U</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For elements <math>x\times h: 1\to U\times\Omega^U</math>, we write <math>x\in^U h</math> for <math>x\times h\in\in^U</math>. Yielding a subset of the product <math>U\times\Omega^U</math>, this is readily interpretable as a relation relating things in <math>U</math> with subsets of <math>U</math>, so that for any <math>x,h</math> we can answer whether <math>x\in^Uh</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>U</math>, the maximal subobject of <math>U</math> is <math>U</math> itself, embedded with <math>1_U</math> into itself. There is an arrow <math>\tau_U:1\to\Omega^U</math> represents this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_U:\Omega^U\to\Omega</math> that takes a given subobject of <math>U</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_R</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:[[Image:ToposFalsumDerivation.png]]<br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples: Sheaves, topology and time sheaves====<br />
<br />
The first interesting example of a topos is the category of (small enough) sets; in some sense clear already since we've been modelling our axioms and workflows pretty closely on the theory of sets.<br />
<br />
Generating logic and set theory in the topos of sets, we get a theory that captures several properties of ''intuitionistic logic''; such as the lack of Boolean negation, of exclusion of the third, and of double negation rules.<br />
<br />
For the more interesting examples, however, we shall introduce the concepts of ''topology'' and of ''sheaf'':<br />
<br />
'''Definition''' A (set-valued) ''presheaf'' on a category <math>C</math> is a contravariant functor <math>E: C^{op}\to Set</math>.<br />
<br />
Presheaves occur all over the place in geometry and topology - and occasionally in computer science too: There is a construction in which a functor <math>A\to Set</math> for a discrete small category <math>A</math> identified with its underlying set of objects as a set, corresponds to the data type of ''bags'' of elements from <math>A</math> - for <math>a\in A</math>, the image <math>F(a)</math> denotes the multiplicity of <math>a</math> in the bag.<br />
<br />
'''Theorem''' The category of all presheaves (with natural transformations as the morphisms) on a category <math>C</math> form a topos.<br />
<br />
'''Example''' Pick a category on the shape<br />
:[[Image:GraphsAsPresheaves.png]]<br />
A contravariant functor on this category is given by a pair of sets <math>G_0, G_1</math> and a pair of function <math>source, target: G_1\to G_0</math>. Identities are sent to identities.<br />
<br />
The category of presheaves on this category, thus, is the category of graphs. Thus graphs form a topos.<br />
<br />
The subobject classifier in the category of graphs is a graph with two nodes: in and out, and five arrows:<br />
:<math>in \to^{all} in</math><br />
:<math>in \to^{both} in</math><br />
:<math>in \to^{source} out</math><br />
:<math>out \to^{target} in</math><br />
:<math>out \to^{neither} out</math><br />
Now, given a subgraph <math>H \leq G</math>, we define a function <math>\chi_H:G\to\Omega</math> by sending nodes to in or out dependent on their membership. For an arrow <math>a</math>, we send it to all if the arrow is in <math>H</math>, and otherwise we send it to both/source/target/neither according to where its source and target reside.<br />
<br />
To really get into sheaves, though, we introduce more structure - specifically, we define what we mean by a ''topology'':<br />
<br />
'''Definition''' Suppose <math>P</math> is a partially ordered set. We call <math>P</math> a ''complete Heyting algebra'' if<br />
* There is a top element <math>1</math> such that <math>x\leq 1 \forall x\in P</math>.<br />
* Any two elements <math>x, y</math> have an infimum (greatest lower bound) <math>x\wedge y</math>.<br />
* Every subset <math>Q\subseteq P</math> has a supremum (least upper bound) <math>\bigvee_{p\in P} p</math>.<br />
* <math>x\wedge(\bigvee y_i) = \bigvee x\wedge y_i</math><br />
<br />
Note that for the partial order by inclusion of a family of subsets of a given set, being a complete Heyting algebra is the same as being a topology in the classical sense - you can take finite unions and any intersections of open sets and still get an open set. <br />
<br />
If <math>\{x_i\}</math> is a subset with supremum <math>x</math>, and <math>E</math> is a presheaf, we get functions <math>e_i:E(x)\to E(x_i)</math> from functoriality. We can summarize all these <math>e_i</math> into <math>e = \prod_i e_i: E(x)\to\prod_i E(x_i)</math>.<br />
<br />
Furthermore, functoriality gives us families of functions <math>c_{ij}: E(x_i)\to E(x_i\wedge x_j)</math> and <math>d_{ij}: E(x_j)\to E(x_i\wedge x_j)</math>. These can be collected into <math>c: \prod_i E(x_i)\to\prod_{ij}E(x_i\wedge x_j)</math> and <math>d:\prod_j E(x_j)\to\prod_{ij}E(x_i\wedge x_j)</math>.<br />
<br />
'''Definition''' A presheaf <math>E</math> on a Heyting algebra is called a ''sheaf'' if it satisfies:<br />
:<math>x = \bigvee x_i</math><br />
implies that <br />
:[[Image:SheafEqualizer.png]]<br />
is an equalizer. If you have seen sheaves before, you may recognize this as the covering axiom.<br />
<br />
In other words, <math>E</math> is a sheaf if whenever <math>x=\bigvee x_i</math> and <math>c(\alpha) = d(\alpha)</math>, then there is some <math>\bar\alpha</math> such that <math>\alpha = e(\bar\alpha)</math>.<br />
<br />
'''Theorem''' The category of sheaves on a Heyting algebra is a topos.<br />
<br />
For context, we can think of sheaves over Heyting algebras as sets in a logic with an expanded notion of truth. Our Heyting algebra is the collection of truth values, and the sheaves are the fuzzy sets with fuzziness introduced by the Heyting algebra.<br />
<br />
Recalling that subsets and predicates are viewed as the same thing, we can view the set <math>E(p)</math> as the part of the fuzzy set <math>E</math> that is at least <math>p</math> true.<br />
<br />
As it turns out, to really make sense of this approach, we realize that ''equality'' is a predicate as well - and thus can hold or not depending on the truth value we use.<br />
<br />
'''Definition''' Let <math>P</math> be a complete Heyting algebra. A ''<math>P</math>-valued set'' is a pair <math>(S,\sigma)</math> of a set <math>S</math> and a function <math>\sigma: S\to P</math>. A ''category of fuzzy sets'' is a category of <math>P</math>-valued sets. A morphism <math>f:(S,\sigma)\to(T,\tau)</math> of <math>P</math>-valued sets is a function <math>f:S\to T</math> such that <math>\tau\circ f = \sigma</math>.<br />
<br />
From these definitions emerges a fuzzy set theory where all components of it being a kind of set theory emerges from the topoidal approach above. Thus, say, subsets in a fuzzy sense are just monics, thus are injective on the set part, and such that the valuation, on the image of the injection, increases from the previous valuation: <math>(T,\tau)\subseteq(S,\sigma)</math> if <math>T\subseteq S</math> and <math>\sigma|_T = \tau</math>.<br />
<br />
To get to topoi, though, there are a few matters we need to consider. First, we may well have several versions of the empty set - either a bona fide empty set, or just a set where every element is never actually there. This issue is minor. Much more significant though, is that while we can easily make <math>(S,\sigma)</math> give rise to a presheaf, by defining<br />
:<math>E(x) = \{s\in S: \sigma(s)\geq x\}</math><br />
this definition will not yield a sheaf. The reason for this boils down to <math>E(0) = S \neq 1</math>. We can fix this, though, by adjoining another element - <math>\bot</math> - to <math>P</math> giving <math>P^+</math>. The new element <math>\bot</math> is imbued with two properties: it is smaller, in <math>P^+</math>, than any other element, and it is mapped, by <math>E</math> to <math>1</math>.<br />
<br />
'''Theorem''' The construction above gives a fuzzy set <math>(S,\sigma)</math> the structure of a sheaf on the augmented Heyting algebra.<br />
<br />
'''Corollary''' The category of fuzzy sets for a Heyting algebra <math>P</math> forms a topos.<br />
<br />
'''Final note''' While this construction allows us to make ''membership'' a fuzzy concept, we're not really done fuzzy-izing sets. There are two fundamental predicates on sets: equality and membership. While fuzzy set theory, classically, only allows us to make one of these fuzzy, topos theory allows us - rather easily - to make both these predicates fuzzy. Not only that, but membership reduces - with the power object construction - to equality testing, by which the fuzzy set theory ends up somewhat inconsistent in its treatment of the predicates.<br />
<br />
===Literature===<br />
<br />
At this point, I would warmly recommend the interested reader to pick up one, or more, of:<br />
* Steve Awodey: Category Theory<br />
* Michael Barr & Charles Wells: Categories for Computing Science<br />
* Colin McLarty: Elementary Categories, Elementary Toposes<br />
<br />
or for more chewy books<br />
* Peter T. Johnstone: Sketches of an Elephant: a Topos Theory compendium<br />
* Michael Barr & Charles Wells: Toposes, Triples and Theories<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
#</div>Michiexilehttps://wiki.haskell.org/index.php?title=File:GraphsAsPresheaves.png&diff=31924File:GraphsAsPresheaves.png2009-11-25T01:32:14Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:SheafEqualizer.png&diff=31923File:SheafEqualizer.png2009-11-25T01:30:14Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31922User:Michiexile/MATH198/Lecture 102009-11-25T01:21:20Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that opens up for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
We can now proceed to define all the familiar logic connectives one by one, using the topos setting. While doing this, we shall introduce the notation <math>t_A: A\to\Omega</math> for the morphism <math>t_A = A\to 1\to^{true}\Omega</math> that takes on the value ''true'' on all of A. We note that with this convention, <math>\chi_{A_0}</math>, the characteristic morphism of a subobject, is the arrow such that <math>\chi_{A_0}\circ i = t_{A_0}</math>.<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously.<br />
<br />
We may define <math>true\times true: 1\to\Omega\times\Omega</math>, a subobject of <math>\Omega\times\Omega</math>. Being a subobject, this has a characteristic arrow <math>\wedge:\Omega\times\Omega\to\Omega</math>, that we call the ''conjunction arrow''.<br />
<br />
Now, we may define <math>\chi_P\times\chi_Q:U\to\Omega\times\Omega</math> for subobjects <math>P,Q\subseteq U</math> - and we take their composition <math>\wedge\circ\chi_P\times\chi_Q</math> to be the characteristic arrow of the subobject <math>P\wedge Q</math>.<br />
<br />
And, indeed, this results in a topoidal version of intersection of subobjects.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1: \Omega_1\to\Omega\times\Omega</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v, w: U\to\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[U\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = (\Rightarrow)\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^U\subseteq U\times\Omega^U</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For elements <math>x\times h: 1\to U\times\Omega^U</math>, we write <math>x\in^U h</math> for <math>x\times h\in\in^U</math>. Yielding a subset of the product <math>U\times\Omega^U</math>, this is readily interpretable as a relation relating things in <math>U</math> with subsets of <math>U</math>, so that for any <math>x,h</math> we can answer whether <math>x\in^Uh</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>U</math>, the maximal subobject of <math>U</math> is <math>U</math> itself, embedded with <math>1_U</math> into itself. There is an arrow <math>\tau_U:1\to\Omega^U</math> represents this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_U:\Omega^U\to\Omega</math> that takes a given subobject of <math>U</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_R</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:[[Image:ToposFalsumDerivation.png]]<br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples: Sheaves, topology and time sheaves====<br />
<br />
The first interesting example of a topos is the category of (small enough) sets; in some sense clear already since we've been modelling our axioms and workflows pretty closely on the theory of sets.<br />
<br />
Generating logic and set theory in the topos of sets, we get a theory that captures several properties of ''intuitionistic logic''; such as the lack of Boolean negation, of exclusion of the third, and of double negation rules.<br />
<br />
For the more interesting examples, however, we shall introduce the concepts of ''topology'' and of ''sheaf'':<br />
<br />
'''Definition''' A (set-valued) ''presheaf'' on a category <math>C</math> is a contravariant functor <math>E: C^{op}\to Set</math>.<br />
<br />
Presheaves occur all over the place in geometry and topology - and occasionally in computer science too: There is a construction in which a functor <math>A\to Set</math> for a discrete small category <math>A</math> identified with its underlying set of objects as a set, corresponds to the data type of ''bags'' of elements from <math>A</math> - for <math>a\in A</math>, the image <math>F(a)</math> denotes the multiplicity of <math>a</math> in the bag.<br />
<br />
'''Theorem''' The category of all presheaves (with natural transformations as the morphisms) on a category <math>C</math> form a topos.<br />
<br />
'''Example''' Pick a category on the shape<br />
:[[Image:GraphsAsPresheaves.png]]<br />
A contravariant functor on this category is given by a pair of sets <math>G_0, G_1</math> and a pair of function <math>source, target: G_1\to G_0</math>. Identities are sent to identities.<br />
<br />
The category of presheaves on this category, thus, is the category of graphs. Thus graphs form a topos.<br />
<br />
The subobject classifier in the category of graphs is a graph with two nodes: in and out, and five arrows:<br />
:<math>in \to^{all} in</math><br />
:<math>in \to^{both} in</math><br />
:<math>in \to^{source} out</math><br />
:<math>out \to^{target} in</math><br />
:<math>out \to^{neither} out</math><br />
Now, given a subgraph <math>H \leq G</math>, we define a function <math>\chi_H:G\to\Omega</math> by sending nodes to in or out dependent on their membership. For an arrow <math>a</math>, we send it to all if the arrow is in <math>H</math>, and otherwise we send it to both/source/target/neither according to where its source and target reside.<br />
<br />
To really get into sheaves, though, we introduce more structure - specifically, we define what we mean by a ''topology'':<br />
<br />
'''Definition''' Suppose <math>P</math> is a partially ordered set. We call </math>P</math> a ''complete Heyting algebra'' if<br />
* There is a top element <math>1</math> such that <math>x\leq 1 \forall x\in P</math>.<br />
* Any two elements <math>x, y</math> have an infimum (greatest lower bound) <math>x\wedge y</math>.<br />
* Every subset <math>Q\subseteq P</math> has a supremum (least upper bound) <math>\bigvee_{p\in P} p</math>.<br />
* <math>x\wedge(\bigvee y_i) = \bigvee x\wedge y_i</math><br />
<br />
Note that for the partial order by inclusion of a family of subsets of a given set, being a complete Heyting algebra is the same as being a topology in the classical sense - you can take finite unions and any intersections of open sets and still get an open set. <br />
<br />
If <math>\{x_i\}</math> is a subset with supremum <math>x</math>, and <math>E</math> is a presheaf, we get functions <math>e_i:E(x)\to E(x_i)</math> from functoriality. We can summarize all these <math>e_i</math> into <math>e = \prod_i e_i: E(x)\to\prod_i E(x_i)</math>.<br />
<br />
Furthermore, functoriality gives us families of functions <math>c_{ij}: E(x_i)\to E(x_i\wedge x_j)</math> and <math>d_{ij}: E(x_j)\to E(x_i\wedge x_j)</math>. These can be collected into <math>c: \prod_i E(x_i)\to\prod_{ij}E(x_i\wedge x_j)?</math> and <math>d:\prod_j E(x_j)\to\prod_{ij}E(x_i\wedge x_j)</math>.<br />
<br />
'''Definition''' A presheaf <math>E</math> on a Heyting algebra is called a ''sheaf'' if it satisfies:<br />
:<math>x = \bigvee x_i</math><br />
implies that <br />
:[[Image:SheafEqualizer.png]]<br />
is an equalizer.<br />
<br />
In other words, <math>E</math> is a sheaf if whenever <math>x=\bigvee x_i</math> and <math>c(\alpha) = d(\alpha)</math>, then there is some <math>\bar\alpha</math> such that <math>\alpha = e(\bar\alpha)</math>.<br />
<br />
'''Theorem''' The category of sheaves on a Heyting algebra is a topos.<br />
<br />
For context, we can think of sheaves over Heyting algebras as sets in a logic with an expanded notion of truth. Our Heyting algebra is the collection of truth values, and the sheaves are the fuzzy sets with fuzziness introduced by the Heyting algebra.<br />
<br />
Recalling that subsets and predicates are viewed as the same thing, we can view the set <math>E(p)</math> as the part of the fuzzy set <math>E</math> that is at least <math>p</math> true.<br />
<br />
As it turns out, to really make sense of this approach, we realize that ''equality'' is a predicate as well - and thus can hold or not depending on the truth value we use.<br />
<br />
'''Definition''' Let <math>P</math> be a complete Heyting algebra. A ''<math>P</math>-valued set'' is a pair <math>(S,\sigma)</math> of a set <math>S</math> and a function <math>\sigma: S\to P</math>. A ''category of fuzzy sets'' is a category of <math>P</math>-valued sets. A morphism <math>f:(S,\sigma)\to(T,\tau)</math> of <math>P</math>-valued sets is a function <math>f:S\to T</math> such that <math>\tau\circ f = \sigma</math>.<br />
<br />
From these definitions emerges a fuzzy set theory where all components of it being a kind of set theory emerges from the topoidal approach above. Thus, say, subsets in a fuzzy sense are just monics, thus are injective on the set part, and such that the valuation, on the image of the injection, increases from the previous valuation: <math>(T,\tau)\subseteq(S,\sigma) if <math>T\subseteq S</math> and <math>\sigma|_T = \tau</math>.<br />
<br />
To get to topoi, though, there are a few matters we need to consider. First, we may well have several versions of the empty set - either a bona fide empty set, or just a set where every element is never actually there. This issue is minor. Much more significant though, is that while we can easily make <math>(S,\sigma)</math> give rise to a presheaf, by defining<br />
:<math>E(x) = \{s\in S: \sigma(s)\geq x\}</math><br />
this definition will not yield a sheaf. The reason for this boils down to <math>E(0) = S \neq 1</math>. We can fix this, though, by adjoining another element - <math>\bot</math> - to <math>P</math> giving <math>P^+</math>. The new element <math>\bot</math> is imbued with two properties: it is smaller, in <math>P^+</math>, than any other element, and it is mapped, by <math>E</math> to <math>1</math>.<br />
<br />
'''Theorem''' The construction above gives a fuzzy set <math>(S,\sigma)</math> the structure of a sheaf on the augmented Heyting algebra.<br />
<br />
'''Corollary''' The category of fuzzy sets for a Heyting algebra <math>P</math> forms a topos.<br />
<br />
'''Final note''' While this construction allows us to make ''membership'' a fuzzy concept, we're not really done fuzzy-izing sets. There are two fundamental predicates on sets: equality and membership. While fuzzy set theory, classically, only allows us to make one of these fuzzy, topos theory allows us - rather easily - to make both these predicates fuzzy. Not only that, but membership reduces - with the power object construction - to equality testing, by which the fuzzy set theory ends up somewhat inconsistent in its treatment of the predicates.<br />
<br />
===Literature===<br />
<br />
At this point, I would warmly recommend the interested reader to pick up one, or more, of:<br />
* Steve Awodey: Category Theory<br />
* Michael Barr & Charles Wells: Categories for Computing Science<br />
* Colin McLarty: Elementary Categories, Elementary Toposes<br />
<br />
or for more chewy books<br />
* Peter T. Johnstone: Sketches of an Elephant: a Topos Theory compendium<br />
* Michael Barr & Charles Wells: Toposes, Triples and Theories<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=File:BooleanNegation.png&diff=31919File:BooleanNegation.png2009-11-24T19:52:13Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposExistsConnective.png&diff=31918File:ToposExistsConnective.png2009-11-24T19:51:52Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposDisjunctionConnective.png&diff=31917File:ToposDisjunctionConnective.png2009-11-24T19:51:14Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposExFalsoQuodlibet.png&diff=31916File:ToposExFalsoQuodlibet.png2009-11-24T19:45:42Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposFalsumDerivation.png&diff=31915File:ToposFalsumDerivation.png2009-11-24T19:45:19Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposSubstitution.png&diff=31914File:ToposSubstitution.png2009-11-24T19:44:59Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposForallConnective.png&diff=31913File:ToposForallConnective.png2009-11-24T19:44:39Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposTrivialSequent.png&diff=31912File:ToposTrivialSequent.png2009-11-24T19:44:22Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposForallPullback.png&diff=31911File:ToposForallPullback.png2009-11-24T19:44:00Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:ToposMembershipPullback.png&diff=31910File:ToposMembershipPullback.png2009-11-24T19:43:02Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:SubobjectClassifierPullback.png&diff=31909File:SubobjectClassifierPullback.png2009-11-24T19:42:19Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:SubobjectFunctorMorphismPullback.png&diff=31908File:SubobjectFunctorMorphismPullback.png2009-11-24T19:42:01Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31907User:Michiexile/MATH198/Lecture 102009-11-24T19:40:55Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that open sup for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
We can now proceed to define all the familiar logic connectives one by one, using the topos setting. While doing this, we shall introduce the notation <math>t_A: A\to\Omega</math> for the morphism <math>t_A = A\to 1\to^{true}\Omega</math> that takes on the value ''true'' on all of A. We note that with this convention, <math>\chi_{A_0}</math>, the characteristic morphism of a subobject, is the arrow such that <math>\chi_{A_0}\circ i = t_{A_0}</math>.<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously.<br />
<br />
We may define <math>true\times true: 1\to\Omega\times\Omega</math>, a subobject of <math>\Omega\times\Omega</math>. Being a subobject, this has a characteristic arrow <math>\wedge:\Omega\times\Omega\to\Omega</math>, that we call the ''conjunction arrow''.<br />
<br />
Now, we may define <math>\chi_P\times\chi_Q:U\to\Omega\times\Omega</math> for subobjects <math>P,Q\subseteq U</math> - and we take their composition <math>\wedge\circ\chi_P\times\chi_Q</math> to be the characteristic arrow of the subobject <math>P\wedge Q</math>.<br />
<br />
And, indeed, this results in a topoidal version of intersection of subobjects.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1: \Omega_1\to\Omega\times\Omega</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v, w: U\to\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[U\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = (\Rightarrow)\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^A\subseteq A\times\Omega^A</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For elements <math>x\times h: 1\to U\times\Omega^U</math>, we write <math>x\in^U h</math> for <math>x\times h\in\in^U</math>. Yielding a subset of the product <math>U\times\Omega^U</math>, this is readily interpretable as a relation relating things in <math>U</math> with subsets of <math>U</math>, so that for any <math>x,h</math> we can answer whether <math>x\in^Uh</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>U</math>, the maximal subobject of <math>U</math> is <math>U</math> itself, embedded with <math>1_U</math> into itself. There is an arrow <math>\tau_U:1\to\Omega^U</math> represents this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_U:\Omega^U\to\Omega</math> that takes a given subobject of <math>U</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_R</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:[[Image:ToposFalsumDerivation.png]]<br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31906User:Michiexile/MATH198/Lecture 102009-11-24T19:03:46Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that open sup for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
We can now proceed to define all the familiar logic connectives one by one, using the topos setting. While doing this, we shall introduce the notation <math>t_A: A\to\Omega</math> for the morphism <math>t_A = A\to 1\to^{true}\Omega</math> that takes on the value ''true'' on all of A. We note that with this convention, <math>\chi_{A_0}</math>, the characteristic morphism of a subobject, is the arrow such that <math>\chi_{A_0}\circ i = t_{A_0}</math>.<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously.<br />
<br />
We may define <math>true\times true: 1\to\Omega\times\Omega</math>, a subobject of <math>\Omega\times\Omega</math>. Being a subobject, this has a characteristic arrow <math>\wedge:\Omega\times\Omega\to\Omega</math>, that we call the ''conjunction arrow''.<br />
<br />
Now, we may define <math>\chi_P\times\chi_Q:U\to\Omega\times\Omega</math> for subobjects <math>P,Q\subseteq U</math> - and we take their composition <math>\wedge\circ\chi_P\times\chi_Q</math> to be the characteristic arrow of the subobject <math>P\wedge Q</math>.<br />
<br />
And, indeed, this results in a topoidal version of intersection of subobjects.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1: \Omega_1\to\Omega\times\Omega</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v, w: U\to\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[U\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = (\Rightarrow)\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^A\subseteq A\times\Omega^A</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For generalized elements <math>x\times h: T\to A\times\Omega^A</math>, we write <math>x\in^A h<math> for <math>x\times h\in\in^A</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>A</math>, the maximal subobject of <math>A</math> is <math>A</math> itself, embedded with <math>1_A</math> into itself. Thus, we have an arrow <math>t_A:1\to\Omega^A</math> representing this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_A:\Omega^A\to\Omega</math> that takes a given subobject of <math>A</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_r</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:<math>*</math><br />
:<math>\forall w.w : \forall w.w</math> <br />
:<math>\forall w.w : w</math><br />
:<math>\forall w.w : \phi</math><br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistentsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31896User:Michiexile/MATH198/Lecture 102009-11-24T18:43:03Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that open sup for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously. <br />
<br />
We can construct pullback diagrams<br />
:[[Image:ToposConjunctionPart1.png]] [[Image:ToposConjunctionPart2.png]]<br />
in which <math>u = \chi_P\times\chi_Q</math>. Furthermore, the arrow <math>true\times true: 1\to\Omega\times\Omega</math> is monic, and thus has a classifier <math>\wedge:\Omega\times\Omega\to\Omega</math>.<br />
<br />
Now, we define <math>P\wedge Q</math> as the composition <math>\wedge\circ\chi_P\times\chi_Q</math>, and observe that <math>P\wedge Q</math> classifies the intersection <math>P\cap Q</math>.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v\times w: T\to\Omega\times\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[T\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = \Rightarrow\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^A\subseteq A\times\Omega^A</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For generalized elements <math>x\times h: T\to A\times\Omega^A</math>, we write <math>x\in^A h<math> for <math>x\times h\in\in^A</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>A</math>, the maximal subobject of <math>A</math> is <math>A</math> itself, embedded with <math>1_A</math> into itself. Thus, we have an arrow <math>t_A:1\to\Omega^A</math> representing this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_A:\Omega^A\to\Omega</math> that takes a given subobject of <math>A</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_r</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:<math>*</math><br />
:<math>\forall w.w : \forall w.w</math> <br />
:<math>\forall w.w : w</math><br />
:<math>\forall w.w : \phi</math><br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistentsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31893User:Michiexile/MATH198/Lecture 102009-11-24T17:05:21Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that open sup for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
<br />
'''Conjunction''': <br />
Given predicates <math>P, Q</math>, we need to define the ''conjunction'' <math>P\wedge Q</math> as some <math>P\wedge Q: U\to\Omega</math> that corresponds to both <math>P</math> and <math>Q</math> simultaneously. <br />
<br />
We can construct pullback diagrams<br />
:[[Image:ToposConjunctionPart1.png]] [[Image:ToposConjunctionPart2.png]]<br />
in which <math>u = \chi_P\times\chi_Q</math>. Furthermore, the arrow <math>true\times\true: 1\to\Omega\times\Omega</math> is monic, and thus has a classifier <math>\wedge:\Omega\times\Omega\to\Omega</math>.<br />
<br />
Now, we define <math>P\wedge Q</math> as the composition <math>\wedge\circ\chi_P\times\chi_Q</math>, and observe that <math>P\wedge Q</math> classifies the intersection <math>P\cap Q</math>.<br />
<br />
'''Implication''': <br />
Next we define <math>\leq_1</math> to be the equalizer of <math>\wedge</math> and <math>proj_1</math>. Given <math>v\times w: T\to\Omega\times\Omega</math>, we write <math>v\leq_1 w</math> if <math>v\times w</math> factors through <math>\leq_1</math>.<br />
<br />
Using the definition of an equalizer we arrive at <math>v\leq_1 w</math> iff <math>v = v\wedge w</math>. From this, we can deduce<br />
:<math>u\leq_1 true</math><br />
:<math>u\leq_1 u</math><br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 w</math> then <math>u\leq_1 w</math>.<br />
:If <math>u\leq_1 v</math> and <math>v\leq_1 u</math> then <math>u=v</math><br />
and thus, <math>\leq_1</math> is a partial order on <math>[T\to\Omega]</math>. Intuitively, <math>u\leq_1 v</math> if <math>v</math> is at least as true as <math>u</math>.<br />
<br />
This relation corresponds to inclusion on subobjects. Note that <math>\leq_1:\Omega_1\to\Omega\times\Omega</math>, given from the equalizer, gives us <math>\Omega_1</math> as a ''relation'' on <math>\Omega</math> - a subobject of <math>\Omega\times\Omega</math>. Specifically, it has a classifying arrow <math>\Rightarrow:\Omega\times\Omega\to\Omega</math>. We write <math>h\Rightarrow k = \Rightarrow\circ h\times k</math>. And for subobjects <math>P,Q\subseteq A</math>, we write <math>P\Rightarrow Q</math> for the subobject classified by <math>\chi_P\Rightarrow\chi_Q</math>.<br />
<br />
It turns out, without much work, that this <math>P\Rightarrow Q</math> behaves just like classical implication in its relationship to <math>\wedge</math>.<br />
<br />
'''Membership''': <br />
We can internalize the notion of ''membership'' as a subobject <math>\in^A\subseteq A\times\Omega^A</math>, and thus get the membership relation from a pullback:<br />
:[[Image:ToposMembershipPullback.png]]<br />
<br />
For generalized elements <math>x\times h: T\to A\times\Omega^A</math>, we write <math>x\in^A h<math> for <math>x\times h\in\in^A</math>. Both notations indicate <math>ev_A\circ h\times x = true</math>.<br />
<br />
'''Universal quantification''':<br />
For any object <math>A</math>, the maximal subobject of <math>A</math> is <math>A</math> itself, embedded with <math>1_A</math> into itself. Thus, we have an arrow <math>t_A:1\to\Omega^A</math> representing this subobject. Being a map from <math>1</math>, it is specifically monic, so it has a classifying arrow <math>\forall_A:\Omega^A\to\Omega</math> that takes a given subobject of <math>A</math> to <math>true</math> precisely if it is in fact the maximal subobject.<br />
<br />
Now, with a relation <math>r:R\to B\times A</math>, we define <math>\forall a. R</math> by the following pullback:<br />
:[[Image:ToposForallPullback.png]]<br />
where <math>\lambda\chi_r</math> comes from the universal property of the exponential.<br />
<br />
'''Theorem''' For any <math>s:S\to B</math> monic, <math>S\subseteq \forall a.R</math> iff <math>S\times A\subseteq R</math>.<br />
<br />
This theorem tells us that the subobject given by <math>\forall a.R</math> is the largest subobject of <math>B</math> that is related by <math>R</math> to all of <math>A</math>.<br />
<br />
'''Falsum''':<br />
We can define the ''false'' truth value using these tools as <math>\forall w\in\Omega.w</math>. This might be familiar to the more advanced Haskell type hackers - as the type <br />
<haskell><br />
x :: forall a. a<br />
</haskell><br />
which has to be able to give us an element of any type, regardless of the type itself. And in Haskell, the only element that inhabits all types is <hask>undefined</hask>.<br />
<br />
From a logical perspective, we use a few basic inference rules:<br />
:[[Image:ToposTrivialSequent.png]] [[Image:ToposForallConnective.png]] [[Image:ToposSubstitution.png]]<br />
and connect them up to derive<br />
:<math>*</math><br />
:<math>\forall w.w : \forall w.w</math> <br />
:<math>\forall w.w : w</math><br />
:<math>\forall w.w : \phi</math><br />
for any <math>\phi</math> not involving <math>w</math> - and we can always adjust any <math>\phi</math> to avoid <math>w</math>.<br />
<br />
Thus, the formula <math>\forall w.w</math> has the property that it implies everything - and thus is a good candidate for the ''false'' truth value; since the inference<br />
:[[Image:ToposExFalsoQuodlibet.png]]<br />
is the defining introduction rule for false.<br />
<br />
<br />
'''Negation''':<br />
We define negation the same way as in classical logic: <math>\neg \phi = \phi \Rightarrow false</math>.<br />
<br />
<br />
'''Disjunction''':<br />
We can define <br />
:<math>P\vee Q = \forall w. ((\phi\Rightarrow w)\wedge(\psi\Rightarrow w))\Rightarrow w</math><br />
<br />
Note that this definition uses one of our primary inference rules:<br />
:[[Image:ToposDisjunctionConnective.png]]<br />
as the defining property for the disjunction, and we may derive any properties we like from these.<br />
<br />
'''Existential quantifier''':<br />
Finally, the existential quantifier is derived similarly to the disjunction - by figuring out a rule we want it to obey, and using that as a definition for it:<br />
:<math>\exists x.\phi = \forall w. (\forall x. \phi \Rightarrow w)\Rightarrow w</math><br />
<br />
Here, the rule we use as defining property is <br />
:[[Image:ToposExistentsConnective.png]]<br />
<br />
Before we leave this exploration of logic, some properties worth knowing about:<br />
While we can prove <math>\neg(\phi\wedge\neg\phi)</math> and <math>\phi\Rightarrow\neg\neg\phi</math>, we cannot, in just topos logic, prove things like<br />
:<math>\neg(\phi\wedge\psi)\Rightarrow(\neg\phi\vee\neg\psi)</math><br />
:<math>\neg\neg\phi\Rightarrow\phi</math><br />
nor any statements like<br />
:<math>\neg(\forall x.\neg\phi)\Rightarrow(\exists x.\phi)</math><br />
:<math>\neg(\forall x.\phi)\Rightarrow(\exists x.\neg\phi)</math><br />
:<math>\neg(\exists x.\neg\phi)\Rightarrow(\forall x.\phi)</math><br />
We can, though, prove<br />
:<math>\neg(\exists x.\phi)\Rightarrow(\forall x.\neg\phi)</math><br />
<br />
If we include, extra, an additional inference rule (called the ''Boolean negation rule'') given by<br />
:[[Image:BooleanNegation.png]]<br />
then suddenly we're back in classical logic, and can prove <math>\neg\neg\phi\Rightarrow\phi</math> and <math>\phi\or\neg\phi</math>.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31703User:Michiexile/MATH198/Lecture 102009-11-22T22:01:54Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega</math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
((universal property of power object?))<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that open sup for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bot\} = \emptyset</math><br />
:<math>\{x : (P \wedge Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P \vee Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
:<math>\{x : \exists y. P(x,y) \}</math> is given by the construction (...)<br />
:<math>\{x : \forall y. P(x,y) \}</math> is given by the construction (...)<br />
<br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\wedge = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>\vee = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
Given predicates <math>P, Q</math>, we define the ''conjunction'' <math>P\wedge Q</math> to be the pullback (pushout?)<br />
:[[Image:ToposConjunction.png]]<br />
<br />
This mimics, closely, the idea of the conjunction as an intersection.<br />
<br />
We further define the ''disjunction'' <math>P\vee Q</math> to be the pushout (pullback?)<br />
:[[Image:ToposDisjunction.png]]<br />
<br />
And we define ''negation'' <math>\neg P</math> by (...)<br />
<br />
We can expand this language further - and introduce predicative connectives. <br />
<br />
Now, a statement on the form <math>\forall x. P(x)</math> is usually taken to mean that on all <math>x\in U</math>, the predicate <math>P</math> holds true. Thus, translating to the operations-on-subsets paradigm, <math>\forall x. P(x)</math> corresponds to the statement <math>P = U</math>.<br />
<br />
((double check in Awodey & Barr-Wells!!!!))<br />
<br />
So we can define a topoidal <math>\forall x. P(x)</math> by ((diagrams))<br />
<br />
And similarily, the statement <math>\exists x. P(x)</math> means that <math>P</math> is non-empty.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31702User:Michiexile/MATH198/Lecture 102009-11-22T21:48:53Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega<math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
((universal property of power object?))<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, and predicate logic, we would say that a ''predicate'' is some function from a universe to a set of truth values. So a predicate takes some sort of objects, and returns either True or False.<br />
<br />
Furthermore, we allow the definition of sets using predicates:<br />
:<math>\{x\in U: P(x)\}</math><br />
<br />
Looking back, though, there is no essential difference between this, and defining the predicate as the subset of the universe directly; the predicate-as-function appears, then, as the characteristic function of the subset. And types are added as easily - we specify each variable, each object, to have a set it belongs to.<br />
<br />
This way, predicates really are subsets. Type annotations decide which set the predicate lives in. And we have everything set up in a way that open sup for the topos language above.<br />
<br />
We'd define, for predicates <math>P, Q</math> acting on the same type:<br />
:<math>\{x\in A : \top\} = A</math><br />
:<math>\{x\in A : \bottom\} = \emptyset</math><br />
:<math>\{x : (P \& Q)(x)\} = \{x : P(x)\} \cap \{x : Q(x)\}</math><br />
:<math>\{x : (P | Q)(x)\} = \{x : P(x)\} \cup \{x : Q(x)\}</math><br />
:<math>\{x\in A : (\neg P)(x) \} = A \setminus \{x\in A : P(x)\}</math><br />
:<math>\{x : \exists y. P(x,y) \}</math> is given by the construction (...)<br />
:<math>\{x : \forall y. P(x,y) \}</math> is given by the construction (...)<br />
<br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\& = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>| = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
Given predicates <math>P, Q</math>, we define the ''conjunction'' <math>P\wedge Q</math> to be the pullback (pushout?)<br />
:[[Image:ToposConjunction.png]]<br />
<br />
This mimics, closely, the idea of the conjunction as an intersection.<br />
<br />
We further define the ''disjunction'' <math>P\vee Q</math> to be the pushout (pullback?)<br />
:[[Image:ToposDisjunction.png]]<br />
<br />
And we define ''negation'' <math>\neg P</math> by (...)<br />
<br />
We can expand this language further - and introduce predicative connectives. <br />
<br />
Now, a statement on the form <math>\forall x. P(x)</math> is usually taken to mean that on all <math>x\in U</math>, the predicate <math>P</math> holds true. Thus, translating to the operations-on-subsets paradigm, <math>\forall x. P(x)</math> corresponds to the statement <math>P = U</math>.<br />
<br />
((double check in Awodey & Barr-Wells!!!!))<br />
<br />
So we can define a topoidal <math>\forall x. P(x)</math> by ((diagrams))<br />
<br />
And similarily, the statement <math>\exists x. P(x)</math> means that <math>P</math> is non-empty.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31701User:Michiexile/MATH198/Lecture 102009-11-22T18:43:29Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
This lecture will be shallow, and leave many things undefined, hinted at, and is mostly meant as an appetizer, enticing the audience to go forth and seek out the literature on topos theory for further studies.<br />
<br />
===Subobject classifier===<br />
<br />
One very useful property of the category <math>Set</math> is that the powerset of a given set is still a set; we have an internal concept of ''object of all subobjects''. Certainly, for any category (small enough) <math>C</math>, we have a contravariant functor <math>Sub(-): C\to Set</math> taking an object to the set of all equivalence classes of monomorphisms into that object; with the image <math>Sub(f)</math> given by the pullback diagram<br />
:[[Image:SubobjectFunctorMorphismPullback.png]]<br />
<br />
If the functor <math>Sub(-)</math> is ''representable'' - meaning that there is some object <math>X\in C_0</math> such that <math>Sub(-) = hom(-,X)</math> - then the theory surrounding representable functors, connected to the Yoneda lemma - give us a number of good properties.<br />
<br />
One of them is that every representable functor has a ''universal element''; a generalization of the kind of universal mapping properties we've seen in definitions over and over again during this course; all the definitions that posit the unique existence of some arrow in some diagram given all other arrows.<br />
<br />
Thus, in a category with a representable subobject functor, we can pick a representing object <math>\Omega\in C_0</math>, such that <math>Sub(X) = hom(X,\Omega)</math>. Furthermore, picking a universal element corresponds to picking a subobject <math>\Omega_0\hookrightarrow\Omega</math> such that for any object <math>A</math> and subobject <math>A_0\hookrightarrow A</math>, there is a unique arrow <math>\chi: A\to\Omega</math> such that there is a pullback diagram<br />
:[[Image:SubobjectClassifierPullback.png]]<br />
<br />
One can prove that <math>\Omega_0</math> is terminal in <math>C</math>, and we shall call <math>\Omega<math> the ''subobject classifier'', and this arrow <math>\Omega_0=1\to\Omega</math> ''true''. The arrow <math>\chi</math> is called the characteristic arrow of the subobject.<br />
<br />
In Set, all this takes on a familiar tone: the subobject classifier is a 2-element set, with a ''true'' element distinguished; and a characteristic function of a subset takes on the ''true'' value for every element in the subset, and the other (false) value for every element not in the subset.<br />
<br />
===Defining topoi===<br />
<br />
'''Definition''' A ''topos'' is a cartesian closed category with all finite limits and with a subobject classifier.<br />
<br />
It is worth noting that this is a far stronger condition than anything we can even hope to fulfill for the category of Haskell types and functions. The functional proogramming relevance will take a back seat in this lecture, in favour of usefulness in logic and set theory replacements.<br />
<br />
===Properties of topoi===<br />
<br />
The meat is in the properties we can prove about topoi, and in the things that turn out to be topoi. <br />
<br />
'''Theorem''' Let <math>E</math> be a topos. <br />
* <math>E</math> has finite colimits.<br />
<br />
====Power object====<br />
<br />
Since a topos is closed, we can take exponentials. Specifically, we can consider <math>[A\to\Omega]</math>. This is an object such that <math>hom(B,[A\to\Omega]) = hom(A\times B, \Omega) = Sub(A\times B)</math>. Hence, we get an internal version of the subobject functor. (pick <math>B</math> to be the terminal object to get a sense for how global elements of <math>[A\to\Omega]</math> correspond to subobjects of <math>A</math>)<br />
<br />
((universal property of power object?))<br />
<br />
====Internal logic====<br />
<br />
We can use the properties of a topos to develop a logic theory - mimicking the development of logic by considering operations on subsets in a given universe:<br />
<br />
Classically, in Set, we would say that a ''predicate'' corresponds to the set of elements on which the predicate holds true. Thus, say, for statements about integers, the set <math>\{n\in\mathbb Z: n>0\}</math> would correspond to the predicate <math>n>0</math>.<br />
<br />
We could then start to define primitive logic connectives as set operations; the intersection of two sets is the set on which '''both''' the corresponding predicates hold true, so <math>\& = \cap</math>. Similarily, the union of two sets is the set on which either of the corresponding predicates holds true, so <math>| = \cup</math>. The complement of a set, in the universe, is the negation of the predicate, and all other propositional connectives (implication, equivalence, ...) can be built with conjunction (and), disjunction (or) and negation (not).<br />
<br />
So we can mimic all these in a given topos:<br />
<br />
We say that a ''universe'' <math>U</math> is just an object in a given topos. <br />
<br />
A ''predicate'' is a subobject of the universe.<br />
<br />
Given predicates <math>P, Q</math>, we define the ''conjunction'' <math>P\wedge Q</math> to be the pullback (pushout?)<br />
:[[Image:ToposConjunction.png]]<br />
<br />
This mimics, closely, the idea of the conjunction as an intersection.<br />
<br />
We further define the ''disjunction'' <math>P\vee Q</math> to be the pushout (pullback?)<br />
:[[Image:ToposDisjunction.png]]<br />
<br />
And we define ''negation'' <math>\neg P</math> by (...)<br />
<br />
We can expand this language further - and introduce predicative connectives. <br />
<br />
Now, a statement on the form <math>\forall x. P(x)</math> is usually taken to mean that on all <math>x\in U</math>, the predicate <math>P</math> holds true. Thus, translating to the operations-on-subsets paradigm, <math>\forall x. P(x)</math> corresponds to the statement <math>P = U</math>.<br />
<br />
((double check in Awodey & Barr-Wells!!!!))<br />
<br />
So we can define a topoidal <math>\forall x. P(x)</math> by ((diagrams))<br />
<br />
And similarily, the statement <math>\exists x. P(x)</math> means that <math>P</math> is non-empty.<br />
<br />
====Examples====<br />
<br />
====Sheaves, topology and time sheaves====<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_10&diff=31626User:Michiexile/MATH198/Lecture 102009-11-17T18:44:57Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Power objects===<br />
<br />
===Classifying objects===<br />
<br />
===Topoi===<br />
<br />
===Internal logic===<br />
<br />
===Exercises===<br />
<br />
No homework at this point. However, if you want something to think about, a few questions and exercises:<br />
<br />
# blah</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198&diff=31625User:Michiexile/MATH1982009-11-17T18:43:14Z<p>Michiexile: </p>
<hr />
<div>==Course overview==<br />
<br />
Page is work in progress for background material for the Fall 2009 lecture course MATH198[http://coursework.stanford.edu/homepage/F09/F09-MATH-198-01.html] on Category Theory and Functional Programming that I am planning to give at Stanford University.<br />
<br />
Single unit course. 10 lectures. Each lecture is Wednesday 4.15-5.05 in 380F.<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 1]]<br />
** Category: Definition and examples.<br />
** Concrete categories.<br />
*** Set.<br />
*** Various categories capturing linear algebra.<br />
** Small categories.<br />
*** Partial orders.<br />
*** Monoids.<br />
*** Finite groups.<br />
** Haskell-Curry isomorphism.<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 2]]<br />
** Special morphisms<br />
*** Epimorphism.<br />
*** Monomorphism.<br />
*** Isomorphism.<br />
*** Endomorphism.<br />
*** Automorphism.<br />
** Special objects<br />
*** Initial. <br />
*** Terminal. <br />
*** Null.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 3]]<br />
** Functors.<br />
** Category of categories.<br />
** Natural transformations.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 4]]<br />
** Products, coproducts.<br />
** The power of dualization.<br />
** The algebra of datatypes<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 5]]<br />
** Limits, colimits.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 6]]<br />
** Equalizers, coequalizers.<br />
** Pushouts/pullbacks<br />
** Adjunctions.<br />
** Free and forgetful.<br />
<br />
<br />
* [[User:Michiexile/MATH198/Lecture 7]]<br />
** Monoid objects.<br />
** Monads.<br />
** Triples.<br />
** Kleisli category.<br />
** Monad factorization.<br />
<br />
* [[User:Michiexile/MATH198/Lecture 8]]<br />
** Algebras over monads<br />
** Algebras over endofunctors<br />
** Initial algebras and recursion<br />
** Lambek's lemma<br />
<br />
* [[User:Michiexile/MATH198/Lecture 9]]<br />
** Catamorphisms<br />
** Anamorphisms<br />
** Hylomorphisms<br />
** Metamorphisms<br />
** Paramorphisms<br />
** Apomorphisms<br />
** Properties of adjunctions, examples of adjunctions<br />
<br />
* [[User:Michiexile/MATH198/Lecture 10]]<br />
** Power objects<br />
** Classifying objects<br />
** Topoi<br />
** Internal logic</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31624User:Michiexile/MATH198/Lecture 92009-11-17T18:40:38Z<p>Michiexile: </p>
<hr />
<div>===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana :: (b -> F a b) -> b -> T a<br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
Again, we can note that the implementation of <hask>fpsi</hask> here is exactly the <hask>c</hask> above, and the resulting function will - as we can verify by compiling and running - give us the same kind of reversed list of the n first integers as the <hask>first</hask> function above would.<br />
<br />
====Hylomorphisms====<br />
<br />
The ''hylomorphisms'' capture one of the two possible compositions of anamorphisms and catamorphisms. Parametrized over an algebra <math>\phi: T A\to A</math> and a coalgebra <math>\psi: B \to T B</math> the hylomorphism is a recursion pattern that computes a value in <math>A</math> from a value in <math>A</math> by generating some sort of intermediate structure and then collapsing it again.<br />
<br />
It is, thus the composition of the uniquely existing morphism from a coalgebra to the final coalgebra for an endofunctor, followed by the uniquely existing morphism from the initial algebra to some other algebra.<br />
<br />
MFP define it, again, as a fix point: <br />
<haskell><br />
hylo :: (F a b2 -> b2) -> (b1 -> F a b1) -> b1 -> b2<br />
hylo phi psi = mu (\x -> phi . fmap x . psi)<br />
</haskell><br />
<br />
First off, we can observe that by picking one or the other of <math>in_A, out_A</math> as a parameter, we can recover both the anamorphisms and the catamorphisms as hylomorphisms.<br />
<br />
As an example, we'll compute the factorial function using a hylomorphism:<br />
<br />
<haskell><br />
phi :: F Int Int -> Int<br />
phi Nil = 1<br />
phi (Cons n m) = n*m<br />
<br />
psi :: Int -> F Int Int<br />
psi 0 = Int<br />
psi n = Cons n (n-1)<br />
<br />
factorial = hylo phi psi<br />
</haskell><br />
<br />
====Metamorphisms====<br />
<br />
The ''metamorphism'' is the ''other'' composition of an anamorphism with a catamorphism. It takes some structure, deconstructs it, and then reconstructs a new structure from it. <br />
<br />
As a recursion pattern, it's kinda boring - it'll take an interesting structure, deconstruct it into a ''scalar'' value, and then reconstruct some structure from that scalar. As such, it won't even capture the richness of <math>hom(F x, G y)</math>, since any morphism expressed as a metamorphism will factor through a map <math>x\to y</math>.<br />
<br />
====Paramorphisms====<br />
<br />
''Paramorphisms'' were discussed in the MFP paper as a way to extend the catamorphisms so that the operating function can access its arguments in computation as well as in recursion. We gave the factorial above as a hylomorphism instead of a catamorphism precisely because no simple enough catamorphic structure exists.<br />
<br />
====Apomorphisms====<br />
<br />
The ''apomorphism'' is the dual of the paramorphism - it does with retention of values along the way what anamorphisms do compared to catamorphisms.<br />
<br />
===Further reading===<br />
<br />
* Erik Meijer, Maarten Fokkinga, Ross Paterson: ''Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire'' [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.41.125&rep=rep1&type=pdf]<br />
* L. Augusteijn: ''Sorting morphisms'' [http://www.springerlink.com/index/w543447353067h67.pdf]<br />
<br />
===Further properties of adjunctions===<br />
<br />
====RAPL====<br />
<br />
'''Proposition''' If <math>F</math> is a ''right adjoint'', thus if <math>F</math> has a left adjoint, then <math>F</math> preserves limits in the sense that <math>F(\lim_{\leftarrow} A_i) = \lim_{\leftarrow} F(A_i)</math>.<br />
<br />
Example: <math>(\lim_{\leftarrow_i} A_i)\times X = \lim_{\leftarrow_i} A_i\times X</math>. <br />
<br />
We can use this to prove that things cannot be adjoints - since all right adjoints preserve limits, if a functor <math>G</math> doesn't preserve limits, then it doesn't have a left adjoint.<br />
<br />
Similarly, and dually, left adjoints preserve colimits. Thus if a functor doesn't preserve colimits, it cannot be a left adjoint, thus cannot have a right adjoint.<br />
<br />
The proof of these statements build on the ''Yoneda lemma'': <br />
<br />
'''Lemma''' If <math>C</math> is a locally small category (i.e. all hom-sets are sets). Then for any <math>c\in C_0</math> and any functor <math>F: C^{op}\to Sets</math> there is an isomorphism<br />
:<math>hom_{hom_{Sets^{C^{op}}}}(yC, F) = FC</math><br />
where we define <math>yC = d\mapsto hom_C(d,c) : C^{op}\to Sets</math>.<br />
<br />
The Yoneda lemma has one important corollary: <br />
<br />
'''Corollary''' If <math>yA = yB</math> then <math>A = B</math>.<br />
<br />
Which, in turn has a number of important corollaries:<br />
<br />
'''Corollary''' <math>(A^B)^C = A^{B\times C}</math><br />
<br />
'''Corollary''' Adjoints are unique up to isomorphism - in particular, if <math>F: C\to D</math> is a functor with right adjoints <math>U, V: D\to C</math>, then <math>U = V</math>.<br />
<br />
'''Proof''' <math>hom_C(C, UD) = hom_D(FC, D) = hom_C(C, VD)</math>, and thus by the corollary to the Yoneda lemma, <math>UD = VD</math>, natural in <math>D</math>. <br />
<br />
====Functors that are adjoints====<br />
<br />
* The functor <math>X\mapsto X\times A</math> has right adjoint <math>Y\mapsto Y^A</math>. The universal mapping property of the exponentials follows from the adjointness property.<br />
* The functor <math>\Delta: C\to C\times C, c\mapsto (c,c)</math> has a left adjoint given by the coproduct <math>(X,Y)\mapsto X + Y</math> and right adjoint the product <math>(X,Y)\mapsto X\times Y</math>.<br />
* More generally, the functor <math>C\to C^J</math> that takes <math>c</math> to the constant functor <math>const_c(j) = c, const_c(f) = 1_c</math> has left andright adjoints given by colimits and limits:<br />
:<math>\lim_\rightarrow -| \Delta -| \lim_\leftarrow</math><br />
* Pointed rings are pairs <math>(R, r\in R)</math> of rings and one element singled out for attention. Homomorphisms of pointed rings need to take the distinguished point to the distinguished point. There is an obvious forgetful functor <math>U: Rings_* \to Rings</math>, and this has a left adjoint - a free ring functor that adjoins a new indeterminate <math>R\mapsto (R[x], x)</math>. This gives a formal definition of what we mean by ''formal polynomial expressions'' et.c.<br />
* Given sets <math>A, B</math>, we can consider the powersets <math>P(A), P(B)</math> containing, as elements, all subsets of <math>A, B</math> respectively. Suppose <math>f:A\to B</math> is a function, then <math>f^{-1}: P(B)\to P(A)</math> takes subsets of <math>B</math> to subsets of <math>A</math>. <br />
:Viewing <math>P(A)</math> and <math>P(B)</math> as partially ordered sets by the inclusion operations, and then as categories induced by the partial order, <math>f^{-1}</math> turns into a functor between partial orders. And it turns out <math>f^{-1}</math> has a left adjoint given by the operation <math>im(f)</math> taking a subset to the set of images under the function <math>f</math>. And it has a right adjoint <math>f_*(U) = \{b\in B: f^{-1}(b)\subseteq U\}</math><br />
* We can introduce a categorical structure to logic. We let <math>L</math> be a formal language, say of predicate logic. Then for any list <math>x = x_1, x_2, ..., x_n</math> of variables, we have a preorder <math>Form(x)</math> of formulas with no free variables not occuring in <math>x</math>. The preorder on <math>Form(x)</math> comes from the ''entailment'' operation - <math> f |- g</math> if in every interpretation of the language, <math>f \Rightarrow g</math>.<br />
: We can build an operation on these preorders - a functor on the underlying categories - by adjoining a single new variable: <math>*: Form(x) \to Form(x, y)</math>, sending each form to itself. Obviously, if <math>f |- g</math> with <math>x</math> the source of free variables, if we introduce a new allowable free variable, but don't actually change the formulas, the entailment stays the same.<br />
: It turns out that there is a right adjoint to <math>*</math> given by <math>f\mapsto \forall y. f</math>. And a left adjoint to <math>*</math> given by <math>f\mapsto \exists y. f</math>. Adjointness properties give us classical deduction rules from logic.<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# Write the fibonacci function as a hylomorphism.<br />
# Write the Towers of Hanoi as a hylomorphism. You'll probably want to use binary trees as the intermediate data structure.<br />
# Write a prime numbers generator as an anamorphism.<br />
# * The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.<br />
:''Hint'': You will be helped by having a function to generate a list of all primes. One suggestion is:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
:''Hint'': A good data structure to use is; with expected output of running the algorithm:<br />
<haskell><br />
data Tree = Leaf Integer | Node Integer [Tree]<br />
<br />
divisionTree 60 = <br />
Node 60 [<br />
Node 30 [<br />
Node 15 [<br />
Leaf 5,<br />
Leaf 3],<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2]],<br />
Node 20 [<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]],<br />
Node 12 [<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]]]<br />
</haskell></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31623User:Michiexile/MATH198/Lecture 92009-11-17T18:40:00Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana :: (b -> F a b) -> b -> T a<br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
Again, we can note that the implementation of <hask>fpsi</hask> here is exactly the <hask>c</hask> above, and the resulting function will - as we can verify by compiling and running - give us the same kind of reversed list of the n first integers as the <hask>first</hask> function above would.<br />
<br />
====Hylomorphisms====<br />
<br />
The ''hylomorphisms'' capture one of the two possible compositions of anamorphisms and catamorphisms. Parametrized over an algebra <math>\phi: T A\to A</math> and a coalgebra <math>\psi: B \to T B</math> the hylomorphism is a recursion pattern that computes a value in <math>A</math> from a value in <math>A</math> by generating some sort of intermediate structure and then collapsing it again.<br />
<br />
It is, thus the composition of the uniquely existing morphism from a coalgebra to the final coalgebra for an endofunctor, followed by the uniquely existing morphism from the initial algebra to some other algebra.<br />
<br />
MFP define it, again, as a fix point: <br />
<haskell><br />
hylo :: (F a b2 -> b2) -> (b1 -> F a b1) -> b1 -> b2<br />
hylo phi psi = mu (\x -> phi . fmap x . psi)<br />
</haskell><br />
<br />
First off, we can observe that by picking one or the other of <math>in_A, out_A</math> as a parameter, we can recover both the anamorphisms and the catamorphisms as hylomorphisms.<br />
<br />
As an example, we'll compute the factorial function using a hylomorphism:<br />
<br />
<haskell><br />
phi :: F Int Int -> Int<br />
phi Nil = 1<br />
phi (Cons n m) = n*m<br />
<br />
psi :: Int -> F Int Int<br />
psi 0 = Int<br />
psi n = Cons n (n-1)<br />
<br />
factorial = hylo phi psi<br />
</haskell><br />
<br />
====Metamorphisms====<br />
<br />
The ''metamorphism'' is the ''other'' composition of an anamorphism with a catamorphism. It takes some structure, deconstructs it, and then reconstructs a new structure from it. <br />
<br />
As a recursion pattern, it's kinda boring - it'll take an interesting structure, deconstruct it into a ''scalar'' value, and then reconstruct some structure from that scalar. As such, it won't even capture the richness of <math>hom(F x, G y)</math>, since any morphism expressed as a metamorphism will factor through a map <math>x\to y</math>.<br />
<br />
====Paramorphisms====<br />
<br />
''Paramorphisms'' were discussed in the MFP paper as a way to extend the catamorphisms so that the operating function can access its arguments in computation as well as in recursion. We gave the factorial above as a hylomorphism instead of a catamorphism precisely because no simple enough catamorphic structure exists.<br />
<br />
====Apomorphisms====<br />
<br />
The ''apomorphism'' is the dual of the paramorphism - it does with retention of values along the way what anamorphisms do compared to catamorphisms.<br />
<br />
===Further reading===<br />
<br />
* Erik Meijer, Maarten Fokkinga, Ross Paterson: ''Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire'' [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.41.125&rep=rep1&type=pdf]<br />
* L. Augusteijn: ''Sorting morphisms'' [http://www.springerlink.com/index/w543447353067h67.pdf]<br />
<br />
===Further properties of adjunctions===<br />
<br />
====RAPL====<br />
<br />
'''Proposition''' If <math>F</math> is a ''right adjoint'', thus if <math>F</math> has a left adjoint, then <math>F</math> preserves limits in the sense that <math>F(\lim_{\leftarrow} A_i) = \lim_{\leftarrow} F(A_i)</math>.<br />
<br />
Example: <math>(\lim_{\leftarrow_i} A_i)\times X = \lim_{\leftarrow_i} A_i\times X</math>. <br />
<br />
We can use this to prove that things cannot be adjoints - since all right adjoints preserve limits, if a functor <math>G</math> doesn't preserve limits, then it doesn't have a left adjoint.<br />
<br />
Similarly, and dually, left adjoints preserve colimits. Thus if a functor doesn't preserve colimits, it cannot be a left adjoint, thus cannot have a right adjoint.<br />
<br />
The proof of these statements build on the ''Yoneda lemma'': <br />
<br />
'''Lemma''' If <math>C</math> is a locally small category (i.e. all hom-sets are sets). Then for any <math>c\in C_0</math> and any functor <math>F: C^{op}\to Sets</math> there is an isomorphism<br />
:<math>hom_{hom_{Sets^{C^{op}}}}(yC, F) = FC</math><br />
where we define <math>yC = d\mapsto hom_C(d,c) : C^{op}\to Sets</math>.<br />
<br />
The Yoneda lemma has one important corollary: <br />
<br />
'''Corollary''' If <math>yA = yB</math> then <math>A = B</math>.<br />
<br />
Which, in turn has a number of important corollaries:<br />
<br />
'''Corollary''' <math>(A^B)^C = A^{B\times C}</math><br />
<br />
'''Corollary''' Adjoints are unique up to isomorphism - in particular, if <math>F: C\to D</math> is a functor with right adjoints <math>U, V: D\to C</math>, then <math>U = V</math>.<br />
<br />
'''Proof''' <math>hom_C(C, UD) = hom_D(FC, D) = hom_C(C, VD)</math>, and thus by the corollary to the Yoneda lemma, <math>UD = VD</math>, natural in <math>D</math>. <br />
<br />
====Functors that are adjoints====<br />
<br />
* The functor <math>X\mapsto X\times A</math> has right adjoint <math>Y\mapsto Y^A</math>. The universal mapping property of the exponentials follows from the adjointness property.<br />
* The functor <math>\Delta: C\to C\times C, c\mapsto (c,c)</math> has a left adjoint given by the coproduct <math>(X,Y)\mapsto X + Y</math> and right adjoint the product <math>(X,Y)\mapsto X\times Y</math>.<br />
* More generally, the functor <math>C\to C^J</math> that takes <math>c</math> to the constant functor <math>const_c(j) = c, const_c(f) = 1_c</math> has left andright adjoints given by colimits and limits:<br />
:<math>\lim_\rightarrow -| \Delta -| \lim_\leftarrow</math><br />
* Pointed rings are pairs <math>(R, r\in R)</math> of rings and one element singled out for attention. Homomorphisms of pointed rings need to take the distinguished point to the distinguished point. There is an obvious forgetful functor <math>U: Rings_* \to Rings</math>, and this has a left adjoint - a free ring functor that adjoins a new indeterminate <math>R\mapsto (R[x], x)</math>. This gives a formal definition of what we mean by ''formal polynomial expressions'' et.c.<br />
* Given sets <math>A, B</math>, we can consider the powersets <math>P(A), P(B)</math> containing, as elements, all subsets of <math>A, B</math> respectively. Suppose <math>f:A\to B</math> is a function, then <math>f^{-1}: P(B)\to P(A)</math> takes subsets of <math>B</math> to subsets of <math>A</math>. <br />
:Viewing <math>P(A)</math> and <math>P(B)</math> as partially ordered sets by the inclusion operations, and then as categories induced by the partial order, <math>f^{-1}</math> turns into a functor between partial orders. And it turns out <math>f^{-1}</math> has a left adjoint given by the operation <math>im(f)</math> taking a subset to the set of images under the function <math>f</math>. And it has a right adjoint <math>f_*(U) = \{b\in B: f^{-1}(b)\subseteq U\}</math><br />
* We can introduce a categorical structure to logic. We let <math>L</math> be a formal language, say of predicate logic. Then for any list <math>x = x_1, x_2, ..., x_n</math> of variables, we have a preorder <math>Form(x)</math> of formulas with no free variables not occuring in <math>x</math>. The preorder on <math>Form(x)</math> comes from the ''entailment'' operation - <math> f |- g</math> if in every interpretation of the language, <math>f \Rightarrow g</math>.<br />
: We can build an operation on these preorders - a functor on the underlying categories - by adjoining a single new variable: <math>*: Form(x) \to Form(x, y)</math>, sending each form to itself. Obviously, if <math>f |- g</math> with <math>x</math> the source of free variables, if we introduce a new allowable free variable, but don't actually change the formulas, the entailment stays the same.<br />
: It turns out that there is a right adjoint to <math>*</math> given by <math>f\mapsto \forall y. f</math>. And a left adjoint to <math>*</math> given by <math>f\mapsto \exists y. f</math>. Adjointness properties give us classical deduction rules from logic.<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# Write the fibonacci function as a hylomorphism.<br />
# Write the Towers of Hanoi as a hylomorphism. You'll probably want to use binary trees as the intermediate data structure.<br />
# Write a prime numbers generator as an anamorphism.<br />
# * The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.<br />
:''Hint'': You will be helped by having a function to generate a list of all primes. One suggestion is:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
:''Hint'': A good data structure to use is; with expected output of running the algorithm:<br />
<haskell><br />
data Tree = Leaf Integer | Node Integer [Tree]<br />
<br />
divisionTree 60 = <br />
Node 60 [<br />
Node 30 [<br />
Node 15 [<br />
Leaf 5,<br />
Leaf 3],<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2]],<br />
Node 20 [<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]],<br />
Node 12 [<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]]]<br />
</haskell></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:CoalgebraMorphism.png&diff=31622File:CoalgebraMorphism.png2009-11-17T18:39:04Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31621User:Michiexile/MATH198/Lecture 92009-11-17T18:34:17Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
* MFP write <math>(f\Delta g)</math> for<br />
<haskell><br />
Delta f g = \x -> (f x, g x)<br />
</haskell><br />
* MFP write <math>(f\nabla g) x</math> for<br />
<haskell><br />
(Nabla f g) (Left x) = f x<br />
(Nabla f g) (Right x) = g x<br />
</haskell><br />
<br />
These two last constructions are directly motivated by the maps induced from the universal properties of products and coproducts.<br />
<br />
We shall write <math>(f\times g)</math> and <math>(f+g)</math> for the <math>\Delta</math> and <math>\nabla</math> constructions, respectively.<br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana :: (b -> F a b) -> b -> T a<br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
Again, we can note that the implementation of <hask>fpsi</hask> here is exactly the <hask>c</hask> above, and the resulting function will - as we can verify by compiling and running - give us the same kind of reversed list of the n first integers as the <hask>first</hask> function above would.<br />
<br />
====Hylomorphisms====<br />
<br />
The ''hylomorphisms'' capture one of the two possible compositions of anamorphisms and catamorphisms. Parametrized over an algebra <math>\phi: T A\to A</math> and a coalgebra <math>\psi: B \to T B</math> the hylomorphism is a recursion pattern that computes a value in <math>A</math> from a value in <math>A</math> by generating some sort of intermediate structure and then collapsing it again.<br />
<br />
It is, thus the composition of the uniquely existing morphism from a coalgebra to the final coalgebra for an endofunctor, followed by the uniquely existing morphism from the initial algebra to some other algebra.<br />
<br />
MFP define it, again, as a fix point: <br />
<haskell><br />
hylo :: (F a b2 -> b2) -> (b1 -> F a b1) -> b1 -> b2<br />
hylo phi psi = mu (\x -> phi . fmap x . psi)<br />
</haskell><br />
<br />
First off, we can observe that by picking one or the other of <math>in_A, out_A</math> as a parameter, we can recover both the anamorphisms and the catamorphisms as hylomorphisms.<br />
<br />
As an example, we'll compute the factorial function using a hylomorphism:<br />
<br />
<haskell><br />
phi :: F Int Int -> Int<br />
phi Nil = 1<br />
phi (Cons n m) = n*m<br />
<br />
psi :: Int -> F Int Int<br />
psi 0 = Int<br />
psi n = Cons n (n-1)<br />
<br />
factorial = hylo phi psi<br />
</haskell><br />
<br />
====Metamorphisms====<br />
<br />
The ''metamorphism'' is the ''other'' composition of an anamorphism with a catamorphism. It takes some structure, deconstructs it, and then reconstructs a new structure from it. <br />
<br />
As a recursion pattern, it's kinda boring - it'll take an interesting structure, deconstruct it into a ''scalar'' value, and then reconstruct some structure from that scalar. As such, it won't even capture the richness of <math>hom(F x, G y)</math>, since any morphism expressed as a metamorphism will factor through a map <math>x\to y</math>.<br />
<br />
====Paramorphisms====<br />
<br />
''Paramorphisms'' were discussed in the MFP paper as a way to extend the catamorphisms so that the operating function can access its arguments in computation as well as in recursion. We gave the factorial above as a hylomorphism instead of a catamorphism precisely because no simple enough catamorphic structure exists.<br />
<br />
====Apomorphisms====<br />
<br />
The ''apomorphism'' is the dual of the paramorphism - it does with retention of values along the way what anamorphisms do compared to catamorphisms.<br />
<br />
===Further reading===<br />
<br />
* Erik Meijer, Maarten Fokkinga, Ross Paterson: ''Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire'' [http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.41.125&rep=rep1&type=pdf]<br />
* L. Augusteijn: ''Sorting morphisms'' [http://www.springerlink.com/index/w543447353067h67.pdf]<br />
<br />
===Further properties of adjunctions===<br />
<br />
====RAPL====<br />
<br />
'''Proposition''' If <math>F</math> is a ''right adjoint'', thus if <math>F</math> has a left adjoint, then <math>F</math> preserves limits in the sense that <math>F(\lim_{\leftarrow} A_i) = \lim_{\leftarrow} F(A_i)</math>.<br />
<br />
Example: <math>(\lim_{\leftarrow_i} A_i)\times X = \lim_{\leftarrow_i} A_i\times X</math>. <br />
<br />
We can use this to prove that things cannot be adjoints - since all right adjoints preserve limits, if a functor <math>G</math> doesn't preserve limits, then it doesn't have a left adjoint.<br />
<br />
Similarly, and dually, left adjoints preserve colimits. Thus if a functor doesn't preserve colimits, it cannot be a left adjoint, thus cannot have a right adjoint.<br />
<br />
The proof of these statements build on the ''Yoneda lemma'': <br />
<br />
'''Lemma''' If <math>C</math> is a locally small category (i.e. all hom-sets are sets). Then for any <math>c\in C_0</math> and any functor <math>F: C^{op}\to Sets</math> there is an isomorphism<br />
:<math>hom_{hom_{Sets^{C^{op}}}}(yC, F) = FC</math><br />
where we define <math>yC = d\mapsto hom_C(d,c) : C^{op}\to Sets</math>.<br />
<br />
The Yoneda lemma has one important corollary: <br />
<br />
'''Corollary''' If <math>yA = yB</math> then <math>A = B</math>.<br />
<br />
Which, in turn has a number of important corollaries:<br />
<br />
'''Corollary''' <math>(A^B)^C = A^{B\times C}</math><br />
<br />
'''Corollary''' Adjoints are unique up to isomorphism - in particular, if <math>F: C\to D</math> is a functor with right adjoints <math>U, V: D\to C</math>, then <math>U = V</math>.<br />
<br />
'''Proof''' <math>hom_C(C, UD) = hom_D(FC, D) = hom_C(C, VD)</math>, and thus by the corollary to the Yoneda lemma, <math>UD = VD</math>, natural in <math>D</math>. <br />
<br />
====Functors that are adjoints====<br />
<br />
* The functor <math>X\mapsto X\times A</math> has right adjoint <math>Y\mapsto Y^A</math>. The universal mapping property of the exponentials follows from the adjointness property.<br />
* The functor <math>\Delta: C\to C\times C, c\mapsto (c,c)</math> has a left adjoint given by the coproduct <math>(X,Y)\mapsto X + Y</math> and right adjoint the product <math>(X,Y)\mapsto X\times Y</math>.<br />
* More generally, the functor <math>C\to C^J</math> that takes <math>c</math> to the constant functor <math>const_c(j) = c, const_c(f) = 1_c</math> has left andright adjoints given by colimits and limits:<br />
:<math>\lim_\rightarrow -| \Delta -| \lim_\leftarrow</math><br />
* Pointed rings are pairs <math>(R, r\in R)</math> of rings and one element singled out for attention. Homomorphisms of pointed rings need to take the distinguished point to the distinguished point. There is an obvious forgetful functor <math>U: Rings_* \to Rings</math>, and this has a left adjoint - a free ring functor that adjoins a new indeterminate <math>R\mapsto (R[x], x)</math>. This gives a formal definition of what we mean by ''formal polynomial expressions'' et.c.<br />
* Given sets <math>A, B</math>, we can consider the powersets <math>P(A), P(B)</math> containing, as elements, all subsets of <math>A, B</math> respectively. Suppose <math>f:A\to B</math> is a function, then <math>f^{-1}: P(B)\to P(A)</math> takes subsets of <math>B</math> to subsets of <math>A</math>. <br />
:Viewing <math>P(A)</math> and <math>P(B)</math> as partially ordered sets by the inclusion operations, and then as categories induced by the partial order, <math>f^{-1}</math> turns into a functor between partial orders. And it turns out <math>f^{-1}</math> has a left adjoint given by the operation <math>im(f)</math> taking a subset to the set of images under the function <math>f</math>. And it has a right adjoint <math>f_*(U) = \{b\in B: f^{-1}(b)\subseteq U\}</math><br />
* We can introduce a categorical structure to logic. We let <math>L</math> be a formal language, say of predicate logic. Then for any list <math>x = x_1, x_2, ..., x_n</math> of variables, we have a preorder <math>Form(x)</math> of formulas with no free variables not occuring in <math>x</math>. The preorder on <math>Form(x)</math> comes from the ''entailment'' operation - <math> f |- g</math> if in every interpretation of the language, <math>f \Rightarrow g</math>.<br />
: We can build an operation on these preorders - a functor on the underlying categories - by adjoining a single new variable: <math>*: Form(x) \to Form(x, y)</math>, sending each form to itself. Obviously, if <math>f |- g</math> with <math>x</math> the source of free variables, if we introduce a new allowable free variable, but don't actually change the formulas, the entailment stays the same.<br />
: It turns out that there is a right adjoint to <math>*</math> given by <math>f\mapsto \forall y. f</math>. And a left adjoint to <math>*</math> given by <math>f\mapsto \exists y. f</math>. Adjointness properties give us classical deduction rules from logic.<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# Write the fibonacci function as a hylomorphism.<br />
# Write the Towers of Hanoi as a hylomorphism. You'll probably want to use binary trees as the intermediate data structure.<br />
# Write a prime numbers generator as an anamorphism.<br />
# * The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.<br />
:''Hint'': You will be helped by having a function to generate a list of all primes. One suggestion is:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
:''Hint'': A good data structure to use is; with expected output of running the algorithm:<br />
<haskell><br />
data Tree = Leaf Integer | Node Integer [Tree]<br />
<br />
divisionTree 60 = <br />
Node 60 [<br />
Node 30 [<br />
Node 15 [<br />
Leaf 5,<br />
Leaf 3],<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2]],<br />
Node 20 [<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]],<br />
Node 12 [<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]]]<br />
</haskell></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31618User:Michiexile/MATH198/Lecture 92009-11-17T18:03:33Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
* MFP write <math>(f\Delta g)</math> for<br />
<haskell><br />
Delta f g = \x -> (f x, g x)<br />
</haskell><br />
* MFP write <math>(f\nabla g) x</math> for<br />
<haskell><br />
(Nabla f g) (Left x) = f x<br />
(Nabla f g) (Right x) = g x<br />
</haskell><br />
<br />
These two last constructions are directly motivated by the maps induced from the universal properties of products and coproducts.<br />
<br />
We shall write <math>(f\times g)</math> and <math>(f+g)</math> for the <math>\Delta</math> and <math>\nabla</math> constructions, respectively.<br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana :: (b -> F a b) -> b -> T a<br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
Again, we can note that the implementation of <hask>fpsi</hask> here is exactly the <hask>c</hask> above, and the resulting function will - as we can verify by compiling and running - give us the same kind of reversed list of the n first integers as the <hask>first</hask> function above would.<br />
<br />
====Hylomorphisms====<br />
<br />
The ''hylomorphisms'' capture one of the two possible compositions of anamorphisms and catamorphisms. Parametrized over an algebra <math>\phi: T A\to A</math> and a coalgebra <math>\psi: B \to T B</math> the hylomorphism is a recursion pattern that computes a value in <math>A</math> from a value in <math>A</math> by generating some sort of intermediate structure and then collapsing it again.<br />
<br />
It is, thus the composition of the uniquely existing morphism from a coalgebra to the final coalgebra for an endofunctor, followed by the uniquely existing morphism from the initial algebra to some other algebra.<br />
<br />
MFP define it, again, as a fix point: <br />
<haskell><br />
hylo :: (F a b2 -> b2) -> (b1 -> F a b1) -> b1 -> b2<br />
hylo phi psi = mu (\x -> phi . fmap x . psi)<br />
</haskell><br />
<br />
First off, we can observe that by picking one or the other of <math>in_A, out_A</math> as a parameter, we can recover both the anamorphisms and the catamorphisms as hylomorphisms.<br />
<br />
As an example, we'll compute the factorial function using a hylomorphism:<br />
<br />
<haskell><br />
phi :: F Int Int -> Int<br />
phi Nil = 1<br />
phi (Cons n m) = n*m<br />
<br />
psi :: Int -> F Int Int<br />
psi 0 = Int<br />
psi n = Cons n (n-1)<br />
<br />
factorial = hylo phi psi<br />
</haskell><br />
<br />
====Metamorphisms====<br />
<br />
The ''metamorphism'' is the ''other'' composition of an anamorphism with a catamorphism. It takes some structure, deconstructs it, and then reconstructs a new structure from it. <br />
<br />
As a recursion pattern, it's kinda boring - it'll take an interesting structure, deconstruct it into a ''scalar'' value, and then reconstruct some structure from that scalar. As such, it won't even capture the richness of <math>hom(F x, G y)</math>, since any morphism expressed as a metamorphism will factor through a map <math>x\to y</math>.<br />
<br />
====Paramorphisms====<br />
<br />
''Paramorphisms'' were discussed in the MFP paper as a way to extend the catamorphisms so that the operating function can access its arguments in computation as well as in recursion. We gave the factorial above as a hylomorphism instead of a catamorphism precisely because no simple enough catamorphic structure exists.<br />
<br />
====Apomorphisms====<br />
<br />
The ''apomorphism'' is the dual of the paramorphism - it does with retention of values along the way what anamorphisms do compared to catamorphisms.<br />
<br />
===Further reading===<br />
<br />
Terminology in the literature: in and out, inl, inr. <br />
Bananas et.c.<br />
Sorting morphisms.<br />
<br />
===Further properties of adjunctions===<br />
<br />
====RAPL====<br />
<br />
'''Proposition''' If <math>F</math> is a ''right adjoint'', thus if <math>F</math> has a left adjoint, then <math>F</math> preserves limits in the sense that <math>F(\lim_{\leftarrow} A_i) = \lim_{\leftarrow} F(A_i)</math>.<br />
<br />
Example: <math>(\lim_{\leftarrow_i} A_i)\times X = \lim_{\leftarrow_i} A_i\times X</math>. <br />
<br />
We can use this to prove that things cannot be adjoints - since all right adjoints preserve limits, if a functor <math>G</math> doesn't preserve limits, then it doesn't have a left adjoint.<br />
<br />
Similarly, and dually, left adjoints preserve colimits. Thus if a functor doesn't preserve colimits, it cannot be a left adjoint, thus cannot have a right adjoint.<br />
<br />
The proof of these statements build on the ''Yoneda lemma'': <br />
<br />
'''Lemma''' If <math>C</math> is a locally small category (i.e. all hom-sets are sets). Then for any <math>c\in C_0</math> and any functor <math>F: C^{op}\to Sets</math> there is an isomorphism<br />
:<math>hom_{hom_{Sets^{C^{op}}}}(yC, F) = FC</math><br />
where we define <math>yC = d\mapsto hom_C(d,c) : C^{op}\to Sets</math>.<br />
<br />
The Yoneda lemma has one important corollary: <br />
<br />
'''Corollary''' If <math>yA = yB</math> then <math>A = B</math>.<br />
<br />
Which, in turn has a number of important corollaries:<br />
<br />
'''Corollary''' <math>(A^B)^C = A^{B\times C}</math><br />
<br />
'''Corollary''' Adjoints are unique up to isomorphism - in particular, if <math>F: C\to D</math> is a functor with right adjoints <math>U, V: D\to C</math>, then <math>U = V</math>.<br />
<br />
'''Proof''' <math>hom_C(C, UD) = hom_D(FC, D) = hom_C(C, VD)</math>, and thus by the corollary to the Yoneda lemma, <math>UD = VD</math>, natural in <math>D</math>. <br />
<br />
====Functors that are adjoints====<br />
<br />
* The functor <math>X\mapsto X\times A</math> has right adjoint <math>Y\mapsto Y^A</math>. The universal mapping property of the exponentials follows from the adjointness property.<br />
* The functor <math>\Delta: C\to C\times C, c\mapsto (c,c)</math> has a left adjoint given by the coproduct <math>(X,Y)\mapsto X + Y</math> and right adjoint the product <math>(X,Y)\mapsto X\times Y</math>.<br />
* More generally, the functor <math>C\to C^J</math> that takes <math>c</math> to the constant functor <math>const_c(j) = c, const_c(f) = 1_c</math> has left andright adjoints given by colimits and limits:<br />
:<math>\lim_\rightarrow -| \Delta -| \lim_\leftarrow</math><br />
* Pointed rings are pairs <math>(R, r\in R)</math> of rings and one element singled out for attention. Homomorphisms of pointed rings need to take the distinguished point to the distinguished point. There is an obvious forgetful functor <math>U: Rings_* \to Rings</math>, and this has a left adjoint - a free ring functor that adjoins a new indeterminate <math>R\mapsto (R[x], x)</math>. This gives a formal definition of what we mean by ''formal polynomial expressions'' et.c.<br />
* Given sets <math>A, B</math>, we can consider the powersets <math>P(A), P(B)</math> containing, as elements, all subsets of <math>A, B</math> respectively. Suppose <math>f:A\to B</math> is a function, then <math>f^{-1}: P(B)\to P(A)</math> takes subsets of <math>B</math> to subsets of <math>A</math>. <br />
:Viewing <math>P(A)</math> and <math>P(B)</math> as partially ordered sets by the inclusion operations, and then as categories induced by the partial order, <math>f^{-1}</math> turns into a functor between partial orders. And it turns out <math>f^{-1}</math> has a left adjoint given by the operation <math>im(f)</math> taking a subset to the set of images under the function <math>f</math>. And it has a right adjoint <math>f_*(U) = \{b\in B: f^{-1}(b)\subseteq U\}</math><br />
* We can introduce a categorical structure to logic. We let <math>L</math> be a formal language, say of predicate logic. Then for any list <math>x = x_1, x_2, ..., x_n</math> of variables, we have a preorder <math>Form(x)</math> of formulas with no free variables not occuring in <math>x</math>. The preorder on <math>Form(x)</math> comes from the ''entailment'' operation - <math> f |- g</math> if in every interpretation of the language, <math>f \Rightarrow g</math>.<br />
: We can build an operation on these preorders - a functor on the underlying categories - by adjoining a single new variable: <math>*: Form(x) \to Form(x, y)</math>, sending each form to itself. Obviously, if <math>f |- g</math> with <math>x</math> the source of free variables, if we introduce a new allowable free variable, but don't actually change the formulas, the entailment stays the same.<br />
: It turns out that there is a right adjoint to <math>*</math> given by <math>f\mapsto \forall y. f</math>. And a left adjoint to <math>*</math> given by <math>f\mapsto \exists y. f</math>. Adjointness properties give us classical deduction rules from logic.<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# Write the fibonacci function as a hylomorphism.<br />
# Write the Towers of Hanoi as a hylomorphism. You'll probably want to use binary trees as the intermediate data structure.<br />
# Write a prime numbers generator as an anamorphism.<br />
# * The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.<br />
:''Hint'': You will be helped by having a function to generate a list of all primes. One suggestion is:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
:''Hint'': A good data structure to use is; with expected output of running the algorithm:<br />
<haskell><br />
data Tree = Leaf Integer | Node Integer [Tree]<br />
<br />
divisionTree 60 = <br />
Node 60 [<br />
Node 30 [<br />
Node 15 [<br />
Leaf 5,<br />
Leaf 3],<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2]],<br />
Node 20 [<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]],<br />
Node 12 [<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]]]<br />
</haskell></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31613User:Michiexile/MATH198/Lecture 92009-11-17T00:51:06Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
* MFP write <math>(f\Delta g)</math> for<br />
<haskell><br />
Delta f g = \x -> (f x, g x)<br />
</haskell><br />
* MFP write <math>(f\nabla g) x</math> for<br />
<haskell><br />
(Nabla f g) (Left x) = f x<br />
(Nabla f g) (Right x) = g x<br />
</haskell><br />
<br />
These two last constructions are directly motivated by the maps induced from the universal properties of products and coproducts.<br />
<br />
We shall write <math>(f\times g)</math> and <math>(f+g)</math> for the <math>\Delta</math> and <math>\nabla</math> constructions, respectively.<br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana :: (b -> F a b) -> b -> T a<br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
Again, we can note that the implementation of <hask>fpsi</hask> here is exactly the <hask>c</hask> above, and the resulting function will - as we can verify by compiling and running - give us the same kind of reversed list of the n first integers as the <hask>first</hask> function above would.<br />
<br />
====Hylomorphisms====<br />
<br />
The ''hylomorphisms'' capture one of the two possible compositions of anamorphisms and catamorphisms. Parametrized over an algebra <math>\phi: T A\to A</math> and a coalgebra <math>\psi: B \to T B</math> the hylomorphism is a recursion pattern that computes a value in <math>A</math> from a value in <math>A</math> by generating some sort of intermediate structure and then collapsing it again.<br />
<br />
It is, thus the composition of the uniquely existing morphism from a coalgebra to the final coalgebra for an endofunctor, followed by the uniquely existing morphism from the initial algebra to some other algebra.<br />
<br />
MFP define it, again, as a fix point: <br />
<haskell><br />
hylo :: (F a b2 -> b2) -> (b1 -> F a b1) -> b1 -> b2<br />
hylo phi psi = mu (\x -> phi . fmap x . psi)<br />
</haskell><br />
<br />
First off, we can observe that by picking one or the other of <math>in_A, out_A</math> as a parameter, we can recover both the anamorphisms and the catamorphisms as hylomorphisms.<br />
<br />
As an example, we'll compute the factorial function using a hylomorphism:<br />
<br />
<haskell><br />
phi :: F Int Int -> Int<br />
phi Nil = 1<br />
phi (Cons n m) = n*m<br />
<br />
psi :: Int -> F Int Int<br />
psi 0 = Int<br />
psi n = Cons n (n-1)<br />
<br />
factorial = hylo phi psi<br />
</haskell><br />
<br />
====Metamorphisms====<br />
<br />
The ''metamorphism'' is the ''other'' composition of an anamorphism with a catamorphism. It takes some structure, deconstructs it, and then reconstructs a new structure from it. <br />
<br />
As a recursion pattern, it's kinda boring - it'll take an interesting structure, deconstruct it into a ''scalar'' value, and then reconstruct some structure from that scalar. As such, it won't even capture the richness of <math>hom(F x, G y)</math>, since any morphism expressed as a metamorphism will factor through a map <math>x\to y</math>.<br />
<br />
====Paramorphisms====<br />
<br />
''Paramorphisms'' were discussed in the MFP paper as a way to extend the catamorphisms so that the operating function can access its arguments in computation as well as in recursion. We gave the factorial above as a hylomorphism instead of a catamorphism precisely because no simple enough catamorphic structure exists.<br />
<br />
====Apomorphisms====<br />
<br />
The ''apomorphism'' is the dual of the paramorphism - it does with retention of values along the way what anamorphisms do compared to catamorphisms.<br />
<br />
===Further reading===<br />
<br />
Terminology in the literature: in and out, inl, inr. <br />
Bananas et.c.<br />
Sorting morphisms.<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# Write the fibonacci function as a hylomorphism.<br />
# Write the Towers of Hanoi as a hylomorphism. You'll probably want to use binary trees as the intermediate data structure.<br />
# Write a prime numbers generator as an anamorphism.<br />
# * The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.<br />
:''Hint'': You will be helped by having a function to generate a list of all primes. One suggestion is:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
:''Hint'': A good data structure to use is; with expected output of running the algorithm:<br />
<haskell><br />
data Tree = Leaf Integer | Node Integer [Tree]<br />
<br />
divisionTree 60 = <br />
Node 60 [<br />
Node 30 [<br />
Node 15 [<br />
Leaf 5,<br />
Leaf 3],<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2]],<br />
Node 20 [<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]],<br />
Node 12 [<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]]]<br />
</haskell></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31612User:Michiexile/MATH198/Lecture 92009-11-17T00:13:54Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
* MFP write <math>(f\Delta g)</math> for<br />
<haskell><br />
Delta f g = \x -> (f x, g x)<br />
</haskell><br />
* MFP write <math>(f\nabla g) x</math> for<br />
<haskell><br />
(Nabla f g) (Left x) = f x<br />
(Nabla f g) (Right x) = g x<br />
</haskell><br />
<br />
These two last constructions are directly motivated by the maps induced from the universal properties of products and coproducts.<br />
<br />
We shall write <math>(f\times g)</math> and <math>(f+g)</math> for the <math>\Delta</math> and <math>\nabla</math> constructions, respectively.<br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
Again, we can note that the implementation of <hask>fpsi</hask> here is exactly the <hask>c</hask> above, and the resulting function will - as we can verify by compiling and running - give us the same kind of reversed list of the n first integers as the <hask>first</hask> function above would.<br />
<br />
====Hylomorphisms====<br />
<br />
The ''hylomorphisms'' capture one of the two possible compositions of anamorphisms and catamorphisms. Parametrized over an algebra <math>\phi: T A\to A</math> and a coalgebra <math>\psi: B \to T B</math> the hylomorphism is a recursion pattern that computes a value in <math>A</math> from a value in <math>A</math> by generating some sort of intermediate structure and then collapsing it again.<br />
<br />
It is, thus the composition of the uniquely existing morphism from a coalgebra to the final coalgebra for an endofunctor, followed by the uniquely existing morphism from the initial algebra to some other algebra.<br />
<br />
MFP define it, again, as a fix point: <br />
<haskell><br />
hylo phi psi = mu (\x -> phi . fmap x . psi)<br />
</haskell><br />
<br />
First off, we can observe that by picking one or the other of <math>in_A, out_A</math> as a parameter, we can recover both the anamorphisms and the catamorphisms as hylomorphisms.<br />
<br />
As an example, we'll compute the factorial function using a hylomorphism:<br />
<br />
<haskell><br />
phi :: F Int Int -> Int<br />
phi Nil = 1<br />
phi (Cons n m) = n*m<br />
<br />
psi :: Int -> F Int Int<br />
psi 0 = Int<br />
psi n = Cons n (n-1)<br />
<br />
factorial = hylo phi psi<br />
</haskell><br />
<br />
<br />
====Metamorphisms====<br />
<br />
====Paramorphisms====<br />
<br />
====Apomorphisms====<br />
<br />
===Further reading===<br />
<br />
Terminology in the literature: in and out, inl, inr. <br />
<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# Write the fibonacci function as a hylomorphism.<br />
# * The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.<br />
:''Hint'': You will be helped by having a function to generate a list of all primes. One suggestion is:<br />
<haskell><br />
primes :: [Integer]<br />
primes = sieve [2..]<br />
where<br />
sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]<br />
</haskell><br />
:''Hint'': A good data structure to use is; with expected output of running the algorithm:<br />
<haskell><br />
data Tree = Leaf Integer | Node Integer [Tree]<br />
<br />
divisionTree 60 = <br />
Node 60 [<br />
Node 30 [<br />
Node 15 [<br />
Leaf 5,<br />
Leaf 3],<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2]],<br />
Node 20 [<br />
Node 10 [<br />
Leaf 5,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]],<br />
Node 12 [<br />
Node 6 [<br />
Leaf 3,<br />
Leaf 2],<br />
Node 4 [<br />
Leaf 2]]]<br />
</haskell></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31608User:Michiexile/MATH198/Lecture 92009-11-16T22:49:45Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
Meijer, Fokkinga & Patterson identified in the paper ''Functional programming with bananas, lenses, envelopes and barbed wire'' a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
We shall define a few specific morphisms we'll use repeatedly. This notation, introduced here, occurs all over the place in these corners of the literature, and are good to be aware of in general: <br />
* If <math>a: TA\to A</math> is an initial algebra for <math>T</math>, we denote <math>a = in_A</math>.<br />
* If <math>a: A\to TA</math> is a final coalgebra for <math>T</math>, we denote <math>a = out_A</math>.<br />
* We write <math>\mu f</math> for the fixed point operator<br />
<haskell><br />
mu f = x where x = f x<br />
</haskell><br />
* MFP write <math>(f\Delta g)</math> for<br />
<haskell><br />
Delta f g = \x -> (f x, g x)<br />
</haskell><br />
* MFP write <math>(f\nabla g) x</math> for<br />
<haskell><br />
(Nabla f g) (Left x) = f x<br />
(Nabla f g) (Right x) = g x<br />
</haskell><br />
<br />
These two last constructions are directly motivated by the maps induced from the universal properties of products and coproducts.<br />
<br />
We shall write <math>(f\times g)</math> and <math>(f+g)</math> for the <math>\Delta</math> and <math>\nabla</math> constructions, respectively.<br />
<br />
We note that in the situation considered by MFP, inital algebras and final coalgebras coincide, and thus <math>in_A, out_A</math> are the pair of isomorphic maps induced by either the initial algebra- or the final coalgebra-structure.<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
MFP define the catamorphism by, supposing <hask>T</hask> is initial for the functor <hask>F</hask>:<br />
<haskell><br />
cata :: (F a b -> b) -> T a -> b<br />
cata phi = mu (\x -> phi . fmap x . outT)<br />
</haskell><br />
<br />
We can reframe the example above as a catamorphism by observing that here, <br />
<haskell><br />
data F a b = Nil | Cons a b deriving (Eq, Show)<br />
type T a = [a]<br />
<br />
instance Functor (F a) where<br />
fmap _ Nil = Nil<br />
fmap f (Cons n a) = Cons n (f a)<br />
<br />
outT :: T a -> F a (T a)<br />
outT [] = Nil<br />
outT (a:as) = Cons a as<br />
<br />
lphi :: F a Int -> Int<br />
lphi Nil = 0<br />
lphi (Cons a n) = n + 1<br />
<br />
l = cata lphi<br />
</haskell><br />
where we observe that <hask>mu</hask> has a global definition for everything we do and <hask>out</hask> is defined once we settle on the functor <hask>F</hask> and its initial algebra. Thus, the definition of <hask>phi</hask> really is the only place that the recursion data shows up. <br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
MFP define the anamorphism by a fixpoint as well, namely:<br />
<haskell><br />
ana psi = mu (\x -> inT . fmap x . psi)<br />
</haskell><br />
<br />
We can, again, recast our illustration above into a structural anamorphism, by:<br />
<haskell><br />
-- Reuse mu, F, T from above<br />
inT :: F a (T a) -> T a<br />
inT Nil = []<br />
inT (Cons a as) = a:as<br />
<br />
fpsi :: Int -> F Int Int<br />
fpsi 0 = Nil<br />
fpsi n = Cons n (n-1)<br />
</haskell><br />
<br />
<br />
<br />
<br />
<br />
====Hylomorphisms====<br />
<br />
====Metamorphisms====<br />
<br />
====Paramorphisms====<br />
<br />
====Apomorphisms====<br />
<br />
===Further reading===<br />
<br />
Terminology in the literature: in and out, inl, inr. <br />
<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31573User:Michiexile/MATH198/Lecture 92009-11-14T08:26:07Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Recursion patterns===<br />
<br />
((X, Y and Z)) identified in the paper ((Bananas et.c.)) a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of ''rules'' for modifying and rewriting expressions involving these generic recursion patterns.<br />
<br />
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality). <br />
<br />
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.<br />
<br />
====Coalgebras for endofunctors====<br />
<br />
'''Definition''' If <math>P: C\to C</math> is an endofunctor, then a <math>P</math>-''coalgebra'' on <math>A</math> is a morphism <math>a: A\to PA</math>.<br />
<br />
A ''morphism of coalgebras'': <math>f: a\to b</math> is some <math>f: A\to B</math> such that the diagram <br />
:[[Image:CoalgebraMorphism.png]]<br />
commutes. <br />
<br />
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the ''final coalgebras''. Just as with algebras, we have<br />
<br />
'''Lemma''' (''Lambek'') If <math>a: A\to PA</math> is a final coalgebra, it is an isomorphism.<br />
<br />
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as <math>\omega-CPO</math>), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).<br />
<br />
Onwards to recursion schemes!<br />
<br />
====Catamorphisms====<br />
<br />
A ''catamorphism'' is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized ''fold'' over the structure at hand before returning the final value.<br />
<br />
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.<br />
<br />
'''Example''': the length function from last lecture. This is the catamorphism for the functor <math>P_A(X) = 1 + A\times X</math> given by the maps<br />
<haskell><br />
u :: Int<br />
u = 0<br />
<br />
m :: (A, Int) -> Int<br />
m (a, n) = n+1<br />
</haskell><br />
<br />
====Anamorphisms====<br />
<br />
An ''anamorphism'' is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor. <br />
<br />
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved. <br />
<br />
'''Example''': we can write a recursive function <br />
<haskell><br />
first :: Int -> [Int]<br />
first 1 = [1]<br />
first n = n : first (n - 1)<br />
</haskell><br />
This is an anamorphism from the coalgebra for <math>P_{\mathbb N}(X) = 1 + \mathbb N\times X</math> on <math>\mathbb N</math> generated by the two maps<br />
<haskell><br />
c 0 = Left ()<br />
c n = Right (n, n-1)<br />
</haskell><br />
and we observe that we can chase through the diagram<br />
:[[Image:CoalgebraMorphism.png]]<br />
to conclude that therefore<br />
<haskell><br />
f 0 = []<br />
f n = n : f (n - 1)<br />
</haskell><br />
which is exactly the recursion we wrote to begin with.<br />
<br />
====Hylomorphisms====<br />
<br />
====Metamorphisms====<br />
<br />
====Paramorphisms====<br />
<br />
====Apomorphisms====<br />
<br />
===Further reading===<br />
<br />
Terminology in the literature: in and out, inl, inr. <br />
<br />
<br />
===Homework===<br />
<br />
# Write a fold for the data type <hask>data T a = L a | B a a | C a a a</hask> and demonstrate how this can be written as a catamorphism by giving the algebra it maps to. <br />
# The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge <math>n \to d</math> if <math>d|n</math> and <math>d</math> doesn't divide any other divisor of <math>n</math>. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_9&diff=31568User:Michiexile/MATH198/Lecture 92009-11-13T19:01:35Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Coalgebras for endofunctors===<br />
<br />
===Recursion patterns===<br />
<br />
====Catamorphisms====<br />
<br />
====Anamorphisms====<br />
<br />
====Hylomorphisms====<br />
<br />
====Metamorphisms====<br />
<br />
====Paramorphisms====<br />
<br />
====Apomorphisms====</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_8&diff=31531User:Michiexile/MATH198/Lecture 82009-11-11T18:59:59Z<p>Michiexile: </p>
<hr />
<div>===Algebras over monads===<br />
<br />
We recall from the last lecture the definition of an Eilenberg-Moore algebra over a monad <math>T = (T, \eta, \mu)</math>: <br />
<br />
'''Definition''' An ''algebra'' over a monad <math>T</math> in a category <math>C</math> (a <math>T</math>-algebra) is a morphism <math>\alpha\in C(TA, A)</math>, such that the diagrams below both commute:<br />
<br />
[[Image:EilenbergMooreUnity.png]]<br />
[[Image:EilenbergMooreAssociativity.png]]<br />
<br />
While a monad corresponds to the imposition of some structure on the objects in a category, an algebra over that monad corresponds to some evaluation of that structure. <br />
<br />
====Example: monoids====<br />
<br />
Let <math>T</math> be the Kleene star monad - the one we get from the adjunction of free and forgetful functors between Monoids and Sets. Then a <math>T</math>-algebra on a set <math>A</math> is equivalent to a monoid structure on <math>A</math>.<br />
<br />
Indeed, if we have a monoid structure on <math>A</math>, given by <math>m:A^2\to A</math> and <math>u:1\to A</math>, we can construct a <math>T</math>-algebra by<br />
:<math>\alpha([]) = u</math><br />
:<math>\alpha([a_1,a_2,\dots,a_n]) = m(a_1,\alpha([a_2,\dots,a_n]))</math><br />
This gives us, indeed, a <math>T</math>-algebra structure on <math>A</math>. Associativity and unity follows from the corresponding properties in the monoid.<br />
<br />
On the other hand, if we have a <math>T</math>-algebra structure on <math>A</math>, we can construct a monoid structure by setting<br />
:<math>u = \alpha([])</math><br />
:<math>m(a,b) = \alpha([a,b])</math> <br />
It is clear that associativity of <math>m</math> follows from the associativity of <math>\alpha</math>, and unitality of <math>u</math> follows from the unitality of <math>\alpha</math>.<br />
<br />
====Example: Vector spaces====<br />
<br />
We have free and forgetful functors <br />
:<math>Set \to^{free} k-Vect \to^{forgetful} Set</math><br />
forming an adjoint pair; where the free functor takes a set <math>S</math> and returns the vector space with basis <math>S</math>; while the forgetful functor takes a vector space and returns the set of all its elements.<br />
<br />
The composition of these yields a monad <math>T</math> in <math>Set</math> taking a set <math>S</math> to the set of all formal linear combinations of elements in <math>S</math>. The monad multiplication takes formal linear combinations of formal linear combinations and multiplies them out:<br />
:<math>3(2v+5w)-5(3v+2w) = 6v+15w-15v-10w = -9v+5w</math><br />
<br />
A <math>T</math>-algebra is a map <math>\alpha: TA\to A</math> that ''acts like a vector space'' in the sense that <math>\alpha(\sum\alpha_i(\sum\beta_jv_j)) = \alpha(\sum\alpha_i\beta_jv_j)</math>.<br />
<br />
We can define <math>\lambda\cdot v = \alpha(\lambda v)</math> and <math>v+w=\alpha(v+w)</math>. The operations thus defined are associative, distributive, commutative, and everything else we could wish for in order to define a vector space - precisely because the operations inside <math>TA</math> are, and <math>\alpha</math> is associative. <br />
<br />
----<br />
<br />
The moral behind these examples is that using monads and monad algebras, we have significant power in defining and studying algebraic structures with categorical and algebraic tools. This paradigm ties in closely with the theory of ''operads'' - which has its origins in topology, but has come to good use within certain branches of universal algebra.<br />
<br />
An (non-symmetric) ''operad'' is a graded set <math>O = \bigoplus_i O_i</math> equipped with composition operations <math>\circ_i: O_n\oplus O_m\to O_{n+m-1}</math> that obey certain unity and associativity conditions. As it turns out, non-symmetric operads correspond to the summands in a monad with polynomial underlying functor, and from a non-symmetric operad we can construct a corresponding monad.<br />
<br />
The designator non-symmetric floats in this text o avoid dealing with the slightly more general theory of symmetric operads - which allow us to resort the input arguments, thus including the symmetrizer of a symmetric monoidal category in the entire definition. <br />
<br />
To read more about these correspondences, I can recommend you start with: the blog posts ''Monads in Mathematics'' here:<br />
[http://embuchestissues.wordpress.com/tag/monads-in-mathematics/]<br />
<br />
<br />
===Algebras over endofunctors===<br />
<br />
Suppose we started out with an endofunctor that is not the underlying functor of a monad - or an endofunctor for which we don't want to settle on a monadic structure. We can still do a lot of the Eilenberg-Moore machinery on this endofunctor - but we don't get quite the power of algebraic specification that monads offer us. At the core, here, lies the lack of associativity for a generic endofunctor - and algebras over endofunctors, once defined, will correspond to non-associative correspondences to their monadic counterparts.<br />
<br />
'''Definition''' For an endofunctor <math>P:C\to C</math>, we define a ''<math>P</math>-algebra'' to be an arrow <math>\alpha\in C(PA,A)</math>.<br />
<br />
A homomorphism of <math>P</math>-algebras <math>\alpha\to\beta</math> is some arrow <math>f:A\to B</math> such that the diagram below commutes:<br />
:[[Image:EilenbergMoorePMorphism.png]]<br />
<br />
This homomorphism definition does not need much work to apply to the monadic case as well.<br />
<br />
====Example: Groups====<br />
<br />
A group is a set <math>G</math> with operations <math>u: 1\to G, i: G\to G, m: G\times G\to G</math>, such that <math>u</math> is a unit for <math>m</math>, <math>m</math> is associative, and <math>i</math> is an inverse.<br />
<br />
Ignoring for a moment the properties, the theory of groups is captured by these three maps, or by a diagram<br />
:[[Image:GroupDiagram.png]]<br />
<br />
We can summarize the diagram as<br />
:<math>1+G+G\times G \mapsto^{[u,i,m]} G</math><br />
and thus recognize that groups are some equationally defined subcategory of the category of <math>T</math>-algebras for the polynomial functor <math>T(X) = 1 + X + X\times X</math>. The subcategory is ''full'', since if we have two algebras <math>\gamma: T(G)\to G</math> and <math>\eta: T(H)\to H</math>, that both lie within the subcategory that fulfills all the additional axioms, then certainly any morphism <math>\gamma\to\eta</math> will be compatible with the structure maps, and thus will be a group homomorphism.<br />
<br />
----<br />
<br />
We shall denote the category of <math>P</math>-algebras in a category <math>C</math> by <math>P-Alg(C)</math>, or just <math>P-Alg</math> if the category is implicitly understood.<br />
<br />
This category is wider than the corresponding concept for a monad. We don't require the kind of associativity we would for a monad - we just lock down the underlying structure. This distinction is best understood with an example: <br />
<br />
The free monoids monad has monoids for its algebras. On the other hand, we can pick out the underlying functor of that monad, forgetting about the unit and multiplication. An algebra over this structure is a slightly more general object: we no longer require <math>(a\cdot b)\cdot c = a\cdot (b\cdot c)</math>, and thus, the theory we get is that of a ''magma''. We have concatenation, but we can't drop the brackets, and so we get something more reminiscent of a binary tree. <br />
<br />
===Initial <math>P</math>-algebras and recursion===<br />
<br />
Consider the polynomical functor <math>P(X) = 1 + X</math> on the category of sets. It's algebras form a category, by the definitions above - and an algebra needs to pick out one special element 0, and one endomorphism T, for a given set.<br />
<br />
What would an initial object in this category of P-algebras look like? It would be an object <math>I</math> equipped with maps <math>1 \to^o I \leftarrow^n I</math>. For any other pair of maps <math>a: 1\to X, s: X\to X</math>, we'd have a unique arrow <math>u: I\to X</math> such that <br />
:[[Image:NNOcommutes.png]]<br />
commutes, or in equations such that<br />
:<math>u(o) = a</math><br />
:<math>u(n(x)) = s(u(x))</math><br />
<br />
Now, unwrapping the definitions in place, we notice that we will have elements <math>o, n(o), n(n(o), \dots</math> in <math>I</math>, and the initiality will force us to not have any ''other'' elements floating around. Also, intiality will prevent us from having any elements not in this minimally forced list.<br />
<br />
We can rename the elements to form something more recognizable - by equating an element in <math>I</math> with the number of applications of <math>n</math> to <math>o</math>. This yields, for us, elements <math>0, 1, 2, \dots</math> with one function that picks out the <math>0</math>, and another that gives us the cussessor.<br />
<br />
This should be recognizable as exactly the natural numbers; with just enough structure on them to make the principle of mathematical induction work: suppose we can prove some statement <math>P(0)</math>, and we can extend a proof of <math>P(n)</math> to <math>P(n+1)</math>. Then induction tells us that the statement holds for all <math>P(n)</math>.<br />
<br />
More importantly, recursive definitions of functions from natural numbers can be performed here by choosing an appropriate algebra mapping to.<br />
<br />
This correspondence between the initial object of <math>P(X) = 1 + X</math> is the reason such an initial object in a category with coproducts and terminal objects is called a ''natural numbers object''. <br />
<br />
For another example, we consider the functor <math>P(X) = 1 + X\times X</math>. <br />
<br />
'''Pop Quiz''' Can you think of a structure with this as underlying defining functor?<br />
<br />
An initial <math>1+X\times X</math>-algebra would be some diagram<br />
:<math>1 \to^o I \leftarrow^m I\times I</math><br />
such that for any other such diagram<br />
:<math>1 \to^a X \leftarrow^* X\times X</math><br />
we have a unique arrow <math>u:I\to X</math> such that<br />
:[[Image:MonoidCommutes.png]]<br />
commutes.<br />
<br />
Unwrapping the definition, working over Sets again, we find we are forced to have some element <math>*</math>, the image of <math>o</math>. Any two elements <math>S,T</math> in the set give rise to some <math>(S,T)</math>, which we can view as being the binary tree<br />
:[[Image:MagmaComposition.png]]<br />
<br />
The same way that we could construct induction as an algebra map from a natural numbers object, we can use this object to construct a tree-shaped induction; and similarily, we can develop what amounts to the theory of ''structural induction'' using these more general approaches to induction.<br />
<br />
====Example of structural induction====<br />
<br />
Using the structure of <math>1+X\times X</math>-algebras we shall prove the following statement:<br />
<br />
'''Proposition''' The number of leaves in a binary tree is one more than the number of internal nodes.<br />
<br />
'''Proof''' We write down the actual Haskell data type for the binary tree initial algebra.<br />
<haskell><br />
data Tree = Leaf | Node Tree Tree<br />
<br />
nLeaves Leaf = 1<br />
nLeaves (Node s t) = nLeaves s + nLeaves t<br />
<br />
nNodes Leaf = 0<br />
nNodes (Node s t) = 1 + nNodes s + nNodes t<br />
</haskell><br />
<br />
Now, it is clear, as a base case, that for the no-nodes tree <hask>Leaf</hask>:<br />
<haskell><br />
nLeaves Leaf = 1 + nNodes Leaf<br />
</haskell><br />
<br />
For the structural induction, now, we consider some binary tree, where we assume the statement to be known for each of the two subtrees. Hence, we have<br />
<haskell><br />
tree = Node s t<br />
<br />
nLeaves s = 1 + nNodes s<br />
nLeaves t = 1 + nNodes t<br />
</haskell><br />
and we may compute<br />
<haskell><br />
nLeaves tree = nLeaves s + nLeaves t <br />
= 1 + nNodes s + 1 + nNodes t <br />
= 2 + nNodes s + nNodes t<br />
<br />
nNodes tree = 1 + nNodes s + nNodes t<br />
</haskell><br />
<br />
Now, since the statement is proven for each of the cases in the structural description of the data, it follows form the principle of structural induction that the proof is finished.<br />
<br />
In order to really nail down what we are doing here, we need to define what we mean by predicates in a strict manner. There is a way to do this using ''fibrations'', but this reaches far outside the scope of this course. For the really interested reader, I'll refer to [http://www.springerlink.com/content/d022nlv03n26nm03/]. <br />
<br />
Another way to do this is to introduce a ''topos'', and work it all out in terms of its ''internal logic'', but again, this reaches outside the scope of this course.<br />
<br />
====Lambek's lemma====<br />
<br />
What we do when we write a recursive data type definition in Haskell ''really'' to some extent is to define a data type as the initial algebra of the corresponding functor. This intuitive equivalence is vindicated by the following <br />
<br />
'''Lemma''' ''Lambek'' If <math>P: C\to C</math> has an initial algebra <math>I</math>, then <math>P(I) = I</math>.<br />
<br />
'''Proof''' Let <math>a: PA\to A</math> be an initial <math>P</math>-algebra. We can apply <math>P</math> again, and get a chain<br />
:<math>PPA \to^{Pa} PA \to^a A</math><br />
We can fill out the diagram<br />
:[[Image:LambekPartialDiagram.png]]<br />
to form the diagram<br />
:[[Image:LambekDiagram.png]]<br />
where <math>f</math> is induced by initiality, since <math>Pa:PPa\to Pa</math> is also a <math>P</math>-algebra.<br />
<br />
The diagram above commutes, and thus <math>af = 1_{PA}</math> and <math>fa = 1_A</math>. Thus <math>f</math> is an inverse to <math>a</math>. QED.<br />
<br />
Thus, by Lambek's lemma we ''know'' that if <math>P_A(X) = 1 + A\times X</math> then for that <math>P_A</math>, the initial algebra - should it exist - will fulfill<math>I = 1 + A\times I</math>, which in turn is exactly what we write, defining this, in Haskell code: <br />
<haskell><br />
List a = Nil | Cons a List<br />
</haskell><br />
<br />
====Recursive definitions with the unique maps from the initial algebra====<br />
<br />
Consider the following <math>P_A(X)</math>-algebra structure <math>l: P_A(\mathbb N)\to\mathbb N</math> on the natural numbers:<br />
<haskell><br />
l(*) = 0<br />
l(a,n) = 1 + n<br />
</haskell><br />
<br />
We get a unique map <math>f</math> from the initial algebra for <math>P_A(X)</math> (lists of elements of type <math>A</math>) to <math>\mathbb N</math> from this definition. This map will fulfill:<br />
<haskell><br />
f(Nil) = l(*) = 0<br />
f(Cons a xs) = l(a,f(xs)) = 1 + f(xs)<br />
</haskell><br />
which starts taking on the shape of the usual definition of the length of a list:<br />
<haskell><br />
length(Nil) = 0<br />
length(Cons a xs) = 1 + length(xs)<br />
</haskell><br />
<br />
And thus, the machinery of endofunctor algebras gives us a strong method for doing recursive definitions in a theoretically sound manner.<br />
<br />
===Homework===<br />
<br />
Complete credit will be given for 8 of the 13 questions.<br />
<br />
# Find a monad whose algebras are ''associative algebras'': vector spaces with a binary, associative, unitary operation (multiplication) defined on them. Factorize the monad into a free/forgetful adjoint pair.<br />
# Find an endofunctor of <math>Hask</math> whose initial object describes trees that are either binary of ternary at each point, carrying values from some <math>A</math> in the leaves.<br />
# Write an implementation of the monad of vector spaces in Haskell. If this is tricky, restrict the domain of the monad to, say, a 3-element set, and implement the specific example of a 3-dimensional vector space as a monad. Hint: [http://sigfpe.blogspot.com] has written about this approach.<br />
# Find a <math>X\mapsto 1+A\times X</math>-algebra <math>L</math> such that the unique map from the initial algebra <math>I</math> to <math>L</math> results in the function that will reverse a given list.<br />
# Find a <math>X\mapsto 1+A\times X</math>-algebra structure on the object <math>1+A</math> that will pick out the first element of a list, if possible.<br />
# Find a <math>X\mapsto \mathbb N+X\times X</math>-algebra structure on the object <math>\mathbb N</math> that will pick out the sum of the leaf values for the binary tree in the initial object.<br />
# Complete the proof of Lambek's lemma by proving the diagram commutes.<br />
# * We define a ''coalgebra'' for an endofunctor <math>T</math> to be some arrow <math>\gamma: A \to TA</math>. If <math>T</math> is a comonad - i.e. equipped with a counit <math>\epsilon: T\to 1</math> and a cocomposition <math>\Delta: T\to T\times T</math>, then we define a coalgebra for the comonad <math>T</math> to additionally fulfill <math>\gamma\circ T\gamma = \gamma\circ\Delta</math> (compatibility) and <math>\epsilon_A\circ\gamma = 1_A</math> (counitality).<br />
## (2pt) Prove that if <math>T</math> is an endofunctor, then if <math>T</math> has an initial algebra, then it is a coalgebra. Does <math>T</math> necessarily have a final coalgebra?<br />
## (2pt) Prove that if <math>U,F</math> are an adjoint pair, then <math>FU</math> forms a comonad.<br />
## (2pt) Describe a final coalgebra over the comonad formed from the free/forgetful adjunction between the categories of Monoids and Sets.<br />
## (2pt) Describe a final coalgebra over the endofunctor <math>P(X) = 1 + X</math>.<br />
## (2pt) Describe a final coalgebra over the endofunctor <math>P(X) = 1 + A\times X</math>.<br />
## (2pt) Prove that if <math>c: C\to PC</math> is a final coalgebra for an endofunctor <math>P:C\to C</math>, then <math>c</math> is an isomorphism.</div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_8&diff=31530User:Michiexile/MATH198/Lecture 82009-11-11T18:59:23Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Algebras over monads===<br />
<br />
We recall from the last lecture the definition of an Eilenberg-Moore algebra over a monad <math>T = (T, \eta, \mu)</math>: <br />
<br />
'''Definition''' An ''algebra'' over a monad <math>T</math> in a category <math>C</math> (a <math>T</math>-algebra) is a morphism <math>\alpha\in C(TA, A)</math>, such that the diagrams below both commute:<br />
<br />
[[Image:EilenbergMooreUnity.png]]<br />
[[Image:EilenbergMooreAssociativity.png]]<br />
<br />
While a monad corresponds to the imposition of some structure on the objects in a category, an algebra over that monad corresponds to some evaluation of that structure. <br />
<br />
====Example: monoids====<br />
<br />
Let <math>T</math> be the Kleene star monad - the one we get from the adjunction of free and forgetful functors between Monoids and Sets. Then a <math>T</math>-algebra on a set <math>A</math> is equivalent to a monoid structure on <math>A</math>.<br />
<br />
Indeed, if we have a monoid structure on <math>A</math>, given by <math>m:A^2\to A</math> and <math>u:1\to A</math>, we can construct a <math>T</math>-algebra by<br />
:<math>\alpha([]) = u</math><br />
:<math>\alpha([a_1,a_2,\dots,a_n]) = m(a_1,\alpha([a_2,\dots,a_n]))</math><br />
This gives us, indeed, a <math>T</math>-algebra structure on <math>A</math>. Associativity and unity follows from the corresponding properties in the monoid.<br />
<br />
On the other hand, if we have a <math>T</math>-algebra structure on <math>A</math>, we can construct a monoid structure by setting<br />
:<math>u = \alpha([])</math><br />
:<math>m(a,b) = \alpha([a,b])</math> <br />
It is clear that associativity of <math>m</math> follows from the associativity of <math>\alpha</math>, and unitality of <math>u</math> follows from the unitality of <math>\alpha</math>.<br />
<br />
====Example: Vector spaces====<br />
<br />
We have free and forgetful functors <br />
:<math>Set \to^{free} k-Vect \to^{forgetful} Set</math><br />
forming an adjoint pair; where the free functor takes a set <math>S</math> and returns the vector space with basis <math>S</math>; while the forgetful functor takes a vector space and returns the set of all its elements.<br />
<br />
The composition of these yields a monad <math>T</math> in <math>Set</math> taking a set <math>S</math> to the set of all formal linear combinations of elements in <math>S</math>. The monad multiplication takes formal linear combinations of formal linear combinations and multiplies them out:<br />
:<math>3(2v+5w)-5(3v+2w) = 6v+15w-15v-10w = -9v+5w</math><br />
<br />
A <math>T</math>-algebra is a map <math>\alpha: TA\to A</math> that ''acts like a vector space'' in the sense that <math>\alpha(\sum\alpha_i(\sum\beta_jv_j)) = \alpha(\sum\alpha_i\beta_jv_j)</math>.<br />
<br />
We can define <math>\lambda\cdot v = \alpha(\lambda v)</math> and <math>v+w=\alpha(v+w)</math>. The operations thus defined are associative, distributive, commutative, and everything else we could wish for in order to define a vector space - precisely because the operations inside <math>TA</math> are, and <math>\alpha</math> is associative. <br />
<br />
----<br />
<br />
The moral behind these examples is that using monads and monad algebras, we have significant power in defining and studying algebraic structures with categorical and algebraic tools. This paradigm ties in closely with the theory of ''operads'' - which has its origins in topology, but has come to good use within certain branches of universal algebra.<br />
<br />
An (non-symmetric) ''operad'' is a graded set <math>O = \bigoplus_i O_i</math> equipped with composition operations <math>\circ_i: O_n\oplus O_m\to O_{n+m-1}</math> that obey certain unity and associativity conditions. As it turns out, non-symmetric operads correspond to the summands in a monad with polynomial underlying functor, and from a non-symmetric operad we can construct a corresponding monad.<br />
<br />
The designator non-symmetric floats in this text o avoid dealing with the slightly more general theory of symmetric operads - which allow us to resort the input arguments, thus including the symmetrizer of a symmetric monoidal category in the entire definition. <br />
<br />
To read more about these correspondences, I can recommend you start with: the blog posts ''Monads in Mathematics'' here:<br />
[http://embuchestissues.wordpress.com/tag/monads-in-mathematics/]<br />
<br />
<br />
===Algebras over endofunctors===<br />
<br />
Suppose we started out with an endofunctor that is not the underlying functor of a monad - or an endofunctor for which we don't want to settle on a monadic structure. We can still do a lot of the Eilenberg-Moore machinery on this endofunctor - but we don't get quite the power of algebraic specification that monads offer us. At the core, here, lies the lack of associativity for a generic endofunctor - and algebras over endofunctors, once defined, will correspond to non-associative correspondences to their monadic counterparts.<br />
<br />
'''Definition''' For an endofunctor <math>P:C\to C</math>, we define a ''<math>P</math>-algebra'' to be an arrow <math>\alpha\in C(PA,A)</math>.<br />
<br />
A homomorphism of <math>P</math>-algebras <math>\alpha\to\beta</math> is some arrow <math>f:A\to B</math> such that the diagram below commutes:<br />
:[[Image:EilenbergMoorePMorphism.png]]<br />
<br />
This homomorphism definition does not need much work to apply to the monadic case as well.<br />
<br />
====Example: Groups====<br />
<br />
A group is a set <math>G</math> with operations <math>u: 1\to G, i: G\to G, m: G\times G\to G</math>, such that <math>u</math> is a unit for <math>m</math>, <math>m</math> is associative, and <math>i</math> is an inverse.<br />
<br />
Ignoring for a moment the properties, the theory of groups is captured by these three maps, or by a diagram<br />
:[[Image:GroupDiagram.png]]<br />
<br />
We can summarize the diagram as<br />
:<math>1+G+G\times G \mapsto^{[u,i,m]} G</math><br />
and thus recognize that groups are some equationally defined subcategory of the category of <math>T</math>-algebras for the polynomial functor <math>T(X) = 1 + X + X\times X</math>. The subcategory is ''full'', since if we have two algebras <math>\gamma: T(G)\to G</math> and <math>\eta: T(H)\to H</math>, that both lie within the subcategory that fulfills all the additional axioms, then certainly any morphism <math>\gamma\to\eta</math> will be compatible with the structure maps, and thus will be a group homomorphism.<br />
<br />
----<br />
<br />
We shall denote the category of <math>P</math>-algebras in a category <math>C</math> by <math>P-Alg(C)</math>, or just <math>P-Alg</math> if the category is implicitly understood.<br />
<br />
This category is wider than the corresponding concept for a monad. We don't require the kind of associativity we would for a monad - we just lock down the underlying structure. This distinction is best understood with an example: <br />
<br />
The free monoids monad has monoids for its algebras. On the other hand, we can pick out the underlying functor of that monad, forgetting about the unit and multiplication. An algebra over this structure is a slightly more general object: we no longer require <math>(a\cdot b)\cdot c = a\cdot (b\cdot c)</math>, and thus, the theory we get is that of a ''magma''. We have concatenation, but we can't drop the brackets, and so we get something more reminiscent of a binary tree. <br />
<br />
===Initial <math>P</math>-algebras and recursion===<br />
<br />
Consider the polynomical functor <math>P(X) = 1 + X</math> on the category of sets. It's algebras form a category, by the definitions above - and an algebra needs to pick out one special element 0, and one endomorphism T, for a given set.<br />
<br />
What would an initial object in this category of P-algebras look like? It would be an object <math>I</math> equipped with maps <math>1 \to^o I \leftarrow^n I</math>. For any other pair of maps <math>a: 1\to X, s: X\to X</math>, we'd have a unique arrow <math>u: I\to X</math> such that <br />
:[[Image:NNOcommutes.png]]<br />
commutes, or in equations such that<br />
:<math>u(o) = a</math><br />
:<math>u(n(x)) = s(u(x))</math><br />
<br />
Now, unwrapping the definitions in place, we notice that we will have elements <math>o, n(o), n(n(o), \dots</math> in <math>I</math>, and the initiality will force us to not have any ''other'' elements floating around. Also, intiality will prevent us from having any elements not in this minimally forced list.<br />
<br />
We can rename the elements to form something more recognizable - by equating an element in <math>I</math> with the number of applications of <math>n</math> to <math>o</math>. This yields, for us, elements <math>0, 1, 2, \dots</math> with one function that picks out the <math>0</math>, and another that gives us the cussessor.<br />
<br />
This should be recognizable as exactly the natural numbers; with just enough structure on them to make the principle of mathematical induction work: suppose we can prove some statement <math>P(0)</math>, and we can extend a proof of <math>P(n)</math> to <math>P(n+1)</math>. Then induction tells us that the statement holds for all <math>P(n)</math>.<br />
<br />
More importantly, recursive definitions of functions from natural numbers can be performed here by choosing an appropriate algebra mapping to.<br />
<br />
This correspondence between the initial object of <math>P(X) = 1 + X</math> is the reason such an initial object in a category with coproducts and terminal objects is called a ''natural numbers object''. <br />
<br />
For another example, we consider the functor <math>P(X) = 1 + X\times X</math>. <br />
<br />
'''Pop Quiz''' Can you think of a structure with this as underlying defining functor?<br />
<br />
An initial <math>1+X\times X</math>-algebra would be some diagram<br />
:<math>1 \to^o I \leftarrow^m I\times I</math><br />
such that for any other such diagram<br />
:<math>1 \to^a X \leftarrow^* X\times X</math><br />
we have a unique arrow <math>u:I\to X</math> such that<br />
:[[Image:MonoidCommutes.png]]<br />
commutes.<br />
<br />
Unwrapping the definition, working over Sets again, we find we are forced to have some element <math>*</math>, the image of <math>o</math>. Any two elements <math>S,T</math> in the set give rise to some <math>(S,T)</math>, which we can view as being the binary tree<br />
:[[Image:MagmaComposition.png]]<br />
<br />
The same way that we could construct induction as an algebra map from a natural numbers object, we can use this object to construct a tree-shaped induction; and similarily, we can develop what amounts to the theory of ''structural induction'' using these more general approaches to induction.<br />
<br />
====Example of structural induction====<br />
<br />
Using the structure of <math>1+X\times X</math>-algebras we shall prove the following statement:<br />
<br />
'''Proposition''' The number of leaves in a binary tree is one more than the number of internal nodes.<br />
<br />
'''Proof''' We write down the actual Haskell data type for the binary tree initial algebra.<br />
<haskell><br />
data Tree = Leaf | Node Tree Tree<br />
<br />
nLeaves Leaf = 1<br />
nLeaves (Node s t) = nLeaves s + nLeaves t<br />
<br />
nNodes Leaf = 0<br />
nNodes (Node s t) = 1 + nNodes s + nNodes t<br />
</haskell><br />
<br />
Now, it is clear, as a base case, that for the no-nodes tree <hask>Leaf</hask>:<br />
<haskell><br />
nLeaves Leaf = 1 + nNodes Leaf<br />
</haskell><br />
<br />
For the structural induction, now, we consider some binary tree, where we assume the statement to be known for each of the two subtrees. Hence, we have<br />
<haskell><br />
tree = Node s t<br />
<br />
nLeaves s = 1 + nNodes s<br />
nLeaves t = 1 + nNodes t<br />
</haskell><br />
and we may compute<br />
<haskell><br />
nLeaves tree = nLeaves s + nLeaves t <br />
= 1 + nNodes s + 1 + nNodes t <br />
= 2 + nNodes s + nNodes t<br />
<br />
nNodes tree = 1 + nNodes s + nNodes t<br />
</haskell><br />
<br />
Now, since the statement is proven for each of the cases in the structural description of the data, it follows form the principle of structural induction that the proof is finished.<br />
<br />
In order to really nail down what we are doing here, we need to define what we mean by predicates in a strict manner. There is a way to do this using ''fibrations'', but this reaches far outside the scope of this course. For the really interested reader, I'll refer to [http://www.springerlink.com/content/d022nlv03n26nm03/]. <br />
<br />
Another way to do this is to introduce a ''topos'', and work it all out in terms of its ''internal logic'', but again, this reaches outside the scope of this course.<br />
<br />
====Lambek's lemma====<br />
<br />
What we do when we write a recursive data type definition in Haskell ''really'' to some extent is to define a data type as the initial algebra of the corresponding functor. This intuitive equivalence is vindicated by the following <br />
<br />
'''Lemma''' ''Lambek'' If <math>P: C\to C</math> has an initial algebra <math>I</math>, then <math>P(I) = I</math>.<br />
<br />
'''Proof''' Let <math>a: PA\to A</math> be an initial <math>P</math>-algebra. We can apply <math>P</math> again, and get a chain<br />
:<math>PPA \to^{Pa} PA \to^a A</math><br />
We can fill out the diagram<br />
:[[Image:LambekPartialDiagram.png]]<br />
to form the diagram<br />
:[[Image:LambekDiagram.png]]<br />
where <math>f</math> is induced by initiality, since <math>Pa:PPa\to Pa</math> is also a <math>P</math>-algebra.<br />
<br />
The diagram above commutes, and thus <math>af = 1_{PA}</math> and <math>fa = 1_A</math>. Thus <math>f</math> is an inverse to <math>a</math>. QED.<br />
<br />
Thus, by Lambek's lemma we ''know'' that if <math>P_A(X) = 1 + A\times X</math> then for that <math>P_A</math>, the initial algebra - should it exist - will fulfill<math>I = 1 + A\times I</math>, which in turn is exactly what we write, defining this, in Haskell code: <br />
<haskell><br />
List a = Nil | Cons a List<br />
</haskell><br />
<br />
====Recursive definitions with the unique maps from the initial algebra====<br />
<br />
Consider the following <math>P_A(X)</math>-algebra structure <math>l: P_A(\mathbb N)\to\mathbb N</math> on the natural numbers:<br />
<haskell><br />
l(*) = 0<br />
l(a,n) = 1 + n<br />
</haskell><br />
<br />
We get a unique map <math>f</math> from the initial algebra for <math>P_A(X)</math> (lists of elements of type <math>A</math>) to <math>\mathbb N</math> from this definition. This map will fulfill:<br />
<haskell><br />
f(Nil) = l(*) = 0<br />
f(Cons a xs) = l(a,f(xs)) = 1 + f(xs)<br />
</haskell><br />
which starts taking on the shape of the usual definition of the length of a list:<br />
<haskell><br />
length(Nil) = 0<br />
length(Cons a xs) = 1 + length(xs)<br />
</haskell><br />
<br />
And thus, the machinery of endofunctor algebras gives us a strong method for doing recursive definitions in a theoretically sound manner.<br />
<br />
===Homework===<br />
<br />
Complete credit will be given for 8 of the 13 questions.<br />
<br />
# Find a monad whose algebras are ''associative algebras'': vector spaces with a binary, associative, unitary operation (multiplication) defined on them. Factorize the monad into a free/forgetful adjoint pair.<br />
# Find an endofunctor of <math>Hask</math> whose initial object describes trees that are either binary of ternary at each point, carrying values from some <math>A</math> in the leaves.<br />
# Write an implementation of the monad of vector spaces in Haskell. If this is tricky, restrict the domain of the monad to, say, a 3-element set, and implement the specific example of a 3-dimensional vector space as a monad. Hint: [http://sigfpe.blogspot.com] has written about this approach.<br />
# Find a <math>X\mapsto 1+A\times X</math>-algebra <math>L</math> such that the unique map from the initial algebra <math>I</math> to <math>L</math> results in the function that will reverse a given list.<br />
# Find a <math>X\mapsto 1+A\times X</math>-algebra structure on the object <math>1+A</math> that will pick out the first element of a list, if possible.<br />
# Find a <math>X\mapsto \mathbb N+X\times X</math>-algebra structure on the object <math>\mathbb N</math> that will pick out the sum of the leaf values for the binary tree in the initial object.<br />
# Complete the proof of Lambek's lemma by proving the diagram commutes.<br />
# * We define a ''coalgebra'' for an endofunctor <math>T</math> to be some arrow <math>\gamma: A \to TA</math>. If <math>T</math> is a comonad - i.e. equipped with a counit <math>\epsilon: T\to 1</math> and a cocomposition <math>\Delta: T\to T\times T</math>, then we define a coalgebra for the comonad <math>T</math> to additionally fulfill <math>\gamma\circ T\gamma = \gamma\circ\Delta</math> (compatibility) and <math>\epsilon_A\circ\gamma = 1_A</math> (counitality).<br />
## (2pt) Prove that if <math>T</math> is an endofunctor, then if <math>T</math> has an initial algebra, then it is a coalgebra. Does <math>T</math> necessarily have a final coalgebra?<br />
## (2pt) Prove that if <math>U,F</math> are an adjoint pair, then <math>FU</math> forms a comonad.<br />
## (2pt) Describe a final coalgebra over the comonad formed from the free/forgetful adjunction between the categories of Monoids and Sets.<br />
## (2pt) Describe a final coalgebra over the endofunctor <math>P(X) = 1 + X</math>.<br />
## (2pt) Describe a final coalgebra over the endofunctor <math>P(X) = 1 + A\times X</math>.<br />
## (2pt) Prove that if <math>c: C\to PC</math> is a final coalgebra for an endofunctor <math>P:C\to C</math>, then <math>c</math> is an isomorphism.</div>Michiexilehttps://wiki.haskell.org/index.php?title=File:LambekDiagram.png&diff=31529File:LambekDiagram.png2009-11-11T18:58:03Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:LambekPartialDiagram.png&diff=31528File:LambekPartialDiagram.png2009-11-11T18:57:30Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_8&diff=31527User:Michiexile/MATH198/Lecture 82009-11-11T18:53:44Z<p>Michiexile: </p>
<hr />
<div>IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.<br />
<br />
<br />
===Algebras over monads===<br />
<br />
We recall from the last lecture the definition of an Eilenberg-Moore algebra over a monad <math>T = (T, \eta, \mu)</math>: <br />
<br />
'''Definition''' An ''algebra'' over a monad <math>T</math> in a category <math>C</math> (a <math>T</math>-algebra) is a morphism <math>\alpha\in C(TA, A)</math>, such that the diagrams below both commute:<br />
<br />
[[Image:EilenbergMooreUnity.png]]<br />
[[Image:EilenbergMooreAssociativity.png]]<br />
<br />
While a monad corresponds to the imposition of some structure on the objects in a category, an algebra over that monad corresponds to some evaluation of that structure. <br />
<br />
====Example: monoids====<br />
<br />
Let <math>T</math> be the Kleene star monad - the one we get from the adjunction of free and forgetful functors between Monoids and Sets. Then a <math>T</math>-algebra on a set <math>A</math> is equivalent to a monoid structure on <math>A</math>.<br />
<br />
Indeed, if we have a monoid structure on <math>A</math>, given by <math>m:A^2\to A</math> and <math>u:1\to A</math>, we can construct a <math>T</math>-algebra by<br />
:<math>\alpha([]) = u</math><br />
:<math>\alpha([a_1,a_2,\dots,a_n]) = m(a_1,\alpha([a_2,\dots,a_n]))</math><br />
This gives us, indeed, a <math>T</math>-algebra structure on <math>A</math>. Associativity and unity follows from the corresponding properties in the monoid.<br />
<br />
On the other hand, if we have a <math>T</math>-algebra structure on <math>A</math>, we can construct a monoid structure by setting<br />
:<math>u = \alpha([])</math><br />
:<math>m(a,b) = \alpha([a,b])</math> <br />
It is clear that associativity of <math>m</math> follows from the associativity of <math>\alpha</math>, and unitality of <math>u</math> follows from the unitality of <math>\alpha</math>.<br />
<br />
(((potential headache: shouldn't <math>\eta</math> show up more? Instead of the empty list, maybe?)))<br />
<br />
====Example: Vector spaces====<br />
<br />
We have free and forgetful functors <br />
:<math>Set \to^{free} k-Vect \to^{forgetful} Set</math><br />
forming an adjoint pair; where the free functor takes a set <math>S</math> and returns the vector space with basis <math>S</math>; while the forgetful functor takes a vector space and returns the set of all its elements.<br />
<br />
The composition of these yields a monad <math>T</math> in <math>Set</math> taking a set <math>S</math> to the set of all formal linear combinations of elements in <math>S</math>. The monad multiplication takes formal linear combinations of formal linear combinations and multiplies them out:<br />
:<math>3(2v+5w)-5(3v+2w) = 6v+15w-15v-10w = -9v+5w</math><br />
<br />
A <math>T</math>-algebra is a map <math>\alpha: TA\to A</math> that ''acts like a vector space'' in the sense that <math>\alpha(\sum\alpha_i(\sum\beta_jv_j)) = \alpha(\sum\alpha_i\beta_jv_j)</math>.<br />
<br />
We can define <math>\lambda\cdot v = \alpha(\lambda v)</math> and <math>v+w=\alpha(v+w)</math>. The operations thus defined are associative, distributive, commutative, and everything else we could wish for in order to define a vector space - precisely because the operations inside <math>TA</math> are, and <math>\alpha</math> is associative. <br />
<br />
----<br />
<br />
The moral behind these examples is that using monads and monad algebras, we have significant power in defining and studying algebraic structures with categorical and algebraic tools. This paradigm ties in closely with the theory of ''operads'' - which has its origins in topology, but has come to good use within certain branches of universal algebra.<br />
<br />
An (non-symmetric) ''operad'' is a graded set <math>O = \bigoplus_i O_i</math> equipped with composition operations <math>\circ_i: O_n\oplus O_m\to O_{n+m-1}</math> that obey certain unity and associativity conditions. As it turns out, non-symmetric operads correspond to the summands in a monad with polynomial underlying functor, and from a non-symmetric operad we can construct a corresponding monad.<br />
<br />
The designator non-symmetric floats in this text o avoid dealing with the slightly more general theory of symmetric operads - which allow us to resort the input arguments, thus including the symmetrizer of a symmetric monoidal category in the entire definition. <br />
<br />
To read more about these correspondences, I can recommend you start with: the blog posts ''Monads in Mathematics'' here:<br />
[http://embuchestissues.wordpress.com/tag/monads-in-mathematics/]<br />
<br />
<br />
===Algebras over endofunctors===<br />
<br />
Suppose we started out with an endofunctor that is not the underlying functor of a monad - or an endofunctor for which we don't want to settle on a monadic structure. We can still do a lot of the Eilenberg-Moore machinery on this endofunctor - but we don't get quite the power of algebraic specification that monads offer us. At the core, here, lies the lack of associativity for a generic endofunctor - and algebras over endofunctors, once defined, will correspond to non-associative correspondences to their monadic counterparts.<br />
<br />
'''Definition''' For an endofunctor <math>P:C\to C</math>, we define a ''<math>P</math>-algebra'' to be an arrow <math>\alpha\in C(PA,A)</math>.<br />
<br />
A homomorphism of <math>P</math>-algebras <math>\alpha\to\beta</math> is some arrow <math>f:A\to B</math> such that the diagram below commutes:<br />
:[[Image:EilenbergMoorePMorphism.png]]<br />
<br />
This homomorphism definition does not need much work to apply to the monadic case as well.<br />
<br />
====Example: Groups====<br />
<br />
A group is a set <math>G</math> with operations <math>u: 1\to G, i: G\to G, m: G\times G\to G</math>, such that <math>u</math> is a unit for <math>m</math>, <math>m</math> is associative, and <math>i</math> is an inverse.<br />
<br />
Ignoring for a moment the properties, the theory of groups is captured by these three maps, or by a diagram<br />
:[[Image:GroupDiagram.png]]<br />
<br />
We can summarize the diagram as<br />
:<math>1+G+G\times G \mapsto^{[u,i,m]} G</math><br />
and thus recognize that groups are some equationally defined subcategory of the category of <math>T</math>-algebras for the polynomial functor <math>T(X) = 1 + X + X\times X</math>. The subcategory is ''full'', since if we have two algebras <math>\gamma: T(G)\to G</math> and <math>\eta: T(H)\to H</math>, that both lie within the subcategory that fulfills all the additional axioms, then certainly any morphism <math>\gamma\to\eta</math> will be compatible with the structure maps, and thus will be a group homomorphism.<br />
<br />
----<br />
<br />
We shall denote the category of <math>P</math>-algebras in a category <math>C</math> by <math>P-Alg(C)</math>, or just <math>P-Alg</math> if the category is implicitly understood.<br />
<br />
This category is wider than the corresponding concept for a monad. We don't require the kind of associativity we would for a monad - we just lock down the underlying structure. This distinction is best understood with an example: <br />
<br />
The free monoids monad has monoids for its algebras. On the other hand, we can pick out the underlying functor of that monad, forgetting about the unit and multiplication. An algebra over this structure is a slightly more general object: we no longer require <math>(a\cdot b)\cdot c = a\cdot (b\cdot c)</math>, and thus, the theory we get is that of a ''magma''. We have concatenation, but we can't drop the brackets, and so we get something more reminiscent of a binary tree. <br />
<br />
===Initial <math>P</math>-algebras and recursion===<br />
<br />
Consider the polynomical functor <math>P(X) = 1 + X</math> on the category of sets. It's algebras form a category, by the definitions above - and an algebra needs to pick out one special element 0, and one endomorphism T, for a given set.<br />
<br />
What would an initial object in this category of P-algebras look like? It would be an object <math>I</math> equipped with maps <math>1 \to^o I \leftarrow^n I</math>. For any other pair of maps <math>a: 1\to X, s: X\to X</math>, we'd have a unique arrow <math>u: I\to X</math> such that <br />
:[[Image:NNOcommutes.png]]<br />
commutes, or in equations such that<br />
:<math>u(o) = a</math><br />
:<math>u(n(x)) = s(u(x))</math><br />
<br />
Now, unwrapping the definitions in place, we notice that we will have elements <math>o, n(o), n(n(o), \dots</math> in <math>I</math>, and the initiality will force us to not have any ''other'' elements floating around. Also, intiality will prevent us from having any elements not in this minimally forced list.<br />
<br />
We can rename the elements to form something more recognizable - by equating an element in <math>I</math> with the number of applications of <math>n</math> to <math>o</math>. This yields, for us, elements <math>0, 1, 2, \dots</math> with one function that picks out the <math>0</math>, and another that gives us the cussessor.<br />
<br />
This should be recognizable as exactly the natural numbers; with just enough structure on them to make the principle of mathematical induction work: suppose we can prove some statement <math>P(0)</math>, and we can extend a proof of <math>P(n)</math> to <math>P(n+1)</math>. Then induction tells us that the statement holds for all <math>P(n)</math>.<br />
<br />
More importantly, recursive definitions of functions from natural numbers can be performed here by choosing an appropriate algebra mapping to.<br />
<br />
This correspondence between the initial object of <math>P(X) = 1 + X</math> is the reason such an initial object in a category with coproducts and terminal objects is called a ''natural numbers object''. <br />
<br />
For another example, we consider the functor <math>P(X) = 1 + X\times X</math>. <br />
<br />
'''Pop Quiz''' Can you think of a structure with this as underlying defining functor?<br />
<br />
An initial <math>1+X\times X</math>-algebra would be some diagram<br />
:<math>1 \to^o I \leftarrow^m I\times I</math><br />
such that for any other such diagram<br />
:<math>1 \to^a X \leftarrow^* X\times X</math><br />
we have a unique arrow <math>u:I\to X</math> such that<br />
:[[Image:MonoidCommutes.png]]<br />
commutes.<br />
<br />
Unwrapping the definition, working over Sets again, we find we are forced to have some element <math>*</math>, the image of <math>o</math>. Any two elements <math>S,T</math> in the set give rise to some <math>(S,T)</math>, which we can view as being the binary tree<br />
:[[Image:MagmaComposition.png]]<br />
<br />
The same way that we could construct induction as an algebra map from a natural numbers object, we can use this object to construct a tree-shaped induction; and similarily, we can develop what amounts to the theory of ''structural induction'' using these more general approaches to induction.<br />
<br />
====Example of structural induction====<br />
<br />
Using the structure of <math>1+X\times X</math>-algebras we shall prove the following statement:<br />
<br />
'''Proposition''' The number of leaves in a binary tree is one more than the number of internal nodes.<br />
<br />
'''Proof''' We write down the actual Haskell data type for the binary tree initial algebra.<br />
<haskell><br />
data Tree = Leaf | Node Tree Tree<br />
<br />
nLeaves Leaf = 1<br />
nLeaves (Node s t) = nLeaves s + nLeaves t<br />
<br />
nNodes Leaf = 0<br />
nNodes (Node s t) = 1 + nNodes s + nNodes t<br />
</haskell><br />
<br />
Now, it is clear, as a base case, that for the no-nodes tree <hask>Leaf</hask>:<br />
<haskell><br />
nLeaves Leaf = 1 + nNodes Leaf<br />
</haskell><br />
<br />
For the structural induction, now, we consider some binary tree, where we assume the statement to be known for each of the two subtrees. Hence, we have<br />
<haskell><br />
tree = Node s t<br />
<br />
nLeaves s = 1 + nNodes s<br />
nLeaves t = 1 + nNodes t<br />
</haskell><br />
and we may compute<br />
<haskell><br />
nLeaves tree = nLeaves s + nLeaves t <br />
= 1 + nNodes s + 1 + nNodes t <br />
= 2 + nNodes s + nNodes t<br />
<br />
nNodes tree = 1 + nNodes s + nNodes t<br />
</haskell><br />
<br />
Now, since the statement is proven for each of the cases in the structural description of the data, it follows form the principle of structural induction that the proof is finished.<br />
<br />
In order to really nail down what we are doing here, we need to define what we mean by predicates in a strict manner. There is a way to do this using ''fibrations'', but this reaches far outside the scope of this course. For the really interested reader, I'll refer to [http://www.springerlink.com/content/d022nlv03n26nm03/]. <br />
<br />
Another way to do this is to introduce a ''topos'', and work it all out in terms of its ''internal logic'', but again, this reaches outside the scope of this course.<br />
<br />
====Lambek's lemma====<br />
<br />
What we do when we write a recursive data type definition in Haskell ''really'' to some extent is to define a data type as the initial algebra of the corresponding functor. This intuitive equivalence is vindicated by the following <br />
<br />
'''Lemma''' ''Lambek'' If <math>P: C\to C</math> has an initial algebra <math>I</math>, then <math>P(I) = I</math>.<br />
<br />
'''Proof''' Let <math>a: PA\to A</math> be an initial <math>P</math>-algebra. We can apply <math>P</math> again, and get a chain<br />
:<math>PPA \to^{Pa} PA \to^a A</math><br />
We can fill out the diagram<br />
:[[Image:LambekPartialDiagram.png]]<br />
to form the diagram<br />
:[[Image:LambekDiagram.png]]<br />
where <math>f</math> is induced by initiality, since <math>Pa:PPa\to Pa</math> is also a <math>P</math>-algebra.<br />
<br />
The diagram above commutes, and thus <math>af = 1_{PA}</math> and <math>fa = 1_A</math>. Thus <math>f</math> is an inverse to <math>a</math>. QED.<br />
<br />
Thus, by Lambek's lemma we ''know'' that if <math>P_A(X) = 1 + A\times X</math> then for that <math>P_A</math>, the initial algebra - should it exist - will fulfill<math>I = 1 + A\times I</math>, which in turn is exactly what we write, defining this, in Haskell code: <br />
<haskell><br />
List a = Nil | Cons a List<br />
</haskell><br />
<br />
====Recursive definitions with the unique maps from the initial algebra====<br />
<br />
Consider the following <math>P_A(X)</math>-algebra structure <math>l: P_A(\mathbb N)\to\mathbb N</math> on the natural numbers:<br />
<haskell><br />
l(*) = 0<br />
l(a,n) = 1 + n<br />
</haskell><br />
<br />
We get a unique map <math>f</math> from the initial algebra for <math>P_A(X)</math> (lists of elements of type <math>A</math>) to <math>\mathbb N</math> from this definition. This map will fulfill:<br />
<haskell><br />
f(Nil) = l(*) = 0<br />
f(Cons a xs) = l(a,f(xs)) = 1 + f(xs)<br />
</haskell><br />
which starts taking on the shape of the usual definition of the length of a list:<br />
<haskell><br />
length(Nil) = 0<br />
length(Cons a xs) = 1 + length(xs)<br />
</haskell><br />
<br />
And thus, the machinery of endofunctor algebras gives us a strong method for doing recursive definitions in a theoretically sound manner.<br />
<br />
===Homework===<br />
<br />
Complete credit will be given for 8 of the 13 questions.<br />
<br />
# Find a monad whose algebras are ''associative algebras'': vector spaces with a binary, associative, unitary operation (multiplication) defined on them. Factorize the monad into a free/forgetful adjoint pair.<br />
# Find an endofunctor of <math>Hask</math> whose initial object describes trees that are either binary of ternary at each point, carrying values from some <math>A</math> in the leaves.<br />
# Write an implementation of the monad of vector spaces in Haskell. If this is tricky, restrict the domain of the monad to, say, a 3-element set, and implement the specific example of a 3-dimensional vector space as a monad. Hint: [http://sigfpe.blogspot.com] has written about this approach.<br />
# Find a <math>X\mapsto 1+A\times X</math>-algebra <math>L</math> such that the unique map from the initial algebra <math>I</math> to <math>L</math> results in the function that will reverse a given list.<br />
# Find a <math>X\mapsto 1+A\times X</math>-algebra structure on the object <math>1+A</math> that will pick out the first element of a list, if possible.<br />
# Find a <math>X\mapsto \mathbb N+X\times X</math>-algebra structure on the object <math>\mathbb N</math> that will pick out the sum of the leaf values for the binary tree in the initial object.<br />
# Complete the proof of Lambek's lemma by proving the diagram commutes.<br />
# * We define a ''coalgebra'' for an endofunctor <math>T</math> to be some arrow <math>\gamma: A \to TA</math>. If <math>T</math> is a comonad - i.e. equipped with a counit <math>\epsilon: T\to 1</math> and a cocomposition <math>\Delta: T\to T\times T</math>, then we define a coalgebra for the comonad <math>T</math> to additionally fulfill <math>\gamma\circ T\gamma = \gamma\circ\Delta</math> (compatibility) and <math>\epsilon_A\circ\gamma = 1_A</math> (counitality).<br />
## (2pt) Prove that if <math>T</math> is an endofunctor, then if <math>T</math> has an initial algebra, then it is a coalgebra. Does <math>T</math> necessarily have a final coalgebra?<br />
## (2pt) Prove that if <math>U,F</math> are an adjoint pair, then <math>FU</math> forms a comonad.<br />
## (2pt) Describe a final coalgebra over the comonad formed from the free/forgetful adjunction between the categories of Monoids and Sets.<br />
## (2pt) Describe a final coalgebra over the endofunctor <math>P(X) = 1 + X</math>.<br />
## (2pt) Describe a final coalgebra over the endofunctor <math>P(X) = 1 + A\times X</math>.<br />
## (2pt) Prove that if <math>c: C\to PC</math> is a final coalgebra for an endofunctor <math>P:C\to C</math>, then <math>c</math> is an isomorphism.</div>Michiexilehttps://wiki.haskell.org/index.php?title=File:MagmaComposition.png&diff=31526File:MagmaComposition.png2009-11-11T18:42:02Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:MonoidCommutes.png&diff=31525File:MonoidCommutes.png2009-11-11T18:41:45Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:NNOcommutes.png&diff=31524File:NNOcommutes.png2009-11-11T18:41:24Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:GroupDiagram.png&diff=31523File:GroupDiagram.png2009-11-11T18:41:00Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:EilenbergMoorePMorphism.png&diff=31522File:EilenbergMoorePMorphism.png2009-11-11T18:40:40Z<p>Michiexile: </p>
<hr />
<div></div>Michiexilehttps://wiki.haskell.org/index.php?title=File:EilenbergMooreAssociativity.png&diff=31521File:EilenbergMooreAssociativity.png2009-11-11T18:39:45Z<p>Michiexile: </p>
<hr />
<div></div>Michiexile