Any Function induces a Galois Connection
between the preorders of partitions.
Sources: 7 Sketches §1.4.2, Examples 1.68, 1.102, 1.104, Exercises 1.69, 1.103, 1.105, 1.106.
Left adjoint (pushforward) . Given a partition of , declare if there are with and ; this need not be transitive, so take the transitive closure. “For a seasoned category theorist”: take the surjection and push out along to get a surjection .
Right adjoint (pullback) . Given a partition , set iff . Categorically: compose with and take the Epi-Mono Factorization to get the surjection . When is surjective the factorization is unnecessary and (Example 1.68).
Example 1.102. , , , , . The partition of is pushed forward to . Example 1.104 shows a pullback along a non-surjective map. 7S Exercise 1.106 checks the adjunction formula in examples.
This is the preorder shadow of the data migration adjunction and of the preimage adjunction; it is why every function, not just surjections, acts contravariantly on partitions.
Docs: FinSets · Limits & colimits · C-set morphisms
using Catlab
# partitions as surjections out of a FinSet; g : S → T
S, T = FinSet(4), FinSet(3)
g = FinFunction([1, 1, 2, 3], T) # 1,2 ↦ 12; 3 ↦ 3; 4 ↦ 4
c = FinFunction([1, 2, 3, 3], 3) # (1)(2)(34)
# pushforward g_!(c): pushout of c and g, then the leg out of T
po = pushout(c, g)
g_shriek_c = legs(po)[2] # T → P ⊔_S T ; parts: (12)(34)
# pullback g^*(d): s₁ ~ s₂ iff d(g(s₁)) == d(g(s₂)); the epi part of g⋅d
d = FinFunction([1, 1, 2], 2) # (12 3)(4) on T
g_star_d = first(epi_mono(compose(g, d))) # FinFunction([1,1,1,2], 2): (123)(4) on S-- partitions as functions to labels; pullback along g is precomposition
pullbackPart :: (s -> t) -> (t -> l) -> (s -> l)
pullbackPart g d = d . g
-- pushforward: relate t₁ ~ t₂ if some s₁ ~ s₂ map to them, then close transitively
pushforwardPart :: (Eq s, Eq t) => [s] -> (s -> t) -> (s -> s -> Bool) -> (t -> t -> Bool)
pushforwardPart ss g c = closure
where step t1 t2 = t1 == t2 || or [ c s1 s2 | s1 <- ss, s2 <- ss, g s1 == t1, g s2 == t2 ]
ts = map g ss
closure t1 t2 = go [t1] []
where go [] _ = False
go (x:xs) seen | x == t2 = True
| x `elem` seen = go xs seen
| otherwise = go (xs ++ [y | y <- ts, step x y]) (x:seen)