• Stars
    star
    731
  • Rank 59,847 (Top 2 %)
  • Language Coq
  • License
    BSD 3-Clause "New...
  • Created almost 10 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An axiom-free formalization of category theory in Coq for personal study and practical work

Category Theory in Coq

This development encodes category theory in Coq, with the primary aim being to allow representation and manipulation of categorical terms, as well realization of those terms in various target categories.

  • Versions used: Coq 8.14.1, 8.15.2, 8.16+rc1.
  • Some parts depend on Coq-Equations 1.2.4, 1.3.

Usage

It is recommended to include this library in your developments by adding the following to your _CoqProject file:

-R <path to this library> Category

Then include the primary elements of the library using:

Require Import Category.Theory.

Library structure

This library is broken up into several major areas:

  • Core Theory, covering topics such as categories, functors, natural transformations, adjunctions, kan extensions, etc.

  • Categorical Structure, which reveals internal structure of a category by way of morphisms related to some universal property.

  • Categorical Construction, which introduces external structure by building new categories out of existing ones.

  • Species of different kinds of Functor, Natural.Transformation, Adjunction and Kan.Extension; for example: categories with monoidal structure give rise to monoidal functors preserving this structure, which in turn leads to monoidal transformations that transform functors while preserving their monoidal mapping property.

  • The Instance directory defines various categories; some of these are fairly general, such as the category of preorders, applicable to any PreOrder relation, but in general these are either not defined in terms of other categories, or are sufficiently specific.

  • When a concept, such as limits, can be defined using more fundamental terms, that version of limits can be found in a subdirectory of the derived concept, for example there is Category.Structure.Limit and Category.Limit.Kan.Extension. This is done to demonstrate the relationship of ideas; for example: Category.Construction.Comma.Natural.Transformation. As a result, files with the same name occur often, with the parent directory establishing intent.

Programming sub-library

Within Theory.Coq there is now a sub-library that continues work started in the coq-haskell library. This sub-library is specifically aimed at "applied category theory" for programmers in the category of Coq types and functions. The aim is to mimic the utility of Haskell's monad hierarchy -- but for Coq users, similar to what ext-lib achieves. I've also adjusted a few of my notations to more closely match ext-lib.

Where this library differs, and what is considered the main contribution of this work, is that laws are not defined for these structures in the sub-library. Rather, the programmer establishs that her Monad is lawful by proving that a mapping exists from that definition into the general definition of monads (found in Theory.Monad) specialized to the category Coq. In this way the rest of the category-theory library is leveraged to discharge these proof obligations, while keeping the programmatic side as simple as possible.

For example, it is trivial to define the composition of two Applicatives. What is not so trivial is proving that this is truly an Applicative, based on that simple definition. While this proof was done in coq-haskell, it requires a bit of Ltac magic to keep the size down:

Program Instance Compose_ApplicativeLaws
  `{ApplicativeLaws F} `{ApplicativeLaws G} : ApplicativeLaws (F \o G).
Obligation 2. (* ap_composition *)
  (* Discharge w *)
  rewrite <- ap_comp; f_equal.
  (* Discharge v *)
  rewrite <- !ap_fmap, <- ap_comp.
  symmetry.
  rewrite <- ap_comp; f_equal.
  (* Discharge u *)
  apply_applicative_laws.
  f_equal.
  extensionality y.
  extensionality x.
  extensionality x0.
  rewrite <- ap_comp, ap_fmap.
  reflexivity.
Qed.

What's ill-gotten about this proof is that it's confined to the very specific case of Coq applicative endo-functors. However, there is a more general truth, which is that any two lax monoidal functors in any monoidal category also compose. So why not appeal to that proof to establish that our programmatic applicative in Coq is lawful by construction?

This is what the new sub-library does. Since the more general proof is already completed (and is too large to paste here), one may appeal to it directly to establish the desired fact:

(* The composition of two applicatives is itself applicative. We establish
   this by appeal to the general proofs that:

   1. every Coq functor has strength;
   2. (also, but not needed: any two strong functors compose to a strong
      functor; if it is a Coq functor it is known to have strength); and
   3. any two lax monoidal functors compose to a lax monoidal functor. *)

Theorem Compose_IsApplicative
  `(HF : EndoFunctor F)
  `(AF : @Functor.Applicative.Applicative _ _ (FromAFunctor HF))
  `(HG : EndoFunctor G)
  `(AG : @Functor.Applicative.Applicative _ _ (FromAFunctor HG)) :
  IsApplicative (Compose_IsFunctor HF HG)
    (@Compose_Applicative
       F HF (EndoApplicative_Applicative HF AF)
       G HG (EndoApplicative_Applicative HG AG)).
Proof.
  construct.
  - apply (@Compose_LaxMonoidalFunctor _ _ _ _ _ _ _ _ AF AG).
  - apply Coq_StrongFunctor.
Qed.

This proof pulls in several instances to establish that the category Coq is cartesian, closed, and thus closed monoidal, etc.

The hope is this will become a happy marriage of simple, useful computational constructions for Coq programmers, with relevant proof results from what category theory tells us about these structures in general, such as the above fact concerning composition of monoidal functors.

Duality

The core theory is defined in such a way that "the dual of the dual" is evident to Coq by mere simplification (that is, "C^op^op = C" follows by reflexivity for the opposite of the opposite of categories, functors, natural transformation, adjunctions, isomorphisms, etc.).

For this to be true, certain artificial constructions are necessary, such as repeating the associativity law for categories in symmetric form, and likewise the naturality condition of natural transformations. This repeats proof obligations when constructing these objects, but pays off in the ability to avoid repetition when stating the dual of whole structures.

As a result, the definition of comonads, for example, is reduced to one line:

Definition Comonad `{M : C โŸถ C} := @Monad (C^op) (M^op).

Most dual constructions are similarly defined, with the exception of Initial and Cocartesian structures. Although the core classes are indeed defined in terms of their dual construction, an alternate surface syntax and set of theorems is provided (for example, using a + b to indicate coproducts) to make life is a little less confusing for the reader. For instance, it follows from duality that 0 + X โ‰… X is just 1 ร— X โ‰… X in the opposite category, but using separate notations makes it easier to see that these two isomorphisms in the same category are not identical. This is especially important because Coq hides implicit parameters that would usually let you know duality is involved.

Design decisions

Some features and choices made in this library:

  • Type classes are used throughout to present concepts. When a type class instance would be too general -- and thus overlap with other instances -- it is presented as a definition that can later be added to instance resolution with Existing Instance.

  • All definitions are in Type, so that Prop is not used anywhere except specific category instances defined over Prop, such as the category Rel with heterogeneous relations as arrows.

  • No axioms are used anywhere in the core theory; they appear only at times when defining specific category instances, mostly for the Coq category.

  • Homsets are defined as computationally-relevant homsetoids (that is, using crelation). This is done using a variant of the Setoid type class defined for this library; likewise, the category of Sets is actually the category of such setoids. This increases the proof work necessary to establish definitions -- since preservation of the equivalence relation is required at all levels -- but allows categories to be flexible in what it means for two arrows to be equivalent.

Notations

There are many notations used through the library, which are chosen in an attempt to make complex constructions appear familiar to those reading modern texts on category theory. Some of the key notations are:

  • โ‰ˆ is equivalence; equality is almost never used.
  • โ‰ˆ[Cat] is equivalence between arrows of some category, here Cat; this is only needed when type inference fails because it tries to find both the type of the arguments, and the type class instance for the equivalence
  • โ‰… is isomorphism; apply it with to or from
  • โ‰Š is used specifically for isomorphisms between homsets in Sets
  • isoโปยน also indicates the reverse direction of an isomorphism
  • X ~> Y: a squiggly arrow between objects is a morphism
  • X ~{C}~> Y: squiggly arrows may also specify the intended category
  • id[C]: many known morphisms allow specifying the intended category; sometimes this is even used in the printing format
  • C โŸถ D: a long right arrow between categories is a functor
  • F โŸน G: a long right double arrow between functors is a natural transformation
  • f โˆ˜ g: a small centered circle is composition of morphisms, or horizontal composition generally
  • f โˆ˜[Cat] g: composition can specify the intended category, as an aid to type inference composition generally
  • f โ—‹ g: a larger hollow circle is composition of functors
  • f โŠ™ g: a larger circle with a dot is composition of isomorphisms
  • f โˆ™ g: a solid composition dot is composition of natural transformations, or vertical composition generally
  • f โŠš g: a larger circle with a smaller circle is composition of adjunctions
  • ([C, D]): A pair of categories in square brackets is another way to give the type of a functor, being an object of the category Fun(C, D)
  • F ~{[C, D]}~> G: An arrow in a functor category is a natural transformation
  • F โŠฃ G: the turnstile is used for adjunctions
  • Cartesian categories use โ–ณ as the fork operation and ร— for products
  • Cocartesian categories use โ–ฝ as the merge operation and + for coproducts
  • Closed categories use ^ for exponents and โ‰ˆ> for the internal hom
  • As objects, the numbers 0 and 1 refer to initial and terminal objects
  • As categories, the numbers 0 and 1 refer to the initial and terminal objects of Cat
  • Products of categories can be specified using โˆ, which does not require pulling in the cartesian definition of Cat
  • Coproducts of categories can be specified using โˆ, which does not require pulling in the cocartesian definition of Cat
  • Products of functors are given with F โˆโŸถ G, combining product and functor notations; the same for โˆโŸถ
  • Comma categories of two functors are given by (F โ†“ G)
  • Likewise, the arrow category of Cโƒ—
  • Slice categories use a unicode forward slash Cฬธc, since the normal forward slash is not considered an operator
  • Coslice categories use c ฬธco C, to avoid ambiguity

Future directions

Computational Solver

There are some equivalences in category-theory that are very easily expressed and proven, but slow to establish in Coq using only symbolic term rewriting. For example:

(f โˆ˜ g) โ–ณ (h โˆ˜ i) โ‰ˆ split f h โˆ˜ g โ–ณ i

This is solved by unfolding the definition of split, and then rewriting so that the fork operation (here given by โ–ณ) absorbs the terms to its left, followed by observing the associativity of composition, and then simplify based on the universal properties of products. This is repeated several times until the prove is trivially completed.

Although this is easy to state, and even to write a tactic for, it can be extremely slow, especially when the types of the terms involved becomes large. A single rewrite can take several seconds to complete for some terms, in my experience.

The goal of this solver is to reify the above equivalence in terms of its fundamental operations, and then, using what we know about the laws of category theory, to compute the equivalence down to an equation on indices between the reduced terms. This is called computational reflection, and encodes the fact that our solution only depends on the categorical structure of the terms, and not their type.

That is, an incorrectly-built structure will simply fail to solve; but since we're reflecting over well-typed expressions to build the structure we pass to the solver, combined with a proof of soundness for that solver, we can know that solvable, well-typed, terms always give correct solutions. In this way, we transfer the problem to a domain without types, only indices, solve the structural problem there, and then bring the solution back to the domain of full types by way of the soundness proof.

Compiling to categories

Work has started in Tools/Abstraction for compiling monomorphic Gallina functions into "categorical terms" that can then be instantiated in any supporting target category using Coq's type class instance resolution.

This is as a Coq implementation of an idea developed by Conal Elliott, which he first implemented in and for Haskell. It is hoped that the medium of categories may provide a sound means for transporting Gallina terms into other syntactic domains, without relying on Coq's extraction mechanism.

License

This library is made available under the MIT license, a copy of which is included in the file LICENSE. Basically: you are free to use it for any purpose, personal or commercial (including proprietary derivates), so long as a copy of the license file is maintained in the derived work. Further, any acknowledgement referring back to this repository, while not necessary, is certainly appreciated.

John Wiegley

More Repositories

1

use-package

A use-package declaration for simplifying your .emacs
Emacs Lisp
4,365
star
2

git-scripts

A bunch of random scripts I've either written, downloaded or clipped from #git.
Shell
1,322
star
3

emacs-async

Simple library for asynchronous processing in Emacs
Emacs Lisp
813
star
4

git-from-the-bottom-up

An introduction to the architecture and design of the Git content manager
766
star
5

dot-emacs

My .emacs.el file and other personal Emacs goodies
Emacs Lisp
606
star
6

alert

A Growl-like alerts notifier for Emacs
Emacs Lisp
426
star
7

nix-config

My local Nix configuration
Emacs Lisp
399
star
8

gitlib

Haskell
176
star
9

coq-haskell

A library for formalizing Haskell types and functions in Coq
Coq
159
star
10

org-mode

This is a very old fork of Org-mode, but it's the version I still use every day
Emacs Lisp
155
star
11

emacs-chess

A complete chess client written in Emacs Lisp.
Emacs Lisp
122
star
12

coq-pipes

Coq
100
star
13

git-undo-el

A command for Emacs to regress or "undo" a region back through its Git history
Emacs Lisp
87
star
14

control-theory

Control theory in Haskell: Data structures, algorithms and adapters
Haskell
80
star
15

putting-lenses-to-work

A presentation for BayHac 2017 on how I uses lenses at work
Haskell
75
star
16

nix-update-el

An Emacs command for updating fetch declarations in place
Emacs Lisp
71
star
17

una

A universal interface to multiple unarchiving tools
Haskell
68
star
18

use-package-examples

Example declarations to demonstrate the features of use-package
52
star
19

regex-tool

A regular expression IDE for Emacs, to help with the creation and testing of regular expressions.
Emacs Lisp
50
star
20

git-annex-el

Emacs integration for the git-annex tool by Joey Hess
Emacs Lisp
43
star
21

notes

Haskell
42
star
22

z3cat

Use Conal Elliott's concat library to compile regular Haskell functions into Z3 equations
Haskell
38
star
23

emacs-release

A history of Emacs releases, under version control
Emacs Lisp
36
star
24

newartisans

HTML
35
star
25

emacs-pl

Emacs Lisp
31
star
26

bytestring-fiat

An implementation of the Haskell ByteString library using the Fiat system from MIT
Coq
31
star
27

periods

Common Lisp library for manipulating date/time objects at a higher level
Common Lisp
29
star
28

c2hsc

Utility for creating .hsc files from C API header files
Haskell
26
star
29

trade-journal

Code for keep an investment trade journal
Haskell
25
star
30

simple-conduit

Haskell
25
star
31

gdtoa

David M. Gay's floating-point conversion library
C
25
star
32

hours

Utility for showing hours worked within a work month against a target
Haskell
24
star
33

thinking-with-functions

A brief presentation on Denotational Design, based on Conal Elliott's work
Nix
23
star
34

comparable

A library for comparing data structures in Rust, oriented toward testing
Rust
21
star
35

async-pool

Haskell
21
star
36

parsec-free

Haskell
20
star
37

pushme

A script I use for synchronizing directories and ZFS pools between systems
Haskell
20
star
38

haskell-config

My haskell-mode configuration for Emacs
Emacs Lisp
19
star
39

categorical

Compiling to STLC to categories in Haskell and Coq, using Conal Elliot's work
Haskell
19
star
40

ghc-dynamic-example

An example of dynamically loading a Haskell source module
Haskell
18
star
41

scripts

Various and sundry shell scripts used on my system
Shell
17
star
42

linearscan

Coq
17
star
43

coq-lattice

A reflection-based proof tactic for lattices in Coq
Coq
16
star
44

git-all

Utility for finding all Git repositories that need attention
Haskell
16
star
45

coq-cds4ltl

A formalization of finite, constructive log analysis using linear temporal logic
Coq
16
star
46

springboard

An Emacs mode based on Helm that makes it easy to bounce around projects
Emacs Lisp
15
star
47

logging

Haskell
15
star
48

ready-lisp

A distribution of Aquamacs, SBCL and SLIME which offers the simplest way to run Common Lisp on Mac OS X
Emacs Lisp
14
star
49

haskell-to-c

Sample code to build a C library from a Haskell module, then call it from C
Haskell
12
star
50

markdown.net

A Markdown and SmartyPants processor written in C# for .NET.
C#
12
star
51

svndump

Library for parsing Subversion dump files from Haskell
Haskell
12
star
52

hello

Hello world project templates for getting started quickly with Nix
Nix
11
star
53

software-foundations

Nix-enabled and fully building mirror of Software Foundations WITHOUT SOLUTIONS
HTML
10
star
54

remember

A mode for Emacs which makes it easy to quickly jot down information.
Emacs Lisp
10
star
55

dirscan

Stateful directory scanning in Python. Makes a great ~/.Trash cleaner.
Python
9
star
56

pipes-files

Haskell
9
star
57

monad-extras

Haskell
9
star
58

cambl

Common Lisp library for working with commoditized amounts and balances
Common Lisp
9
star
59

sizes

Recursively show space (size and i-nodes) used in subdirectories
Haskell
9
star
60

disk-catalog

A Python script for cataloging offline media and disk archives.
Python
8
star
61

erc-yank

Automagically create a Gist in ERC if pasting more than 5 lines
Emacs Lisp
8
star
62

hierarchy

Haskell
8
star
63

simple-ltl

A simple compiler from LTL formulas to state machines
Haskell
7
star
64

linearscan-hoopl

Haskell
7
star
65

pcomplete

A programmable TAB completion facility for Emacs Lisp programmers. Used by Eshell.
Emacs Lisp
7
star
66

subconvert

A script to faithfully convert Subversion repositories to Git
C++
7
star
67

red-black

An efficient implementation of red-black trees for Common Lisp, by Jรผrgen Bรถhms Heimatseiten
Common Lisp
6
star
68

stringable

A Stringable type class, in the spirit of Foldable and Traversable
Haskell
6
star
69

gnus-harvest

Harvest e-mail addresses from read/written Gnus articles
Emacs Lisp
5
star
70

rs-ltl

A linear temporal logic library for Rust
Nix
5
star
71

start-kadena

My own Nix script for starting and testing a Kadena node
Nix
5
star
72

ipcvar

Haskell
5
star
73

set-theory

Coq
5
star
74

pipes-async

Haskell
5
star
75

eval-expr

Enhanced eval-expression command
Emacs Lisp
5
star
76

planner

A day-planner-like planning tool for Emacs; uses Muse to publish plan pages.
Emacs Lisp
5
star
77

sacred-writings

A bilingual typesetting of the Hidden Words
TeX
4
star
78

sitebuilder

Common Hakyll builder for my websites
Haskell
4
star
79

procman

A Rust library for managing a family of child processes
Rust
4
star
80

bcalc

Haskell
4
star
81

refine-freer

Experiments with an extensible refinement framework
Coq
4
star
82

wallet

Information about staking and management ICP tokens on the Internet Computer
Nix
4
star
83

haskell-infra

Some files related to administration of Haskell infrastructure
4
star
84

check-balance

Check your Kadena balance, as a Web service
Haskell
4
star
85

firewall

A rigorous set of firewall scripts for BSD ipfw, and Linux iptables
Shell
4
star
86

linkdups

Intelligently hard-link duplicate files in a directory tree
Python
4
star
87

haskell-c-stack

Experiments to determine how the C stack relates to the Haskell FFI
Haskell
3
star
88

runmany

Run multiple commands, interleaving output and errors
Haskell
3
star
89

johnwiegley

My personal website, at johnwiegley.com
HTML
3
star
90

zomega

A computational reflection based solver for expressions involving Z (but tunable)
Coq
3
star
91

rehoo

Utility to combine lots and lots of .hoo files in parallel
Haskell
3
star
92

consistent

Haskell
3
star
93

sshify

Script for setting up publickey authentication on new hosts
Shell
3
star
94

monad-base-control

A rewrite of monad-control which provides only MonadBaseControl
Haskell
3
star
95

haskell-quantification

Presentation on quantification in Haskell for South Bay Haskell
Haskell
3
star
96

muse

The Emacs Muse, a complete publishing environment written for Emacs.
Emacs Lisp
3
star
97

helm-hoogle

Use helm to navigate query results from Hoogle
Emacs Lisp
2
star
98

org-beamer-template

A quick template from which to start new presentations
Emacs Lisp
2
star
99

aasaan

A library for transliterating between different representations of the Arabic alphabet.
C++
2
star
100

kleisli

Haskell
2
star