Timings for Adjunction.v
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.OLD/ocaml-OLD/.opam-switch/build/coq-category-theory.dev//./Construction/Comma/Adjunction.v.timing
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.NEW/ocaml-NEW/.opam-switch/build/coq-category-theory.dev//./Construction/Comma/Adjunction.v.timing
Require Import Category.Lib.
Require Import Category.Theory.Category.
Require Import Category.Theory.Isomorphism.
Require Import Category.Theory.Functor.
Require Import Category.Theory.Natural.Transformation.
Require Import Category.Theory.Adjunction.
Require Import Category.Adjunction.Natural.Transformation.
Require Import Category.Adjunction.Natural.Transformation.Universal.
Require Import Category.Construction.Comma.
Require Import Category.Construction.Product.
Require Import Category.Instance.Cat.
Require Import Category.Instance.Fun.
Require Import Category.Instance.Sets.
Generalizable All Variables.
Definition whisker_equiv
{C D E : Category}
(φ : C ⟶ D)
(ψ : D ⟶ C)
(πC : C ⟶ E)
(πD : D ⟶ E)
(η : Id ⟹ ψ ◯ φ)
(μ : Id ⟹ φ ◯ ψ)
(κ : πC ⟹ πD ◯ φ)
(θ : πD ⟹ πC ◯ ψ) :=
to (nat_α _ _ _) ∙ πC ⊳ η ∙ from (nat_λ _) ≈ (θ ⊲ φ) ∙ κ ∧
to (nat_α _ _ _) ∙ πD ⊳ μ ∙ from (nat_λ _) ≈ (κ ⊲ ψ) ∙ θ.
(* Wikipedia: "Lawvere showed that the functors F : C → D and G : D → C are
adjoint if and only if the comma categories (F ↓ Id[D]) and (Id[C] ↓ G) are
isomorphic, and equivalent elements in the comma category can be projected
onto the same element of C × D. This allows adjunctions to be described
without involving sets, and was in fact the original motivation for
introducing comma categories."
From ncatlab: "To give an adjunction i ⊣ r it suffices to give, for each k
: x → pe in B ↓ p, an object rk in E such that prk = x and an arrow irk =
1x → k in B ↓ p that is universal from i to k."
Lawvere's own statement of the theorem, from his thesis (page 40):
"For each functor f : A ⟶ B, there exists a functor g : B ⟶ A such that g
is adjoint to f iff for every object B ∈ |B| there exists an object A ∈ |A|
and a map φ : B ~> A in B such that for every object A′ ∈ |A| and every
map x : B ~> A′ in B, there exists a unique map y : A ~> A′ in A such that
x = φ(yf) in B." *)
Definition πD := comma_proj1.
Definition πC := comma_proj2.
#[local] Notation "⟨πD,πC⟩" := comma_proj (at level 0).
Record lawvere_equiv := {
lawvere_iso : F ↓ Id[C] ≅[Cat] Id[D] ↓ G;
φ := to lawvere_iso;
ψ := from lawvere_iso;
η x := from (`1 (iso_from_to lawvere_iso) x);
μ x := from (`1 (iso_to_from lawvere_iso) x);
projF : ⟨πD,πC⟩ ≈ ⟨πD,πC⟩ ◯ φ;
projG : ⟨πD,πC⟩ ≈ ⟨πD,πC⟩ ◯ ψ;
κ := `1 projF;
θ := `1 projG;
σ : @whisker_equiv
(F ↓ Id[C]) (Id[D] ↓ G) (D ∏ C)
(to lawvere_iso) (from lawvere_iso)
comma_proj comma_proj
(from (equiv_iso (iso_from_to lawvere_iso)))
(from (equiv_iso (iso_to_from lawvere_iso)))
(to (equiv_iso projF))
(to (equiv_iso projG));
lawvere_to {a b} (f : F a ~> b) : a ~> G b :=
let o := ((a, b); f) in
fmap[G] (snd (from (κ o))) ∘ `2 (φ o) ∘ fst (to (κ o));
lawvere_from {a b} (g : a ~> G b) : F a ~> b :=
let o := ((a, b); g) in
snd (from (θ o)) ∘ `2 (ψ o) ∘ fmap[F] (fst (to (θ o)));
φ' {a b} (f : F a ~> b) := lawvere_to f;
ψ' {a b} (g : a ~> G b) := lawvere_from g
}.
Context `(E : lawvere_equiv).
Lemma η_θ_κ : ∀ x, `1 (η E x) ≈ θ E (φ E x) ∘ κ E x.
specialize (X x); simpl in X.
unfold equiv_iso, η, κ, θ, φ in *.
destruct (iso_from_to (lawvere_iso E)), (projG E), (projF E).
Lemma μ_κ_θ : ∀ x, `1 (μ E x) ≈ κ E (ψ E x) ∘ θ E x.
specialize (X x); simpl in X.
unfold equiv_iso, μ, κ, θ, ψ in *.
destruct (iso_to_from (lawvere_iso E)), (projG E), (projF E).
Theorem ψ_φ_equiv :
∀ x, snd (from (κ E x))
∘ snd (from (θ E (φ E x)))
∘ `2 (ψ E (φ E x))
∘ fmap[F] (fst (to (θ E (φ E x))))
∘ fmap[F] (fst (to (κ E x)))
≈ `2 x.
intros [[a b] f]; simpl in f |- *.
rewrite (snd_comp _ _ _ (κ E ((a, b); f))⁻¹ (θ E (φ E _))⁻¹).
rewrite (fst_comp _ _ _ (θ E (φ E _)) (κ E ((a, b); f))).
rewrite (`2 (η E ((a, b); f))).
rewrite (snd_comp _ _ _
((κ E _)⁻¹ ∘ (θ E (φ E _))⁻¹)
(θ E (φ E _) ∘ κ E ((a, b); f))).
rewrite (comp_assoc (θ E (φ E ((a, b); f)))⁻¹ _).
rewrite iso_from_to, id_left.
now rewrite iso_from_to; cat.
Theorem φ_ψ_equiv :
∀ x, fmap[G] (snd (from (θ E x)))
∘ fmap[G] (snd (from (κ E (ψ E x))))
∘ `2 (φ E (ψ E x))
∘ fst (to (κ E (ψ E x)))
∘ fst (to (θ E x))
≈ `2 x.
intros [[a b] f]; simpl in f |- *.
rewrite (snd_comp _ _ _ (θ E ((a, b); f))⁻¹ (κ E (ψ E _))⁻¹).
rewrite (fst_comp _ _ _ (κ E (ψ E _)) (θ E ((a, b); f))).
rewrite (`2 (μ E ((a, b); f))).
rewrite (snd_comp _ _ _
((θ E _)⁻¹ ∘ (κ E (ψ E _))⁻¹)
(κ E (ψ E _) ∘ θ E ((a, b); f))).
rewrite (comp_assoc (κ E (ψ E ((a, b); f)))⁻¹ _).
rewrite iso_from_to, id_left.
now rewrite iso_from_to; cat.
Program Instance to_lawvere_iso_Proper :
Proper (Isomorphism ==> Isomorphism) (φ E).
exact (fmap[φ E] (to X)).
exact (fmap[φ E] (from X)).
exact (iso_to_from (@fobj_iso _ _ (φ E) _ _ X)).
exact (iso_from_to (@fobj_iso _ _ (φ E) _ _ X)).
Program Instance from_lawvere_iso_Proper :
Proper (Isomorphism ==> Isomorphism) (ψ E).
exact (fmap[ψ E] (to X)).
exact (fmap[ψ E] (from X)).
exact (iso_to_from (@fobj_iso _ _ (ψ E) _ _ X)).
exact (iso_from_to (@fobj_iso _ _ (ψ E) _ _ X)).
Program Instance lawvere_to_Proper {a b} :
Proper (equiv ==> equiv) (@φ' E a b).
given (ff : ((a, b); x) ~{ F ↓ Id[C] }~> ((a, b); y)).
now refine ((id, id); _); abstract cat.
spose (`2 (projF E) ((a, b); x) ((a, b); y) ff) as H0.
rewrite (comp_assoc (fst _) _).
spose (iso_to_from (κ E ((a, b); y))) as H0.
rewrite <- (id_left (snd _)).
rewrite (comp_assoc (fmap (snd (to (κ E ((a, b); x)))))).
spose (iso_to_from (κ E ((a, b); x))) as H0.
rewrite fmap_id, id_left.
remember (fmap[to (lawvere_iso E)] _) as o.
Program Instance lawvere_from_Proper {a b} :
Proper (equiv ==> equiv) (@ψ' E a b).
given (ff : ((a, b); x) ~{ Id[D] ↓ G }~> ((a, b); y)).
now refine ((id, id); _); abstract cat.
spose (`2 (projG E) ((a, b); x) ((a, b); y) ff) as H0.
rewrite (comp_assoc (snd (to (θ E ((a, b); x)))) (snd _)).
spose (iso_to_from (θ E ((a, b); x))) as H0.
rewrite <- (id_right (fst _)).
spose (iso_to_from (θ E ((a, b); y))) as H0.
rewrite fmap_id, id_right.
remember (fmap[from (lawvere_iso E)] _) as o.
Ltac pair_comp :=
match goal with
| [ |- context[@fst _ _ ?F ∘ @fst _ _ ?G] ] =>
rewrite (@fst_comp _ _ _ _ _ F G)
| [ |- context[@snd _ _ ?F ∘ @snd _ _ ?G] ] =>
rewrite (@snd_comp _ _ _ _ _ F G)
end.
Lemma lawvere_iso_to {a b} (f : F a ~> b) :
φ E ((a, b); f) ≅ ((a, b); φ' E f).
exists (from (κ E ((a, b); f))).
abstract
(unfold φ', lawvere_to;
rewrite <- !comp_assoc;
pair_comp;
rewrite iso_to_from;
simpl fst;
now rewrite id_right).
exists (to (κ E ((a, b); f))).
abstract
(unfold φ', lawvere_to;
rewrite !comp_assoc;
rewrite <- !fmap_comp;
pair_comp;
rewrite iso_to_from;
simpl snd;
now rewrite fmap_id, id_left).
abstract
(simpl;
split; pair_comp;
now rewrite iso_from_to).
abstract
(simpl;
split; pair_comp;
now rewrite iso_to_from).
Lemma lawvere_iso_from {a b} (g : a ~> G b) :
ψ E ((a, b); g) ≅ ((a, b); ψ' E g).
exists (from (θ E ((a, b); g))).
abstract
(unfold ψ', lawvere_from;
rewrite <- !comp_assoc;
rewrite <- !fmap_comp;
pair_comp;
rewrite iso_to_from;
simpl fst;
now rewrite fmap_id, id_right).
exists (to (θ E ((a, b); g))).
abstract
(unfold ψ', lawvere_from;
rewrite !comp_assoc;
pair_comp;
rewrite iso_to_from;
simpl snd;
now rewrite id_left).
abstract
(simpl;
split; pair_comp;
now rewrite iso_from_to).
abstract
(simpl;
split; pair_comp;
now rewrite iso_to_from).
Lemma lawvere_iso_from_to {a b} (f : F a ~> b) :
ψ E (φ E ((a, b); f)) ≅ ((a, b); ψ' E (φ' E f)).
refine (iso_compose (lawvere_iso_from (φ' E f)) _).
now apply lawvere_iso_to.
Definition lawvere_iso_to_from {a b} (g : a ~> G b) :
φ E (ψ E ((a, b); g)) ≅ ((a, b); φ' E (ψ' E g)).
refine (iso_compose (lawvere_iso_to (ψ' E g)) _).
now apply lawvere_iso_from.
Definition lawvere_to_from_iso {a b} (g : a ~> G b) :
((a, b); φ' E (ψ' E g)) ≅[Id[D] ↓ G] ((a, b); g) :=
iso_compose (`1 (iso_to_from (lawvere_iso E)) ((a, b); g))
(iso_sym (@lawvere_iso_to_from _ _ g)).
Definition lawvere_from_to_iso {a b} (f : F a ~> b) :
((a, b); ψ' E (φ' E f)) ≅[F ↓ Id[C]] ((a, b); f) :=
iso_compose (`1 (iso_from_to (lawvere_iso E)) ((a, b); f))
(iso_sym (@lawvere_iso_from_to _ _ f)).
Lemma lawvere_to_functorial {a b} (f : F a ~{C}~> b)
{a' b'} (i : a' ~> a) (j : b ~> b') :
φ' E (j ∘ f ∘ fmap[F] i) ≈ fmap[G] j ∘ φ' E f ∘ i.
(* φ'(j ∘ f ∘ Fi) = φ'(j ∘ f) ∘ i *)
given (Fi : ((a', b'); j ∘ f ∘ fmap[F] i) ~{ F ↓ Id[C] }~> ((a, b'); j ∘ f)).
now refine ((i, id); _); abstract cat.
spose (`2 (to (lawvere_iso_to (j ∘ f))
∘ fmap[φ E] Fi
∘ from (lawvere_iso_to (j ∘ f ∘ fmap[F] i)))) as H.
spose (`2 (projF E) ((a', b'); j ∘ f ∘ fmap[F] i) ((a, b'); j ∘ f) Fi) as H1.
rewrite <- H1 in H; clear H1.
rewrite <- H2 in H; clear H2.
rewrite fmap_id, id_left in H.
(* = G(j ∘ f) ∘ φ'(Fi) *)
given (Fi : ((a', F a); fmap[F] i) ~{ F ↓ Id[C] }~> ((a, b'); j ∘ f)).
now refine ((i, j ∘ f); _); abstract cat.
spose (`2 (to (lawvere_iso_to (j ∘ f))
∘ fmap[φ E] Fi
∘ from (lawvere_iso_to (fmap[F] i)))) as H.
spose (`2 (projF E) ((a', F a); fmap[F] i) ((a, b'); j ∘ f) Fi) as H1.
rewrite <- H1 in H; clear H1.
rewrite <- H2 in H; clear H2.
given (Fi : ((a', F a); fmap[F] i) ~{ F ↓ Id[C] }~> ((a, b); f)).
now refine ((i, f); _); abstract cat.
spose (`2 (to (lawvere_iso_to f)
∘ fmap[φ E] Fi
∘ from (lawvere_iso_to (fmap[F] i)))) as H.
spose (`2 (projF E) ((a', F a); fmap[F] i) ((a, b); f) Fi) as H1.
rewrite <- H1 in H; clear H1.
rewrite <- H2 in H; clear H2.
Lemma lawvere_from_functorial {a b} (g : a ~{D}~> G b)
{a' b'} (i : a' ~> a) (j : b ~> b') :
j ∘ ψ' E g ∘ fmap[F] i ≈ ψ' E (fmap[G] j ∘ g ∘ i).
(* ψ'(Gj ∘ g ∘ i) = j ∘ ψ'(g ∘ i) *)
given (Gj : ((a', b); g ∘ i) ~{ Id[D] ↓ G }~> ((a', b'); fmap[G] j ∘ g ∘ i)).
now refine ((id, j); _); simpl; abstract cat.
spose (`2 (to (lawvere_iso_from (fmap[G] j ∘ g ∘ i))
∘ fmap[ψ E] Gj
∘ from (lawvere_iso_from (g ∘ i)))) as H.
spose (`2 (projG E) ((a', b); g ∘ i) ((a', b'); fmap[G] j ∘ g ∘ i) Gj) as H1.
rewrite <- H1 in H; clear H1.
rewrite <- H2 in H; clear H2.
rewrite fmap_id, id_right in H.
(* = ψ'(Gj) ∘ F(g ∘ i) *)
given (Gj : ((a', b); g ∘ i) ~{ Id[D] ↓ G }~> ((G b, b'); fmap[G] j)).
now refine ((g ∘ i, j); _); simpl; abstract cat.
spose (`2 (to (lawvere_iso_from (fmap[G] j))
∘ fmap[ψ E] Gj
∘ from (lawvere_iso_from (g ∘ i)))) as H.
spose (`2 (projG E) ((a', b); g ∘ i) ((G b, b'); fmap[G] j) Gj) as H1.
rewrite <- H1 in H; clear H1.
rewrite <- H2 in H; clear H2.
given (Gj : ((a, b); g) ~{ Id[D] ↓ G }~> ((G b, b'); fmap[G] j)).
now refine ((g, j); _); abstract cat.
spose (`2 (to (lawvere_iso_from (fmap[G] j))
∘ fmap[ψ E] Gj
∘ from (lawvere_iso_from (g)))) as H.
spose (`2 (projG E) ((a, b); g) ((G b, b'); fmap[G] j) Gj) as H1.
rewrite <- H1 in H; clear H1.
rewrite <- H2 in H; clear H2.
Lemma surjective_tripleF (p : obj[F ↓ Id[C]]) :
((fst `1 p, snd `1 p); `2 p) = p.
destruct p; simpl; simpl_eq.
Lemma surjective_tripleG (p : obj[Id[D] ↓ G]) :
((fst `1 p, snd `1 p); `2 p) = p.
Lemma expand_φ_ψ {a b} (g : a ~> G b) :
φ E (ψ E ((a, b); g))
≈
φ E
((fst `1 ((lawvere_iso E)⁻¹ ((a, b); g)),
snd `1 ((lawvere_iso E)⁻¹ ((a, b); g)));
`2 ((lawvere_iso E)⁻¹ ((a, b); g))).
now rewrite surjective_tripleF.
Lemma expand_ψ_φ {a b} (f : F a ~> b) :
ψ E (φ E ((a, b); f))
≈
ψ E
((fst `1 (φ E ((a, b); f)),
snd `1 (φ E ((a, b); f)));
`2 (φ E ((a, b); f))).
now rewrite surjective_tripleG.
(** Given that:
π₁((A,B);f) = (A,B)
= π₁(φ((A,B);f)) = π₁(φ((A,B);f)) [projF, projG]
φ((A,B);f) ≅ ((A,B);φ'(f)) [lawvere_iso_to]
ψ((A,B);f) ≅ ((A,B);ψ'(f)) [lawvere_iso_from]
φ(ψ(f)) ≈ f and ψ(φ(f)) ≈ f [lawvere_iso]
it follows that:
φ'(ψ'(f)) ≈ f and ψ'(φ'(f)) ≈ f *)
Lemma lawvere_to_from {a b} (g : a ~> G b) : φ' E (ψ' E g) ≈ g.
pose proof (@lawvere_to_functorial
_ _ (`2 (fobj[(lawvere_iso E)⁻¹] ((a, b); g)))
a b
(fst (to (`1 (projG E) ((a, b); g))))
(snd (`1 (projG E) ((a, b); g))⁻¹)) as X.
spose (φ_ψ_equiv ((a, b); g)) as X1.
apply compose_respects; [|reflexivity].
apply compose_respects; [reflexivity|].
spose (surjective_tripleF (ψ E ((a, b); g))) as X2.
solve [ reflexivity (* works in >=8.12 *)
| simpl; (* needed for <8.11 *)
unfold lawvere_to, θ, κ, ψ;
rewrite !comp_assoc;
reflexivity
].
Lemma lawvere_from_to {a b} (f : F a ~> b) : ψ' E (φ' E f) ≈ f.
pose proof (@lawvere_from_functorial
_ _ (`2 (fobj[to (lawvere_iso E)] ((a, b); f)))
a b
(fst (to (`1 (projF E) ((a, b); f))))
(snd (`1 (projF E) ((a, b); f))⁻¹)) as X.
spose (ψ_φ_equiv ((a, b); f)) as X1.
apply compose_respects; [|reflexivity].
apply compose_respects; [reflexivity|].
spose (surjective_tripleG (φ E ((a, b); f))) as X2.
solve [ reflexivity (* works in >=8.12 *)
| simpl; (* needed for <8.11 *)
unfold lawvere_to, θ, κ, ψ;
rewrite !comp_assoc;
reflexivity
].
Program Instance lawvere_morph_iso {a b} : F a ~> b ≊ a ~> G b := {
to := {| morphism := φ' E; proper_morphism := lawvere_to_Proper |};
from := {| morphism := ψ' E; proper_morphism := lawvere_from_Proper |};
iso_to_from := lawvere_to_from;
iso_from_to := lawvere_from_to
}.
Corollary lawvere_to_morph_iso_functorial {a b} (f : F a ~{C}~> b)
{a' b'} (i : a' ~> a) (j : b ~> b') :
to lawvere_morph_iso (j ∘ f ∘ fmap[F] i)
≈ fmap[G] j ∘ to lawvere_morph_iso f ∘ i.
now apply lawvere_to_functorial.
Corollary lawvere_from_morph_iso_functorial {a b} (g : a ~{D}~> G b)
{a' b'} (i : a' ~> a) (j : b ~> b') :
j ∘ from lawvere_morph_iso g ∘ fmap[F] i
≈ from lawvere_morph_iso (fmap[G] j ∘ g ∘ i).
now apply lawvere_from_functorial.
Program Definition Left_Functor : D ⟶ (F ↓ Id[C]) := {|
fobj := fun x : D => ((x, F x); id[F x]);
fmap := fun _ _ f => ((f, fmap[F] f); _)
|}.
proper; rewrites; reflexivity.
split; [ reflexivity | apply fmap_comp ].
Program Definition Right_Functor : C ⟶ (Id[D] ↓ G) := {|
fobj := fun x : C => ((G x, x); id[G x]);
fmap := fun _ _ f => ((fmap[G] f, f); _)
|}.
proper; rewrites; reflexivity.
split; [ apply fmap_comp | reflexivity ].
Definition lawvere_eqv_unit {a} : a ~{ D }~> G (F a) :=
to lawvere_morph_iso (`2 (Left_Functor a)).
Definition lawvere_eqv_counit {a} : F (G a) ~{ C }~> a :=
from lawvere_morph_iso (`2 (Right_Functor a)).
Lemma lawvere_eqv_counit_fmap_unit {a} :
lawvere_eqv_counit ∘ fmap[F] lawvere_eqv_unit ≈ id[F a].
unfold lawvere_eqv_counit, lawvere_eqv_unit.
rewrite lawvere_from_morph_iso_functorial.
rewrite fmap_id, !id_left.
now sapply (iso_from_to (@lawvere_morph_iso a (F a))).
Lemma lawvere_eqv_fmap_counit_unit {a} :
fmap[G] lawvere_eqv_counit ∘ lawvere_eqv_unit ≈ id[G a].
unfold lawvere_eqv_counit, lawvere_eqv_unit.
rewrite <- (id_right (to lawvere_morph_iso _)).
rewrite <- lawvere_to_morph_iso_functorial.
rewrite fmap_id, !id_right.
now sapply (iso_to_from (@lawvere_morph_iso (G a) a)).
Lemma Left_Functoriality
x y (f : comma_proj (Left_Functor x) ~> comma_proj (Left_Functor y)) :
fmap[G] (fmap[F] (fst f))
∘ (fmap[G] (snd (κ E (Left_Functor x))⁻¹)
∘ `2 (φ E (Left_Functor x))
∘ fst (to (κ E (Left_Functor x))))
≈ fmap[G] (snd (κ E (Left_Functor y))⁻¹)
∘ `2 (φ E (Left_Functor y))
∘ fst (to (κ E (Left_Functor y)))
∘ fst f.
given (ff : (Left_Functor x) ~{ F ↓ Id[C] }~> (Left_Functor y)).
exists (fst f, fmap[F] (fst f)).
abstract (simpl; rewrite id_left, id_right; reflexivity).
destruct (`2 (projF E) (Left_Functor x) (Left_Functor y) ff).
rewrite (comp_assoc (fmap[G] (snd (to (κ E (Left_Functor x)))))).
rewrite (snd (iso_to_from (κ E (Left_Functor x)))).
spose (`2 (fmap[φ E] ff)) as X.
rewrite (fst (iso_to_from (κ E (Left_Functor y)))).
Lemma Right_Functoriality
x y (f : comma_proj (Right_Functor x) ~> comma_proj (Right_Functor y)) :
snd f ∘ (snd (θ E (Right_Functor x))⁻¹
∘ `2 ((lawvere_iso E)⁻¹ (Right_Functor x))
∘ fmap[F] (fst (to (θ E (Right_Functor x)))))
≈ snd (θ E (Right_Functor y))⁻¹
∘ `2 ((lawvere_iso E)⁻¹ (Right_Functor y))
∘ fmap[F] (fst (to (θ E (Right_Functor y))))
∘ fmap[F] (fmap[G] (snd f)).
given (ff : (Right_Functor x) ~{ Id[D] ↓ G }~> (Right_Functor y)).
exists (fmap[G] (snd f), snd f).
abstract (simpl; rewrite id_left, id_right; reflexivity).
destruct (`2 (projG E) (Right_Functor x) (Right_Functor y) ff).
rewrite (fst (iso_to_from (θ E (Right_Functor y)))).
rewrite (comp_assoc (snd (to (θ E (Right_Functor x))))).
rewrite (snd (iso_to_from (θ E (Right_Functor x)))).
apply (`2 (fmap[ψ E] ff)).
Program Definition lawvere_eqv_unit_transform : Id ⟹ G ◯ F := {|
transform := @lawvere_eqv_unit;
naturality := fun x y f =>
Left_Functoriality x y (f, fmap[F] f);
naturality_sym := fun x y f =>
symmetry (Left_Functoriality x y (f, fmap[F] f))
|}.
Program Definition lawvere_eqv_counit_transform : F ◯ G ⟹ Id := {|
transform := @lawvere_eqv_counit;
naturality := fun x y f =>
Right_Functoriality x y (fmap[G] f, f);
naturality_sym := fun x y f =>
symmetry (Right_Functoriality x y (fmap[G] f, f))
|}.
Program Definition Comma_Functor_F_Id_Id_G (H : F ⊣ G) :
(F ↓ Id[C]) ⟶ (Id[D] ↓ G) := {|
fobj := fun x => (``x; to adj (`2 x));
fmap := fun _ _ f => (``f; _)
|}.
rewrite <- to_adj_nat_r;
rewrite <- X;
rewrite <- to_adj_nat_l;
reflexivity.
Program Definition Comma_Functor_Id_G_F_Id (H : F ⊣ G) :
(Id[D] ↓ G) ⟶ (F ↓ Id[C]) := {|
fobj := fun x => (``x; from adj (`2 x));
fmap := fun _ _ f => (``f; _)
|}.
rewrite <- from_adj_nat_r;
rewrite <- X;
rewrite <- from_adj_nat_l;
reflexivity.
Program Instance Comma_F_Id_Id_G_Iso (H : F ⊣ G) :
(F ↓ Id[C]) ≅[Cat] (Id[D] ↓ G) := {
to := Comma_Functor_F_Id_Id_G H;
from := Comma_Functor_Id_G_F_Id H
}.
abstract
(destruct x as [[x y] f]; cat;
srewrite (iso_to_from (@adj _ _ _ _ H x y)); reflexivity).
abstract
(destruct x as [[x y] f]; cat;
srewrite (iso_to_from (@adj _ _ _ _ H x y)); reflexivity).
abstract (clear; simpl; split; cat).
abstract (clear; simpl; split; cat).
abstract (clear; simpl; split; cat).
abstract
(destruct x as [[x y] f]; cat;
srewrite (iso_from_to (@adj _ _ _ _ H x y)); reflexivity).
abstract
(destruct x as [[x y] f]; cat;
srewrite (iso_from_to (@adj _ _ _ _ H x y)); reflexivity).
abstract (clear; simpl; split; cat).
abstract (clear; simpl; split; cat).
abstract (clear; simpl; split; cat).
Theorem Adjunction_Comma `{F : D ⟶ C} `{G : C ⟶ D} :
F ⊣ G ↔ @lawvere_equiv _ _ F G.
unshelve refine {| lawvere_iso := Comma_F_Id_Id_G_Iso H |}.
unshelve eexists; intros; split;
destruct f; simpl; cat.
unshelve eexists; intros; split;
destruct f; simpl; cat.
split; intros; simpl; intros; cat.
apply Adjunction_from_Transform.
exact (Build_Adjunction_Transform
(@lawvere_eqv_unit_transform _ _ _ _ H)
(@lawvere_eqv_counit_transform _ _ _ _ H)
(@lawvere_eqv_counit_fmap_unit _ _ _ _ H)
(@lawvere_eqv_fmap_counit_unit _ _ _ _ H)).