MathLabs

Nền tảng toán học

Phạm trù và hàm tử

Một phạm trù gói gọn các đối tượng và các mũi tên giữa chúng, chỉ cần tuân theo tính kết hợp và phần tử đơn vị; một hàm tử là một phép dịch giữ cấu trúc giữa hai thế giới như vậy, và hoá ra khi đã cố định "các vật liên hệ với nhau ra sao", chính các đối tượng chỉ được xác định sai khác một đẳng cấu duy nhất.

Trực giácCùng một dáng hình, khác bộ áo

Một người phiên dịch, một đồ thị, một mạng lưới các ga tàu nối bằng các tuyến đường, một tập việc cần làm nối bằng quan hệ "phải xảy ra trước" — tất cả đều có chung một khung xương: một số vật (đối tượng) và một số mũi tên giữa chúng có thể nối tiếp nhau. Một phạm trù làm khung xương đó chính xác; một hàm tử là cách vẽ lại một mạng lưới như vậy bên trong một mạng khác mà vẫn giữ nguyên mọi chuỗi mũi tên.

Sơ đồ mạng tương tác cho thấy đối tượng và các mũi tên có thể ghép giữa chúng.
Đối tượng là nút, cấu xạ là cạnh có hướng; ghép hai cạnh liên tiếp cho ra cạnh thứ ba, đúng là dữ liệu một phạm trù ghi lại.

Đại họcPhạm trù: đối tượng, cấu xạ, phép hợp

Định nghĩa: Phạm trù

Một phạm trù C\mathcal{C} gồm một họ đối tượng A,B,C,…A, B, C, \dots và, với mỗi cặp, một tập cấu xạ HomC(A,B)\mathrm{Hom}_{\mathcal{C}}(A,B), cùng một quy tắc hợp gửi f:A→Bf : A \to B và g:B→Cg : B \to C tới g∘f:A→Cg \circ f : A \to C, và một cấu xạ đơn vị 1A:A→A1_A : A \to A cho mỗi đối tượng.

h∘(g∘f)=(h∘g)∘fh \circ (g \circ f) = (h \circ g) \circ f

Hai tiên đề biến dữ liệu này thành một phạm trù: phép hợp kết hợp (h∘(g∘f)=(h∘g)∘fh \circ (g \circ f) = (h \circ g) \circ f, nên một chuỗi mũi tên có đúng một hợp thức, bất kể đặt dấu ngoặc ở đâu) và các phần tử đơn vị trung hoà (1B∘f=f=f∘1A1_B \circ f = f = f \circ 1_A, nên hợp với 1A1_A hay 1B1_B không bao giờ đổi một cấu xạ).

1B∘f=f=f∘1A1_B \circ f = f = f \circ 1_A
Hàm tử hiệp biến so với phản biến
LoạiTác động trên cấu xạVí dụ điển hình
Hiệp biếnGửi f:A→Bf : A \to B tới F(f):F(A)→F(B)F(f) : F(A) \to F(B), cùng hướngHàm tử danh sách, hàm tử quên
Phản biếnGửi f:A→Bf : A \to B tới F(f):F(B)→F(A)F(f) : F(B) \to F(A), hướng đảoHàm tử không gian đối ngẫu, tiền bó Hom(-,A)

Nâng caoHàm tử và biến đổi tự nhiên

Một hàm tử F:C→DF : \mathcal{C} \to \mathcal{D} gán cho mỗi đối tượng AA của C\mathcal{C} một đối tượng F(A)F(A) của D\mathcal{D}, và cho mỗi cấu xạ ff một cấu xạ F(f)F(f), sao cho phép hợp và đơn vị được giữ nguyên: F(g∘f)=F(g)∘F(f)F(g \circ f) = F(g) \circ F(f) và F(1A)=1F(A)F(1_A) = 1_{F(A)}. Một biến đổi tự nhiên η:F⇒G\eta : F \Rightarrow G giữa hai hàm tử C→D\mathcal{C} \to \mathcal{D} gán cho mỗi đối tượng AA một cấu xạ ηA:F(A)→G(A)\eta_A : F(A) \to G(A) trong D\mathcal{D}, tuân theo hình vuông tự nhiên: với mọi f:A→Bf : A \to B, G(f)∘ηA=ηB∘F(f)G(f) \circ \eta_A = \eta_B \circ F(f).

F(g∘f)=F(g)∘F(f)F(g \circ f) = F(g) \circ F(f)
G(f)∘ηA=ηB∘F(f)G(f) \circ \eta_A = \eta_B \circ F(f)

Nếu T1T_1 và T2T_2 đều là đối tượng cuối của C\mathcal{C} (có đúng một cấu xạ từ mọi đối tượng vào mỗi đối tượng đó), thì T1≅T2T_1 \cong T_2: có một đẳng cấu giữa chúng, và đó là cấu xạ duy nhất T1→T2T_1 \to T_2. Phát biểu đối ngẫu đúng cho đối tượng đầu, và do đó cho tích, bằng cùng lập luận áp lên phạm trù các nón ứng viên.

Vì sao đúng?

Không có sự kiện này, "đối tượng cuối" hay "tích" sẽ không được xác định rõ — các cách xây tích khác nhau (chẳng hạn cặp có thứ tự so với mã hoá khác) cần thay thế được cho nhau, và tính duy nhất sai khác một đẳng cấu duy nhất chính là nghĩa chính xác để nói chúng "giống nhau".

Chứng minh

Vì T2T_2 là đối tượng cuối, mọi đối tượng — riêng T1T_1 — có đúng một cấu xạ vào nó; gọi là u:T1→T2u : T_1 \to T_2. Vì T1T_1 là đối tượng cuối, đối xứng, có đúng một v:T2→T1v : T_2 \to T_1.

Xét hợp v∘u:T1→T1v \circ u : T_1 \to T_1. Vì T1T_1 là đối tượng cuối, có đúng một cấu xạ T1→T1T_1 \to T_1, và 1T11_{T_1} là một cấu xạ như vậy; vì v∘uv \circ u cũng là một cấu xạ T1→T1T_1 \to T_1, tính duy nhất buộc v∘u=1T1v \circ u = 1_{T_1}.

Bằng lập luận đối xứng dùng tính đối tượng cuối của T2T_2, hợp u∘v:T2→T2u \circ v : T_2 \to T_2 phải bằng 1T21_{T_2}: u∘v=1T2u \circ v = 1_{T_2}.

Một cấu xạ có nghịch đảo hai phía theo định nghĩa là một đẳng cấu, nên uu là một đẳng cấu T1≅T2T_1 \cong T_2 với nghịch đảo vv. Nó là cấu xạ duy nhất T1→T2T_1 \to T_2 vì tính đối tượng cuối của T2T_2 đã nói chỉ có đúng một cấu xạ như vậy — uu bị buộc phải như thế từ đầu, và nó chỉ đơn giản là hoá ra khả nghịch.

Nếu F:C→DF : \mathcal{C} \to \mathcal{D} là một hàm tử và f:A→Bf : A \to B là một đẳng cấu trong C\mathcal{C} với nghịch đảo g:B→Ag : B \to A, thì F(f):F(A)→F(B)F(f) : F(A) \to F(B) là một đẳng cấu trong D\mathcal{D}, với nghịch đảo F(g)F(g).

Vì sao đúng?

Đây là điều làm hàm tử trở thành phép dịch đáng tin: một hàm tử không bao giờ vô tình phá một đẳng cấu thành hai đối tượng thật sự khác nhau, nên việc phân loại đối tượng "sai khác một đẳng cấu" là câu hỏi hàm tử tôn trọng.

Chứng minh

Vì ff và gg nghịch đảo lẫn nhau, g∘f=1Ag \circ f = 1_A và f∘g=1Bf \circ g = 1_B.

Áp FF lên phương trình đầu. Hàm tử giữ phép hợp, nên F(g∘f)=F(g)∘F(f)F(g \circ f) = F(g) \circ F(f); hàm tử giữ đơn vị, nên F(1A)=1F(A)F(1_A) = 1_{F(A)}. Kết hợp với g∘f=1Ag \circ f = 1_A cho F(g)∘F(f)=1F(A)F(g) \circ F(f) = 1_{F(A)}.

Áp FF lên phương trình thứ hai tương tự: F(f∘g)=F(f)∘F(g)F(f \circ g) = F(f) \circ F(g) và F(1B)=1F(B)F(1_B) = 1_{F(B)}, nên từ f∘g=1Bf \circ g = 1_B ta được F(f)∘F(g)=1F(B)F(f) \circ F(g) = 1_{F(B)}.

Hai phương trình trên nói chính xác rằng F(g)F(g) là nghịch đảo hai phía của F(f)F(f). Một cấu xạ có nghịch đảo hai phía là một đẳng cấu, nên F(f):F(A)→F(B)F(f) : F(A) \to F(B) là một đẳng cấu với nghịch đảo F(g)F(g), như đã khẳng định.

Đại họcỨng dụng: lập trình hàm và di trú cơ sở dữ liệu

Mọi ngôn ngữ hàm chính thống đều có lớp kiểu `Functor` chính vì các container như danh sách, cây và `Maybe`/`Option` là hàm tử trên phạm trù các kiểu và hàm: `fmap` chính là FF trên cấu xạ, và các luật hàm tử fmap id=id\mathrm{fmap}\,\mathrm{id} = \mathrm{id}, fmap (g∘f)=fmap g∘fmap f\mathrm{fmap}\,(g \circ f) = \mathrm{fmap}\,g \circ \mathrm{fmap}\,f chính là các tiên đề trên. `Monad` tinh chỉnh thêm với hai biến đổi tự nhiên (`return` và `join`) thoả các luật chặt kiểu hình vuông tự nhiên. Ngoài lập trình, di trú dữ liệu theo hàm tử của David Spivak mô hình một lược đồ cơ sở dữ liệu là một phạm trù nhỏ (bảng là đối tượng, khoá ngoại là cấu xạ) và một cuộc di trú lược đồ là một hàm tử giữa hai phạm trù như vậy, nên "chuyển dữ liệu đúng" nghĩa đen là "là một hàm tử" — bảo toàn phép hợp đảm bảo di trú qua một lược đồ trung gian cho cùng kết quả với di trú trực tiếp.

Ví dụ: Kiểm luật hàm tử cho danh sách

Lấy fmap\mathrm{fmap} cho danh sách, định nghĩa bằng áp hàm lên mọi phần tử: fmap f [x1,…,xn]=[f(x1),…,f(xn)]\mathrm{fmap}\,f\,[x_1,\dots,x_n] = [f(x_1),\dots,f(x_n)]. Kiểm cả hai luật hàm tử trên danh sách cụ thể [1,2,3][1,2,3] với f(x)=x+1f(x)=x+1 và g(x)=2xg(x)=2x.

Lời giải

Luật một, fmap id=id\mathrm{fmap}\,\mathrm{id} = \mathrm{id}: áp hàm đơn vị theo từng phần tử cho fmap id [1,2,3]=[id(1),id(2),id(3)]=[1,2,3]\mathrm{fmap}\,\mathrm{id}\,[1,2,3] = [\mathrm{id}(1),\mathrm{id}(2),\mathrm{id}(3)] = [1,2,3], đúng là id [1,2,3]\mathrm{id}\,[1,2,3]. Điều này đúng cho mọi danh sách, không chỉ danh sách này, vì áp "không làm gì" lên mỗi phần tử thì không làm gì cho danh sách.

Luật hai, fmap (g∘f)=fmap g∘fmap f\mathrm{fmap}\,(g \circ f) = \mathrm{fmap}\,g \circ \mathrm{fmap}\,f: tính vế trái trước. (g∘f)(x)=2(x+1)(g \circ f)(x) = 2(x+1), nên fmap (g∘f) [1,2,3]=[2⋅2,2⋅3,2⋅4]=[4,6,8]\mathrm{fmap}\,(g\circ f)\,[1,2,3] = [2\cdot2, 2\cdot3, 2\cdot4] = [4,6,8].

Giờ vế phải: fmap f [1,2,3]=[2,3,4]\mathrm{fmap}\,f\,[1,2,3] = [2,3,4], rồi fmap g [2,3,4]=[4,6,8]\mathrm{fmap}\,g\,[2,3,4] = [4,6,8].

Cả hai vế đều bằng [4,6,8][4,6,8], xác nhận luật trên ví dụ này; chứng minh tổng quát là cùng tính toán với xix_i thay cho 1,2,31,2,3, vì fmap\mathrm{fmap} không bao giờ đổi thứ tự hay bỏ phần tử.

Ví dụ: Di trú lược đồ như một hàm tử

Một lược đồ S1\mathcal{S}_1 có bảng `Person` và `City`, với khoá ngoại `livesIn : Person -> City`. Lược đồ mới S2\mathcal{S}_2 tách `Person` thành `Person` và `Contact`, với `hasContact : Person -> Contact` và `livesIn2 : Contact -> City`. Mô tả cuộc di trú như một hàm tử và giải thích bảo toàn phép hợp mang lại gì.

Lời giải

Mô hình mỗi lược đồ như một phạm trù: đối tượng là bảng, cấu xạ là khoá ngoại hợp tự do (nên S1\mathcal{S}_1 có hợp livesIn:Person→City\texttt{livesIn} : \texttt{Person} \to \texttt{City} như một phần sinh). Cuộc di trú F:S1→S2F : \mathcal{S}_1 \to \mathcal{S}_2 gửi Person↦Person\texttt{Person} \mapsto \texttt{Person}, City↦City\texttt{City} \mapsto \texttt{City}, và cấu xạ livesIn\texttt{livesIn} tới cấu xạ hợp livesIn2∘hasContact:Person→City\texttt{livesIn2} \circ \texttt{hasContact} : \texttt{Person} \to \texttt{City} trong S2\mathcal{S}_2.

Để FF là hàm tử, nó phải gửi đơn vị tới đơn vị (tầm thường ở đây) và tôn trọng phép hợp: mọi chuỗi khoá ngoại xây trong S1\mathcal{S}_1 từ livesIn\texttt{livesIn} phải ánh xạ tới cùng chuỗi xây từ F(livesIn)=livesIn2∘hasContactF(\texttt{livesIn}) = \texttt{livesIn2} \circ \texttt{hasContact}, cùng thứ tự, không bỏ hay đổi bước.

Đây chính xác là điều định lý "hàm tử giữ phép hợp" mang lại cho kỹ sư: nếu một truy vấn ghép Person\texttt{Person} với City\texttt{City} qua livesIn\texttt{livesIn} ở lược đồ cũ, dịch mỗi bảng và ánh xạ livesIn\texttt{livesIn} tới đường hai bước rồi thực thi ghép cho ra cùng đáp án với dịch cả truy vấn như một khối — dữ liệu di trú theo từng bảng được đảm bảo nhất quán với dữ liệu di trú theo từng truy vấn, chính xác vì F(g∘f)=F(g)∘F(f)F(g \circ f) = F(g) \circ F(f).

Cặp phương trình nào là hai tiên đề phạm trù?

Một hàm tử phản biến gửi f:A→Bf : A \to B tới một cấu xạ đi hướng nào?

Trong di trú dữ liệu theo hàm tử của Spivak, di trú lược đồ tương ứng với gì?

Nếu u:T1→T2u : T_1 \to T_2 là cấu xạ duy nhất giữa hai đối tượng cuối, định lý nói gì về uu?

Tài liệu tham khảo

  1. Saunders Mac Lane (1998). Categories for the Working Mathematician
  2. Emily Riehl (2016). Category Theory in Context
  3. David I. Spivak (2012). Functorial Data Migration · arXiv:1009.1166