A Function is injective (an injection, drawn ) if for all and with we have . Equivalently (Kittenlab): whenever then .
Sources: 7 Sketches Definition 1.22, Exercise 1.24; Kittenlab Lecture 2; DaoFP §2.4 (monomorphisms); CTfS Definition 2.7.5.1, Proposition 2.7.5.4, Proposition 2.7.5.5, Example 2.7.5.7, Corollary 2.7.5.8
Examples. , , is injective (and not surjective). with is not. The unique function is injective but not surjective.
- Injective functions are exactly the monomorphisms in (DaoFP §2.4). Any arrow out of the Terminal Object is a monomorphism.
- Pullbacks of injections (CTfS Proposition 2.7.5.5, Example 2.7.5.7): pulling an injection back along any map gives an injection, and in an Olog such a pullback has a canonical label. Pulling “a cow an animal” back along “a rib an animal” gives “a rib which is made by a cow”. Every injection is the pullback of along its characteristic function (CTfS Corollary 2.7.5.8, Subobject Classifier).
- A function is a Bijection iff it is injective and surjective; then it has an inverse.
- The Pigeonhole Principle: a function from a larger finite set to a smaller one cannot be injective.
- An injection is the “Subobject” view of a Subset.
Docs: FinSets · C-set morphisms — Kittenlab Lecture 2
Builds on: Function (𝔽Mor) — run that note’s Julia code first.
# Kittenlab Lecture 2
function is_injective(f::𝔽Mor)
length(unique!(collect(f.dom))) == length(unique!([f(x) for x in f.dom]))
endCatlab version (run in a fresh Julia session — Catlab exports its own compose, id, FinFunction, …):
# Catlab
using Catlab
f = FinFunction([1, 2], 3)
is_monic(f) # true#check @Function.Injective -- ∀ a₁ a₂, f a₁ = f a₂ → a₁ = a₂
example : Function.Injective (fun n : ℕ => n + 1) := Nat.succ_injective
-- in Mathlib's category of types, mono ↔ injective:
#check @CategoryTheory.mono_iff_injectiveimport Data.List (nub)
-- check injectivity on a finite domain
isInjective :: Eq b => [a] -> (a -> b) -> Bool
isInjective dom f = length (nub (map f dom)) == length dom