123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116{-# OPTIONS --without-K --safe #-} open import Categories.Category module Categories.Morphism.IsoEquiv {o β e} (π : Category o β e) where open import Levelopen import Function using (flip; _on_)open import Relation.Binary hiding (_β_)import Relation.Binary.Construct.On as On open import Categories.Morphism π open Category π private variable A B C : Obj -- Two lemmas to set things up: if they exist, inverses are unique. to-unique : β {fβ fβ : A β B} {gβ gβ} β Iso fβ gβ β Iso fβ gβ β fβ β fβ β gβ β gβto-unique {_} {_} {fβ} {fβ} {gβ} {gβ} isoβ isoβ hyp = begin gβ βΛβ¨ identityΛ‘ β© id β gβ βΛβ¨ β-resp-βΛ‘ Isoβ.isoΛ‘ β© (gβ β fβ) β gβ βΛβ¨ β-resp-βΛ‘ (β-resp-βΚ³ hyp) β© (gβ β fβ) β gβ ββ¨ assoc β© gβ β (fβ β gβ) ββ¨ β-resp-βΚ³ Isoβ.isoΚ³ β© gβ β id ββ¨ identityΚ³ β© gβ β where open HomReasoning module Isoβ = Iso isoβ module Isoβ = Iso isoβ from-unique : β {fβ fβ : A β B} {gβ gβ} β Iso fβ gβ β Iso fβ gβ β gβ β gβ β fβ β fβfrom-unique isoβ isoβ hyp = to-unique isoββ»ΒΉ isoββ»ΒΉ hyp where isoββ»ΒΉ = record { isoΛ‘ = Iso.isoΚ³ isoβ ; isoΚ³ = Iso.isoΛ‘ isoβ } isoββ»ΒΉ = record { isoΛ‘ = Iso.isoΚ³ isoβ ; isoΚ³ = Iso.isoΛ‘ isoβ } -- Equality of isomorphisms is just equality of the underlying morphism(s).---- Only one equation needs to be given; the equation in the other-- direction holds automatically (by the above lemmas).---- The reason for wrapping the underlying equality in a record at all-- is that this helps unification. Concretely, it allows Agda to-- infer the isos |i| and |j| being related in function applications-- where only the equation |i β j| is passed as an explicit argument. infix 4 _β_record _β_ (i j : A β B) : Set e where constructor β_β open _β _ field from-β : from i β from j to-β : to i β to j to-β = to-unique (iso i) (iso j) from-β open _β_ module _ {A B : Obj} where open Equiv β-refl : Reflexive (_β_ {A} {B}) β-refl = β refl β β-sym : Symmetric (_β_ {A} {B}) β-sym = Ξ» where β eq β β β sym eq β β-trans : Transitive (_β_ {A} {B}) β-trans = Ξ» where β eqβ β β eqβ β β β trans eqβ eqβ β β-isEquivalence : IsEquivalence (_β_ {A} {B}) β-isEquivalence = record { refl = β-refl ; sym = β-sym ; trans = β-trans } β-setoid : β {A B : Obj} β Setoid _ _β-setoid {A} {B} = record { Carrier = A β B ; _β_ = _β_ ; isEquivalence = β-isEquivalence } ---------------------------------------------------------------------- -- An alternative, more direct notion of equality on isomorphisms that-- involves no wrapping/unwrapping. infix 4 _ββ²__ββ²_ : Rel (A β B) e_ββ²_ = _β_ on _β _.from ββ²-isEquivalence : IsEquivalence (_ββ²_ {A} {B})ββ²-isEquivalence = On.isEquivalence _β _.from equiv ββ²-setoid : β {A B : Obj} β Setoid _ _ββ²-setoid {A} {B} = record { Carrier = A β B ; _β_ = _ββ²_ ; isEquivalence = ββ²-isEquivalence } -- The two notions of equality are equivalent ββββ² : β {i j : A β B} β i β j β i ββ² jββββ² eq = from-β eq ββ²ββ : β {i j : A β B} β i ββ² j β i β jββ²ββ {_} {_} {i} {j} eq = β eq β