Built with Alectryon. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
(** * Varieties of univalence *)Require Import HoTT.Basics HoTT.Types.Require Import Idempotents.Require Import Metatheory.Core.LocalOpen Scope path_scope.(** A weaker form that only asserts that we can make equivalences into paths with a computation rule (no uniqueness rule). *)DefinitionWeakUnivalence :=
{ etop : forallAB, (A <~> B) -> (A = B) &
forallAB (f : A <~> B), equiv_path A B (etop A B f) = f }.(** The same thing, stated with an incoherent notion of equivalence but a pointwise equality for the computation rule. *)DefinitionIncoherentWeakUnivalence :=
{ etop : forallAB (f : A -> B) (g : B -> A),
(f o g == idmap) -> (g o f == idmap) -> (A = B) &
forallABfgHK, equiv_path A B (etop A B f g H K) == f }.(** Finally, it even suffices to consider only just a few special cases. This is due to Ian Orton and Andrew Pitts. *)RecordVeryWeakUnivalence :=
{ unit : forallA, A = { a : A & Unit };
flip : forallAB (C : A -> B -> Type),
{ a : A & { b : B & C a b }} = { b : B & { a : A & C a b }};
contract : forallA, Contr A -> A = Unit;
unit_comp : forallAa, transport idmap (unit A) a = (a;tt);
flip_comp : forallABC (a:A) (b:B) (c : C a b),
transport idmap (flip A B C) (a ; (b ; c)) = (b ; (a ; c))
}.
WeakUnivalence -> Univalence_type
WeakUnivalence -> Univalence_type
etop: forallA0B : Type, A0 <~> B -> A0 = B H: forall (A0B : Type) (f : A0 <~> B), equiv_path A0 B (etop A0 B f) = f A: Type
forallB : Type, IsEquiv (equiv_path A B)
etop: forallA0B : Type, A0 <~> B -> A0 = B H: forall (A0B : Type) (f : A0 <~> B), equiv_path A0 B (etop A0 B f) = f A: Type
IsEquiv (functor_sigma idmap (equiv_path A))
etop: forallA0B : Type, A0 <~> B -> A0 = B H: forall (A0B : Type) (f : A0 <~> B), equiv_path A0 B (etop A0 B f) = f A: Type
Contr {x : _ & A <~> x}
etop: forallA0B : Type, A0 <~> B -> A0 = B H: forall (A0B : Type) (f : A0 <~> B), equiv_path A0 B (etop A0 B f) = f A: Type
(funBe : {x : _ & A = x} => (Be.1; equiv_path A Be.1 Be.2))
o (funBf : {x : _ & A <~> x} => (Bf.1; etop A Bf.1 Bf.2)) == idmap
etop: forallA0B0 : Type, A0 <~> B0 -> A0 = B0 H: forall (A0B0 : Type) (f0 : A0 <~> B0), equiv_path A0 B0 (etop A0 B0 f0) = f0 A, B: Type f: A <~> B
(((B; f).1; etop A (B; f).1 (B; f).2).1;
equiv_path A ((B; f).1; etop A (B; f).1 (B; f).2).1
((B; f).1; etop A (B; f).1 (B; f).2).2) =
(B; f)
refine (path_sigma' (funB => A <~> B) 1 (H A B f)).Defined.(** For this one and the next one, we need to assume funext to start with (so that these forms of univalence, unlike the usual one, probably don't suffice to prove funext from). *)
H: Funext
IncoherentWeakUnivalence -> Univalence_type
H: Funext
IncoherentWeakUnivalence -> Univalence_type
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f
Univalence_type
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f
WeakUnivalence
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f
forallAB : Type, A <~> B -> A = B
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f etop':= ?Goal: forallAB : Type, A <~> B -> A = B
WeakUnivalence
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f etop':= fun (AB : Type) (f : A <~> B) =>
etop A B f f^-1
((funx : B => eisretr f x) : (funx : B => f (f^-1 x)) == idmap)
((funx : A => eissect f x) : (funx : A => f^-1 (f x)) == idmap): forallAB : Type, A <~> B -> A = B
WeakUnivalence
H: Funext etop: forall (AB : Type) (f : A -> B) (g : B -> A),
(funx : B => f (g x)) == idmap -> (funx : A => g (f x)) == idmap -> A = B K: forall (AB : Type) (f : A -> B) (g : B -> A)
(H0 : (funx : B => f (g x)) == idmap)
(K0 : (funx : A => g (f x)) == idmap),
equiv_path A B (etop A B f g H0 K0) == f etop':= fun (AB : Type) (f : A <~> B) =>
etop A B f f^-1
((funx : B => eisretr f x) : (funx : B => f (f^-1 x)) == idmap)
((funx : A => eissect f x) : (funx : A => f^-1 (f x)) == idmap): forallAB : Type, A <~> B -> A = B
forall (AB : Type) (f : A <~> B), equiv_path A B (etop' A B f) = f
(funetop : forallAB : Type, A <~> B -> A = B =>
forall (AB : Type) (f : A <~> B), equiv_path A B (etop A B f) = f)
?proj1
H: Funext vwu: VeryWeakUnivalence
forallAB : Type, A <~> B -> A = B
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
A = B
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
{_ : A & Unit} = {_ : B & Unit}
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
{_ : A & Unit} = {a : A & {b : B & f a = b}}
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
{b : B & {a : A & f a = b}} = {_ : B & Unit}
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
{_ : A & Unit} = {a : A & {b : B & f a = b}}
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
Unit = {b : B & f a = b}
symmetry; rapply (contract vwu).
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
{b : B & {a : A & f a = b}} = {_ : B & Unit}
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B b: B
{a : A & f a = b} = Unit
apply (contract vwu); exact _.
H: Funext vwu: VeryWeakUnivalence
(funetop : forallAB : Type, A <~> B -> A = B =>
forall (AB : Type) (f : A <~> B), equiv_path A B (etop A B f) = f)
(fun (AB : Type) (f : A <~> B) =>
(unit vwu A @
((ap sig
(path_arrow (fun_ : A => Unit) (funa : A => {b : B & f a = b})
((funa : A =>
(contract vwu {b : B & f a = b} (contr_basedpaths (f a)))^)
:
(fun_ : A => Unit) == (funa : A => {b : B & f a = b}))) @
flip vwu A B (fun (a : A) (b : B) => f a = b)) @
ap sig
(path_arrow (funb : B => {a : A & f a = b})
(fun_ : B => Unit)
((funb : B => contract vwu {a : A & f a = b} (istruncmap_fiber b))
:
(funb : B => {a : A & f a = b}) == (fun_ : B => Unit))))) @
(unit vwu B)^)
H: Funext vwu: VeryWeakUnivalence
(funetop : forallAB : Type, A <~> B -> A = B =>
forall (AB : Type) (f : A <~> B), equiv_path A B (etop A B f) = f)
(fun (AB : Type) (f : A <~> B) =>
(unit vwu A @
((ap sig
(path_arrow (fun_ : A => Unit) (funa : A => {b : B & f a = b})
((funa : A =>
(contract vwu {b : B & f a = b} (contr_basedpaths (f a)))^)
:
(fun_ : A => Unit) == (funa : A => {b : B & f a = b}))) @
flip vwu A B (fun (a : A) (b : B) => f a = b)) @
ap sig
(path_arrow (funb : B => {a : A & f a = b})
(fun_ : B => Unit)
((funb : B => contract vwu {a : A & f a = b} (istruncmap_fiber b))
:
(funb : B => {a : A & f a = b}) == (fun_ : B => Unit))))) @
(unit vwu B)^)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B
equiv_path A B
((unit vwu A @
((ap sig
(path_arrow (fun_ : A => Unit) (funa : A => {b : B & f a = b})
(funa : A =>
(contract vwu {b : B & f a = b} (contr_basedpaths (f a)))^)) @
flip vwu A B (fun (a : A) (b : B) => f a = b)) @
ap sig
(path_arrow (funb : B => {a : A & f a = b})
(fun_ : B => Unit)
(funb : B => contract vwu {a : A & f a = b} (istruncmap_fiber b))))) @
(unit vwu B)^) =
f
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport idmap
((unit vwu A @
((ap sig
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^)) @
flip vwu A B (fun (a0 : A) (b : B) => f a0 = b)) @
ap sig
(path_arrow (funb : B => {a0 : A & f a0 = b})
(fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b))))) @
(unit vwu B)^)
a =
f a
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport idmap (unit vwu B)^
(transport idmap
(ap sig
(path_arrow (funb : B => {a0 : A & f a0 = b})
(fun_ : B => Unit)
(funb : B =>
contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b))))
(transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(transport idmap
(ap sig
(path_arrow (fun_ : A => Unit)
(funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^)))
(transport idmap (unit vwu A) a)))) =
f a
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport idmap
(ap sig
(path_arrow (funb : B => {a0 : A & f a0 = b})
(fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b))))
(transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(transport idmap
(ap sig
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^)))
(transport idmap (unit vwu A) a))) =
transport idmap (unit vwu B) (f a)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport idmap
(ap sig
(path_arrow (funb : B => {a0 : A & f a0 = b})
(fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b))))
(transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(transport idmap
(ap sig
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^)))
(a; tt))) =
(f a; tt)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport (funx : B -> Type => {x0 : _ & x x0})
(path_arrow (funb : B => {a0 : A & f a0 = b}) (fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b)))
(transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(transport (funx : A -> Type => {x0 : _ & x x0})
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^))
(a; tt))) =
(f a; tt)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport (funx : B -> Type => {x0 : _ & x x0})
(path_arrow (funb : B => {a0 : A & f a0 = b}) (fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b)))
(transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(a;
transport (funx : A -> Type => x a)
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^))
tt)) =
(f a; tt)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(a;
transport (funx : A -> Type => x a)
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^))
tt) =
?Goal
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport (funx : B -> Type => {x0 : _ & x x0})
(path_arrow (funb : B => {a0 : A & f a0 = b}) (fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b)))
?Goal =
(f a; tt)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(a;
transport (funx : A -> Type => x a)
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^))
tt) =
?Goal
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport (funx : A -> Type => x a)
(path_arrow (fun_ : A => Unit) (funa0 : A => {b : B & f a0 = b})
(funa0 : A =>
(contract vwu {b : B & f a0 = b} (contr_basedpaths (f a0)))^))
tt =
?y
exact (path_contr _ (f a ; 1)).
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport (funx : B -> Type => {x0 : _ & x x0})
(path_arrow (funb : B => {a0 : A & f a0 = b}) (fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b)))
(transport idmap (flip vwu A B (fun (a0 : A) (b : B) => f a0 = b))
(a; f a; 1)) =
(f a; tt)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
transport (funx : B -> Type => {x0 : _ & x x0})
(path_arrow (funb : B => {a0 : A & f a0 = b}) (fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b)))
(f a; a; 1) =
(f a; tt)
H: Funext vwu: VeryWeakUnivalence A, B: Type f: A <~> B a: A
(f a;
transport (funx : B -> Type => x (f a))
(path_arrow (funb : B => {a0 : A & f a0 = b}) (fun_ : B => Unit)
(funb : B => contract vwu {a0 : A & f a0 = b} (istruncmap_fiber b)))
(a; 1)) =
(f a; tt)