Hi Jonathan (#21), relational database theory can help find all the natural transformations I => J quickly, where I, J : C -> Set, and I is small relative to J. The reason is that I can be thought of as a 'conjunctive query' Q^I (this is getting a bit far afield but these are great slides: https://classes.soe.ucsc.edu/cmps277/Winter10/Lectures/lect8-w10.pdf ). It turns out that finding all the natural transformations I => J is the same problem as evaluating Q^I on instance J.

Anyway, the key idea is that if I is small and J is large, you can translate I into a SQL query and J into a SQL database, run the query, and then recover the set of natural transformations I => J. In fact you can even arrange these onto the schema C, since the category C->Set is cartesian closed, J^I is also an object of C.

To try to make this concrete, suppose C is the arrow category f : A -> B, and for each natural number n, let I_n be the functor C -> Set defined as I_n(a) = I_n(b) = {n} and I_n(f)(n) = n. Suppose we want to find the natural transformations I_1 + I_2 => I_3 + I_4 + I_5. The instance J := I_3 + I_4 + I_5 has J(A) = J(B) = {3,4,5} and J(f) = id. The SQL query Q^I(J) for instance I_1 + I_2 is "FROM J as I_1, J as I_2", and returns 9 rows, as expected. What's neat is that no matter how complicated I is, you can still write Q^I using SELECT, FROM, WHERE, and the SQL query optimizer takes care of finding a way to quickly execute the query.

Anyway, the key idea is that if I is small and J is large, you can translate I into a SQL query and J into a SQL database, run the query, and then recover the set of natural transformations I => J. In fact you can even arrange these onto the schema C, since the category C->Set is cartesian closed, J^I is also an object of C.

To try to make this concrete, suppose C is the arrow category f : A -> B, and for each natural number n, let I_n be the functor C -> Set defined as I_n(a) = I_n(b) = {n} and I_n(f)(n) = n. Suppose we want to find the natural transformations I_1 + I_2 => I_3 + I_4 + I_5. The instance J := I_3 + I_4 + I_5 has J(A) = J(B) = {3,4,5} and J(f) = id. The SQL query Q^I(J) for instance I_1 + I_2 is "FROM J as I_1, J as I_2", and returns 9 rows, as expected. What's neat is that no matter how complicated I is, you can still write Q^I using SELECT, FROM, WHERE, and the SQL query optimizer takes care of finding a way to quickly execute the query.