8. Families of maps¶
This is a literate rzk
file:
Fiber of total map¶
We now calculate the fiber of the map on total spaces associated to a family of maps.
#def total-map
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
: ( total-type A B) → (total-type A C)
:= \ (a , b) → (a , f a b)
#def fib-total-map-fib-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( ( a , c) : total-type A C)
: fib (B a) (C a) (f a) (c)
→ fib (total-type A B) (total-type A C) (total-map A B C f) (a , c)
:= \ (b , p) → ((a , b) , eq-eq-fiber-Σ A C a (f a b) c p)
#def fib-fiberwise-fib-total-map
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
: ( ( a , c) : total-type A C)
→ fib (total-type A B) (total-type A C) (total-map A B C f) (a , c)
→ fib (B a) (C a) (f a) (c)
:=
ind-fib (total-type A B) (total-type A C) (total-map A B C f)
( \ (a' , c') _ → fib (B a') (C a') (f a') c')
( \ (_ , b') → (b' , refl))
#def has-retraction-fib-total-map-fib-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( ( a , c) : total-type A C)
: has-retraction
( fib (B a) (C a) (f a) (c))
( fib (total-type A B) (total-type A C) (total-map A B C f) (a , c))
( fib-total-map-fib-fiberwise A B C f (a , c))
:=
( ( fib-fiberwise-fib-total-map A B C f (a , c))
, ( \ (b , p) →
ind-path (C a) (f a b)
( \ c' p' →
( ( fib-fiberwise-fib-total-map A B C f ((a , c')))
( ( fib-total-map-fib-fiberwise A B C f (a , c')) (b , p'))
= ( b , p')))
( refl)
( c)
( p)))
#def has-section-fib-total-map-fib-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( ( a , c) : (Σ (x : A) , C x))
: has-section
( fib (B a) (C a) (f a) c)
( fib (total-type A B) (total-type A C) (total-map A B C f) (a , c))
( fib-total-map-fib-fiberwise A B C f (a , c))
:=
( ( fib-fiberwise-fib-total-map A B C f (a , c))
, ( \ ((a' , b') , p) →
ind-path
( total-type A C)
( a' , f a' b')
( \ w' p' →
( ( fib-total-map-fib-fiberwise A B C f w')
( ( fib-fiberwise-fib-total-map A B C f w') ((a' , b') , p'))
= ( ( a' , b') , p')))
( refl)
( a , c)
( p)))
#def is-equiv-fib-total-map-fib-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( ( a , c) : total-type A C)
: is-equiv
( fib (B a) (C a) (f a) c)
( fib (total-type A B) (total-type A C) (total-map A B C f) (a , c))
( fib-total-map-fib-fiberwise A B C f (a , c))
:=
( has-retraction-fib-total-map-fib-fiberwise A B C f (a , c)
, has-section-fib-total-map-fib-fiberwise A B C f (a , c))
#def equiv-fib-total-map-fib-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( ( a , c) : total-type A C)
: Equiv
( fib (B a) (C a) (f a) c)
( fib (total-type A B) (total-type A C) (total-map A B C f) (a , c))
:=
( fib-total-map-fib-fiberwise A B C f (a , c)
, is-equiv-fib-total-map-fib-fiberwise A B C f (a , c))
Families of equivalences¶
A family of equivalences induces an equivalence on total spaces and conversely. It will be easiest to work with the incoherent notion of two-sided-inverses.
#def map-inverse-total-has-inverse-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( invfamily : (a : A) → has-inverse (B a) (C a) (f a))
: ( total-type A C) → (total-type A B)
:=
\ (a , c) →
( a , (map-inverse-has-inverse (B a) (C a) (f a) (invfamily a)) c)
#def has-retraction-total-has-inverse-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( invfamily : (a : A) → has-inverse (B a) (C a) (f a))
: has-retraction (total-type A B) (total-type A C) (total-map A B C f)
:=
( map-inverse-total-has-inverse-fiberwise A B C f invfamily
, \ (a , b) →
( eq-eq-fiber-Σ A B a
( ( map-inverse-has-inverse (B a) (C a) (f a) (invfamily a)) (f a b)) b
( ( first (second (invfamily a))) b)))
#def has-section-total-has-inverse-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( invfamily : (a : A) → has-inverse (B a) (C a) (f a))
: has-section (total-type A B) (total-type A C) (total-map A B C f)
:=
( map-inverse-total-has-inverse-fiberwise A B C f invfamily
, \ (a , c) →
( eq-eq-fiber-Σ A C a
( f a ((map-inverse-has-inverse (B a) (C a) (f a) (invfamily a)) c)) c
( ( second (second (invfamily a))) c)))
#def has-inverse-total-has-inverse-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( invfamily : (a : A) → has-inverse (B a) (C a) (f a))
: has-inverse (total-type A B) (total-type A C) (total-map A B C f)
:=
( map-inverse-total-has-inverse-fiberwise A B C f invfamily
, ( second (has-retraction-total-has-inverse-fiberwise A B C f invfamily)
, second (has-section-total-has-inverse-fiberwise A B C f invfamily)))
The one-way result: that a family of equivalence gives an invertible map (and thus an equivalence) on total spaces.
#def has-inverse-total-is-equiv-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( familyequiv : (a : A) → is-equiv (B a) (C a) (f a))
: has-inverse (total-type A B) (total-type A C) (total-map A B C f)
:=
has-inverse-total-has-inverse-fiberwise A B C f
( \ a → has-inverse-is-equiv (B a) (C a) (f a) (familyequiv a))
#def is-equiv-total-is-equiv-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( familyequiv : (a : A) → is-equiv (B a) (C a) (f a))
: is-equiv (total-type A B) (total-type A C) (total-map A B C f)
:=
is-equiv-has-inverse
( total-type A B) (total-type A C) (total-map A B C f)
( has-inverse-total-is-equiv-fiberwise A B C f familyequiv)
#def total-equiv-family-of-equiv
( A : U)
( B C : A → U)
( familyeq : (a : A) → Equiv (B a) (C a))
: Equiv (total-type A B) (total-type A C)
:=
( total-map A B C (\ a → first (familyeq a))
, is-equiv-total-is-equiv-fiberwise A B C
( \ a → first (familyeq a))
( \ a → second (familyeq a)))
For the converse, we make use of our calculation on fibers. The first implication could be proven similarly.
#def is-contr-map-total-is-contr-map-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( totalcontrmap
: is-contr-map (total-type A B) (total-type A C) (total-map A B C f))
( a : A)
: is-contr-map (B a) (C a) (f a)
:=
\ c →
is-contr-equiv-is-contr'
( fib (B a) (C a) (f a) c)
( fib (total-type A B) (total-type A C) (total-map A B C f) (a , c))
( equiv-fib-total-map-fib-fiberwise A B C f (a , c))
( totalcontrmap (a , c))
#def is-equiv-fiberwise-is-equiv-total
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( totalequiv
: is-equiv (total-type A B) (total-type A C) (total-map A B C f))
( a : A)
: is-equiv (B a) (C a) (f a)
:=
is-equiv-is-contr-map (B a) (C a) (f a)
( is-contr-map-total-is-contr-map-fiberwise A B C f
( is-contr-map-is-equiv
( total-type A B) (total-type A C) (total-map A B C f)
( totalequiv))
( a))
#def family-of-equiv-is-equiv-total
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
( totalequiv
: is-equiv (total-type A B) (total-type A C) (total-map A B C f))
( a : A)
: Equiv (B a) (C a)
:= (f a , is-equiv-fiberwise-is-equiv-total A B C f totalequiv a)
In summary, a family of maps is an equivalence iff the map on total spaces is an equivalence.
#def is-equiv-total-iff-is-equiv-fiberwise
( A : U)
( B C : A → U)
( f : (a : A) → (B a) → (C a))
: iff
( ( a : A) → is-equiv (B a) (C a) (f a))
( is-equiv (Σ (x : A) , B x) (Σ (x : A) , C x)
( total-map A B C f))
:=
( is-equiv-total-is-equiv-fiberwise A B C f
, is-equiv-fiberwise-is-equiv-total A B C f)
Path spaces¶
Based path spaces¶
#def equiv-based-paths
( A : U)
( a : A)
: Equiv (Σ (x : A) , x = a) (Σ (x : A) , a = x)
:= total-equiv-family-of-equiv A (\ x → x = a) (\ x → a = x) (\ x → equiv-rev A x a)
#def is-contr-endpoint-based-paths
( A : U)
( a : A)
: is-contr (Σ (x : A) , x = a)
:=
is-contr-equiv-is-contr' (Σ (x : A) , x = a) (Σ (x : A) , a = x)
( equiv-based-paths A a)
( is-contr-based-paths A a)
Free path spaces¶
The canonical map from a type to its the free path type is an equivalence.
#def free-paths
( A : U)
: U
:= Σ ((x , y) : product A A) , (x = y)
#def constant-free-path
( A : U)
( a : A)
: free-paths A
:= ((a , a) , refl)
#def is-constant-free-path
( A : U)
( ( ( a , y) , p) : free-paths A)
: constant-free-path A a = ((a , y) , p)
:=
ind-path A a
( \ x p' → constant-free-path A a = ((a , x) , p'))
( refl)
( y) (p)
#def start-free-path
( A : U)
: free-paths A → A
:= \ ((a , _) , _) → a
#def is-equiv-constant-free-path
( A : U)
: is-equiv A (free-paths A) (constant-free-path A)
:=
( ( start-free-path A , \ _ → refl)
, ( start-free-path A , is-constant-free-path A))
Pullback of a type family¶
A family of types over B pulls back along any function f : A → B to define a family of types over A.
#def pullback
( A B : U)
( f : A → B)
( C : B → U)
: A → U
:= \ a → C (f a)
The pullback of a family along homotopic maps is equivalent.
#section is-equiv-pullback-htpy
#variables A B : U
#variables f g : A → B
#variable α : homotopy A B f g
#variable C : B → U
#variable a : A
#def pullback-homotopy
: ( pullback A B f C a) → (pullback A B g C a)
:= transport B C (f a) (g a) (α a)
#def map-inverse-pullback-homotopy
: ( pullback A B g C a) → (pullback A B f C a)
:= transport B C (g a) (f a) (rev B (f a) (g a) (α a))
#def has-retraction-pullback-homotopy
: has-retraction
( pullback A B f C a)
( pullback A B g C a)
( pullback-homotopy)
:=
( map-inverse-pullback-homotopy
, \ c →
concat
( pullback A B f C a)
( transport B C (g a) (f a)
( rev B (f a) (g a) (α a))
( transport B C (f a) (g a) (α a) c))
( transport B C (f a) (f a)
( concat B (f a) (g a) (f a) (α a) (rev B (f a) (g a) (α a))) c)
( c)
( transport-concat-rev B C (f a) (g a) (f a) (α a)
( rev B (f a) (g a) (α a)) c)
( transport2 B C (f a) (f a)
( concat B (f a) (g a) (f a) (α a) (rev B (f a) (g a) (α a))) refl
( right-inverse-concat B (f a) (g a) (α a)) c))
#def has-section-pullback-homotopy
: has-section (pullback A B f C a) (pullback A B g C a)
( pullback-homotopy)
:=
( map-inverse-pullback-homotopy
, \ c →
concat
( pullback A B g C a)
( transport B C (f a) (g a) (α a)
( transport B C (g a) (f a) (rev B (f a) (g a) (α a)) c))
( transport B C (g a) (g a)
( concat B (g a) (f a) (g a) (rev B (f a) (g a) (α a)) (α a)) c)
( c)
( transport-concat-rev B C (g a) (f a) (g a)
( rev B (f a) (g a) (α a)) (α a) (c))
( transport2 B C (g a) (g a)
( concat B (g a) (f a) (g a) (rev B (f a) (g a) (α a)) (α a))
( refl)
( left-inverse-concat B (f a) (g a) (α a)) c))
#def is-equiv-pullback-homotopy uses (α)
: is-equiv
( pullback A B f C a)
( pullback A B g C a)
( pullback-homotopy)
:= (has-retraction-pullback-homotopy , has-section-pullback-homotopy)
#def equiv-pullback-homotopy uses (α)
: Equiv (pullback A B f C a) (pullback A B g C a)
:= (pullback-homotopy , is-equiv-pullback-homotopy)
#end is-equiv-pullback-htpy
The total space of a pulled back family of types maps to the original total space.
#def pullback-comparison-map
( A B : U)
( f : A → B)
( C : B → U)
: ( Σ ( a : A) , (pullback A B f C) a) → (Σ (b : B) , C b)
:= \ (a , c) → (f a , c)
Now we show that if a family is pulled back along an equivalence, the total spaces are equivalent by proving that the comparison is a contractible map. For this, we first prove that each fiber is equivalent to a fiber of the original map.
#def pullback-comparison-fiber
( A B : U)
( f : A → B)
( C : B → U)
( z : Σ (b : B) , C b)
: U
:=
fib
( Σ ( a : A) , (pullback A B f C) a)
( Σ ( b : B) , C b)
( pullback-comparison-map A B f C) z
#def pullback-comparison-fiber-to-fiber
( A B : U)
( f : A → B)
( C : B → U)
( z : Σ (b : B) , C b)
: ( pullback-comparison-fiber A B f C z) → (fib A B f (first z))
:=
\ (w , p) →
ind-path
( Σ ( b : B) , C b)
( pullback-comparison-map A B f C w)
( \ z' p' →
( fib A B f (first z')))
( first w , refl)
( z)
( p)
#def from-base-fiber-to-pullback-comparison-fiber
( A B : U)
( f : A → B)
( C : B → U)
( b : B)
: ( fib A B f b) → (c : C b) → (pullback-comparison-fiber A B f C (b , c))
:=
\ (a , p) →
ind-path
( B)
( f a)
( \ b' p' →
( c : C b') → (pullback-comparison-fiber A B f C ((b' , c))))
( \ c → ((a , c) , refl))
( b)
( p)
#def pullback-comparison-fiber-to-fiber-inv
( A B : U)
( f : A → B)
( C : B → U)
( z : Σ (b : B) , C b)
: ( fib A B f (first z)) → (pullback-comparison-fiber A B f C z)
:=
\ (a , p) →
from-base-fiber-to-pullback-comparison-fiber A B f C
( first z) (a , p) (second z)
#def pullback-comparison-fiber-to-fiber-retracting-homotopy
( A B : U)
( f : A → B)
( C : B → U)
( z : Σ (b : B) , C b)
( ( w , p) : pullback-comparison-fiber A B f C z)
: ( ( pullback-comparison-fiber-to-fiber-inv A B f C z)
( ( pullback-comparison-fiber-to-fiber A B f C z) (w , p))) = (w , p)
:=
ind-path
( Σ ( b : B) , C b)
( pullback-comparison-map A B f C w)
( \ z' p' →
( ( pullback-comparison-fiber-to-fiber-inv A B f C z')
( ( pullback-comparison-fiber-to-fiber A B f C z') (w , p')))
= ( w , p'))
( refl)
( z)
( p)
#def pullback-comparison-fiber-to-fiber-section-homotopy-map
( A B : U)
( f : A → B)
( C : B → U)
( b : B)
( ( a , p) : fib A B f b)
: ( c : C b)
→ ( ( pullback-comparison-fiber-to-fiber A B f C (b , c))
( ( pullback-comparison-fiber-to-fiber-inv A B f C (b , c)) (a , p)))
= ( a , p)
:=
ind-path
( B)
( f a)
( \ b' p' →
( c : C b')
→ ( ( pullback-comparison-fiber-to-fiber A B f C (b' , c))
( ( pullback-comparison-fiber-to-fiber-inv A B f C (b' , c)) (a , p')))
= ( a , p'))
( \ c → refl)
( b)
( p)
#def pullback-comparison-fiber-to-fiber-section-homotopy
( A B : U)
( f : A → B)
( C : B → U)
( z : Σ (b : B) , C b)
( ( a , p) : fib A B f (first z))
: ( pullback-comparison-fiber-to-fiber A B f C z
( pullback-comparison-fiber-to-fiber-inv A B f C z (a , p))) = (a , p)
:=
pullback-comparison-fiber-to-fiber-section-homotopy-map A B f C
( first z) (a , p) (second z)
#def equiv-pullback-comparison-fiber
( A B : U)
( f : A → B)
( C : B → U)
( z : Σ (b : B) , C b)
: Equiv (pullback-comparison-fiber A B f C z) (fib A B f (first z))
:=
( pullback-comparison-fiber-to-fiber A B f C z
, ( ( pullback-comparison-fiber-to-fiber-inv A B f C z
, pullback-comparison-fiber-to-fiber-retracting-homotopy A B f C z)
, ( pullback-comparison-fiber-to-fiber-inv A B f C z
, pullback-comparison-fiber-to-fiber-section-homotopy A B f C z)))
As a corollary, we show that pullback along an equivalence induces an equivalence of total spaces.
#def equiv-total-pullback-is-equiv
( A B : U)
( f : A → B)
( is-equiv-f : is-equiv A B f)
( C : B → U)
: Equiv (Σ (a : A) , (pullback A B f C) a) (Σ (b : B) , C b)
:=
( pullback-comparison-map A B f C
, is-equiv-is-contr-map
( Σ ( a : A) , (pullback A B f C) a)
( Σ ( b : B) , C b)
( pullback-comparison-map A B f C)
( \ z →
( is-contr-equiv-is-contr'
( pullback-comparison-fiber A B f C z)
( fib A B f (first z))
( equiv-pullback-comparison-fiber A B f C z)
( is-contr-map-is-equiv A B f is-equiv-f (first z)))))
Fundamental theorem of identity types¶
The fundamental theorem of identity types concerns the following question: Given
a type family B : A → U
, when is B
equivalent to \ x → a x
for some
a : A
?
We start by fixing a : A
and investigating when a map of families
x : A → (a = x) → B x
is a (fiberwise) equivalence.
#section fundamental-thm-id-types
#variable A : U
#variable a : A
#variable B : A → U
#variable f : (x : A) → (a = x) → B x
#def is-contr-total-are-equiv-from-paths
: ( ( x : A) → (is-equiv (a = x) (B x) (f x)))
→ ( is-contr (Σ (x : A) , B x))
:=
( \ familyequiv →
( equiv-with-contractible-domain-implies-contractible-codomain
( Σ ( x : A) , a = x) (Σ (x : A) , B x)
( ( total-map A (\ x → (a = x)) B f)
, ( is-equiv-has-inverse (Σ (x : A) , a = x) (Σ (x : A) , B x)
( total-map A (\ x → (a = x)) B f)
( has-inverse-total-is-equiv-fiberwise A
( \ x → (a = x)) B f familyequiv)))
( is-contr-based-paths A a)))
#def are-equiv-from-paths-is-contr-total
: ( is-contr (Σ (x : A) , B x))
→ ( ( x : A) → (is-equiv (a = x) (B x) (f x)))
:=
( \ is-contr-Σ-A-B x →
is-equiv-fiberwise-is-equiv-total A
( \ x' → (a = x'))
( B)
( f)
( is-equiv-are-contr
( Σ ( x' : A) , (a = x'))
( Σ ( x' : A) , (B x'))
( is-contr-based-paths A a)
( is-contr-Σ-A-B)
( total-map A (\ x' → (a = x')) B f))
( x))
This allows us to apply "based path induction" to a family satisfying the fundamental theorem:
#def ind-based-path
( familyequiv : (z : A) → (is-equiv (a = z) (B z) (f z)))
( P : (z : A) → B z → U)
( p0 : P a (f a refl))
( u : A)
( p : B u)
: P u p
:=
ind-sing
( Σ ( v : A) , B v)
( a , f a refl)
( \ (u' , p') → P u' p')
( contr-implies-singleton-induction-pointed
( Σ ( z : A) , B z)
( is-contr-total-are-equiv-from-paths familyequiv)
( \ (x' , p') → P x' p'))
( p0)
( u , p)
#end fundamental-thm-id-types
We can now answer the original question. A type family B : A → U
is equivalent
to the family of based paths at a point if and only if its total space is
contractible.
#def map-from-paths-inhabited-total
( A : U)
( B : A → U)
( ( a , b) : total-type A B)
( x : A)
: ( a = x) → B x
:= ind-path A a (\ y _ → B y) b x
#def fundamental-theorem-of-identity-types
( A : U)
( B : A → U)
: iff
( is-contr (total-type A B))
( Σ ( a : A) , ((x : A) → Equiv (a = x) (B x)))
:=
( ( \ ((a , b) , h) →
( a
, \ x →
( map-from-paths-inhabited-total A B (a , b) x
, are-equiv-from-paths-is-contr-total A a B
( map-from-paths-inhabited-total A B (a , b))
( ( a , b) , h)
( x))))
, ( \ (a , familyequiv) →
is-contr-total-are-equiv-from-paths A a B
( \ x → first (familyequiv x))
( \ x → second (familyequiv x))))
Weak function extensionality implies function extensionality¶
Using the fundamental theorem of identity types, we prove the converse of
weakfunext-funext
, so we now know that FunExt
is logically equivalent
to WeakFunExt
. We follow the proof in Rijke, section 13.1.
We first fix one of the two functions and show that WeakFunExt
implies a
version of function extensionality that asserts that a type of "maps together
with homotopies" is contractible.
#def components-dhomotopy
( A : U)
( C : A → U)
( f : (x : A) → C x)
: ( Σ ( g : (x : A) → C x)
, ( dhomotopy A C f g))
→ ( ( x : A)
→ ( Σ ( c : (C x))
, ( f x =_{C x} c)))
:=
\ (g , H) →
( \ x →
( g x , H x))
#def has-retraction-components-dhomotopy
( A : U)
( C : A → U)
( f : (x : A) → C x)
: has-retraction
( Σ ( g : (x : A) → C x)
, ( dhomotopy A C f g))
( ( x : A)
→ ( Σ ( c : (C x))
, ( f x =_{C x} c)))
( components-dhomotopy A C f)
:=
( ( \ G →
( \ x → first (G x) , \ x → second (G x)))
, \ x → refl)
#def is-retract-components-dhomotopy
( A : U)
( C : A → U)
( f : (x : A) → C x)
: is-retract-of
( Σ ( g : (x : A) → C x)
, ( dhomotopy A C f g))
( ( x : A)
→ ( Σ ( c : (C x))
, ( f x =_{C x} c)))
:=
( components-dhomotopy A C f
, has-retraction-components-dhomotopy A C f)
#def WeirdFunExt
: U
:=
( A : U) → (C : A → U)
→ ( f : (x : A) → C x)
→ is-contr
( Σ ( g : (x : A) → C x)
, ( dhomotopy A C f g))
#def weirdfunext-weakfunext
( weakfunext : WeakFunExt)
: WeirdFunExt
:=
\ A C f →
is-contr-is-retract-of-is-contr
( Σ ( g : (x : A) → C x)
, ( dhomotopy A C f g))
( ( x : A)
→ ( Σ ( c : (C x))
, ( f x =_{C x} c)))
( is-retract-components-dhomotopy A C f)
( weakfunext
( A)
( \ x → Σ (c : (C x)) , (f x =_{C x} c))
( \ x → is-contr-based-paths (C x) (f x)))
We now use the fundamental theorem of identity types to go from the version for
a fixed f to the total FunExt
axiom.
#def funext-weirdfunext
( weirdfunext : WeirdFunExt)
: FunExt
:=
\ A C f g →
are-equiv-from-paths-is-contr-total
( ( x : A) → C x)
( f)
( \ h → dhomotopy A C f h)
( \ h → htpy-eq A C f h)
( weirdfunext A C f)
( g)
#def funext-weakfunext
( weakfunext : WeakFunExt)
: FunExt
:=
funext-weirdfunext (weirdfunext-weakfunext weakfunext)
The proof of weakfunext-funext
from 06-contractible.rzk
works with a version
of function extensionality only requiring the map in the converse direction. We
can then prove a cycle of implications between FunExt
,
NaiveFunExt
and WeakFunExt
.
#def NaiveFunExt
: U
:=
( A : U) → (C : A → U)
→ ( f : (x : A) → C x)
→ ( g : (x : A) → C x)
→ ( p : (x : A) → f x = g x)
→ ( f = g)
#def naivefunext-funext
( funext : FunExt)
: NaiveFunExt
:=
\ A C f g p →
eq-htpy funext A C f g p
#def weakfunext-naivefunext
( naivefunext : NaiveFunExt)
: WeakFunExt
:=
\ A C is-contr-C →
( map-weakfunext A C is-contr-C
, ( \ g →
( naivefunext
( A)
( C)
( map-weakfunext A C is-contr-C)
( g)
( \ a → second (is-contr-C a) (g a)))))
Maps over product types¶
For later use, we specialize the previous results to the case of a family of types over a product type.
#section fibered-map-over-product
#variables A A' B B' : U
#variable C : A → B → U
#variable C' : A' → B' → U
#variable f : A → A'
#variable g : B → B'
#variable h : (a : A) → (b : B) → (C a b) → C' (f a) (g b)
#def total-map-fibered-map-over-product
: ( Σ ( a : A) , (Σ (b : B) , C a b))
→ ( Σ ( a' : A') , (Σ (b' : B') , C' a' b'))
:= \ (a , (b , c)) → (f a , (g b , h a b c))
#def pullback-is-equiv-base-is-equiv-total-is-equiv
( is-equiv-total
: is-equiv
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a' : A') , (Σ (b' : B') , C' a' b'))
( total-map-fibered-map-over-product))
( is-equiv-f : is-equiv A A' f)
: is-equiv
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a : A) , (Σ (b' : B') , C' (f a) b'))
( \ (a , (b , c)) → (a , (g b , h a b c)))
:=
is-equiv-right-factor
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a : A) , (Σ (b' : B') , C' (f a) b'))
( Σ ( a' : A') , (Σ (b' : B') , C' a' b'))
( \ (a , (b , c)) → (a , (g b , h a b c)))
( \ (a , (b' , c')) → (f a , (b' , c')))
( second
( equiv-total-pullback-is-equiv
( A) (A')
( f) (is-equiv-f)
( \ a' → (Σ (b' : B') , C' a' b'))))
( is-equiv-total)
#def pullback-is-equiv-bases-are-equiv-total-is-equiv
( is-equiv-total
: is-equiv
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a' : A') , (Σ (b' : B') , C' a' b'))
( total-map-fibered-map-over-product))
( is-equiv-f : is-equiv A A' f)
( is-equiv-g : is-equiv B B' g)
: is-equiv
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a : A) , (Σ (b : B) , C' (f a) (g b)))
( \ (a , (b , c)) → (a , (b , h a b c)))
:=
is-equiv-right-factor
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a : A) , (Σ (b : B) , C' (f a) (g b)))
( Σ ( a : A) , (Σ (b' : B') , C' (f a) b'))
( \ (a , (b , c)) → (a , (b , h a b c)))
( \ (a , (b , c)) → (a , (g b , c)))
( is-equiv-total-is-equiv-fiberwise A
( \ a → (Σ (b : B) , C' (f a) (g b)))
( \ a → (Σ (b' : B') , C' (f a) b'))
( \ a (b , c) → (g b , c))
( \ a →
( second
( equiv-total-pullback-is-equiv
( B) (B')
( g) (is-equiv-g)
( \ b' → C' (f a) b')))))
( pullback-is-equiv-base-is-equiv-total-is-equiv is-equiv-total is-equiv-f)
#def fibered-map-is-equiv-bases-are-equiv-total-map-is-equiv
( is-equiv-total
: is-equiv
( Σ ( a : A) , (Σ (b : B) , C a b))
( Σ ( a' : A') , (Σ (b' : B') , C' a' b'))
( total-map-fibered-map-over-product))
( is-equiv-f : is-equiv A A' f)
( is-equiv-g : is-equiv B B' g)
( a0 : A)
( b0 : B)
: is-equiv (C a0 b0) (C' (f a0) (g b0)) (h a0 b0)
:=
is-equiv-fiberwise-is-equiv-total B
( \ b → C a0 b)
( \ b → C' (f a0) (g b))
( \ b c → h a0 b c)
( is-equiv-fiberwise-is-equiv-total
( A)
( \ a → (Σ (b : B) , C a b))
( \ a → (Σ (b : B) , C' (f a) (g b)))
( \ a (b , c) → (b , h a b c))
( pullback-is-equiv-bases-are-equiv-total-is-equiv
is-equiv-total is-equiv-f is-equiv-g)
( a0))
( b0)
#end fibered-map-over-product