Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. 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.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Truncations.Require Import Universes.BAut.Require Import Pointed.Core.LocalOpen Scope trunc_scope.LocalOpen Scope path_scope.LocalOpen Scope pointed_scope.(** * BAut(Bool) *)SectionAssumeUnivalence.Context `{Univalence}.(** ** Nontrivial central homotopy *)(** The equivalence [Bool <~> (Bool <~> Bool)], and particularly its consequence [abelian_aut_bool], implies that [BAut Bool] has a nontrivial center. *)
exact (false_ne_true p).Defined.(** In particular, every element of [BAut Bool] has a canonical flip automorphism. *)Definitionnegb_baut_bool (Z : BAut Bool) : Z <~> Z
:= equiv_path Z Z (negb_center_baut_bool Z)..1.
H: Univalence Z: BAut Bool
negb_baut_bool Z <> 1%equiv
H: Univalence Z: BAut Bool
negb_baut_bool Z <> 1%equiv
H: Univalence Z: BAut Bool oops: negb_baut_bool Z = 1%equiv
Empty
H: Univalence Z: BAut Bool oops: negb_baut_bool Z = 1%equiv
exact negb_baut_bool_bool_negb.Defined.(** Moreover, we can show that every automorphism of a [Z : BAut Bool] must be either the flip or the identity. *)
H: Univalence Z: BAut Bool e: Z <~> Z
(e = 1%equiv) + (e = negb_baut_bool Z)
H: Univalence Z: BAut Bool e: Z <~> Z
(e = 1%equiv) + (e = negb_baut_bool Z)
H: Univalence Z: BAut Bool e: Z <~> Z
IsHProp ((e = 1%equiv) + (e = negb_baut_bool Z))
H: Univalence Z: BAut Bool e: Z <~> Z X: IsHProp ((e = 1%equiv) + (e = negb_baut_bool Z))
(e = 1%equiv) + (e = negb_baut_bool Z)
H: Univalence Z: BAut Bool e: Z <~> Z
IsHProp ((e = 1%equiv) + (e = negb_baut_bool Z))
H: Univalence Z: BAut Bool e: Z <~> Z
e = 1%equiv -> e = negb_baut_bool Z -> Empty
intros p q; exact (negb_baut_bool_ne_idmap Z (q^ @ p)).
H: Univalence Z: BAut Bool e: Z <~> Z X: IsHProp ((e = 1%equiv) + (e = negb_baut_bool Z))
exact (tr true).Defined.Definitionmerely_inhab_baut_bool `{Funext} (Z : BAut Bool)
: merely Z
:= center (merely Z).(** ** Equivalence types *)(** As soon as an element of [BAut Bool] is inhabited, it is (purely) equivalent to [Bool]. (Of course, every element of [BAut Bool] is *merely* inhabited, since [Bool] is.) In fact, it is equivalent in two canonical ways.First we define the function that will be the equivalence. *)Definitioninhab_baut_bool_from_bool (t : Bool)
(Z : BAut Bool) (z : Z)
: Bool -> Z
:= funb => if t thenif b then z else negb_baut_bool Z z
elseif b then negb_baut_bool Z z else z.(** We compute this in the case when [Z] is [Bool]. *)
H: Univalence t: Bool
inhab_baut_bool_from_bool t pt =
(fun (z : pt) (b : Bool) =>
if t
thenif b then z else negb z
elseif b then negb z else z)
H: Univalence t: Bool
inhab_baut_bool_from_bool t pt =
(fun (z : pt) (b : Bool) =>
if t
thenif b then z else negb z
elseif b then negb z else z)
H: Univalence t, z': Bool
inhab_baut_bool_from_bool t pt z' =
(funb : Bool =>
if t
thenif b then z' else negb z'
elseif b then negb z' else z')
H: Univalence t, z', b: Bool
inhab_baut_bool_from_bool t pt z' b =
(if t
thenif b then z' else negb z'
elseif b then negb z' else z')
destruct z', b, t; simpl;
tryreflexivity;
tryapply (ap10_equiv negb_baut_bool_bool_negb).Defined.(** Now we show that it is an equivalence. *)
H: Univalence t: Bool Z: BAut Bool z: Z
IsEquiv (inhab_baut_bool_from_bool t Z z)
H: Univalence t: Bool Z: BAut Bool z: Z
IsEquiv (inhab_baut_bool_from_bool t Z z)
H: Univalence t: Bool z: pt
IsEquiv (inhab_baut_bool_from_bool t pt z)
H: Univalence t: Bool z: pt
IsEquiv
(funb : Bool =>
if t
thenif b then z else negb z
elseif b then negb z else z)
H: Univalence
IsEquiv (funb : Bool => if b then true else false)
H: Univalence
IsEquiv (funb : Bool => if b then false else true)
H: Univalence
IsEquiv (funb : Bool => if b then false else true)
H: Univalence
IsEquiv (funb : Bool => if b then true else false)
H: Univalence
IsEquiv (funb : Bool => if b then true else false)
IsEquiv (funb : Bool => if b then false else true)
exact isequiv_negb.
H: Univalence
IsEquiv (funb : Bool => if b then false else true)
exact isequiv_negb.
H: Univalence
IsEquiv (funb : Bool => if b then true else false)
refine (isequiv_homotopic idmap _); intros []; reflexivity.Defined.Definitionequiv_inhab_baut_bool_bool (t : Bool)
(Z : BAut Bool) (z : Z)
: Bool <~> Z
:= Build_Equiv _ _ (inhab_baut_bool_from_bool t Z z) _.
H: Univalence Z: BAut Bool z: Z
pt = Z
H: Univalence Z: BAut Bool z: Z
pt = Z
H: Univalence Z: BAut Bool z: Z
pt <~> Z
exact (equiv_inhab_baut_bool_bool true Z z). (** [true] is a choice! *)Defined.(** In fact, the map sending [z:Z] to this equivalence [Bool <~> Z] is also an equivalence. To assist with computing the result when [Z] is [Bool], we prove it with an extra parameter first. *)
(funb : Bool =>
if t
thenif b then e t else negb (e t)
elseif b then negb (e t) else e t) = e
H: Univalence e: Bool <~> Bool
e true = e true
H: Univalence e: Bool <~> Bool
negb (e false) = e true
H: Univalence e: Bool <~> Bool
negb (e true) = e false
H: Univalence e: Bool <~> Bool
e false = e false
H: Univalence e: Bool <~> Bool
e true = e true
reflexivity.
H: Univalence e: Bool <~> Bool
negb (e false) = e true
exact (abelian_aut_bool equiv_negb e false).
H: Univalence e: Bool <~> Bool
negb (e true) = e false
exact (abelian_aut_bool equiv_negb e true).
H: Univalence e: Bool <~> Bool
e false = e false
reflexivity.
H: Univalence t: Bool
(funx : Bool => equiv_inhab_baut_bool_bool t pt x t) ==
idmap
H: Univalence t, z: Bool
equiv_inhab_baut_bool_bool t pt z t = z
H: Univalence t, z: Bool
(if t
thenif t then z else negb z
elseif t then negb z else z) = z
destruct t; reflexivity.Defined.
H: Univalence t: Bool Z: BAut Bool
IsEquiv (equiv_inhab_baut_bool_bool t Z)
H: Univalence t: Bool Z: BAut Bool
IsEquiv (equiv_inhab_baut_bool_bool t Z)
exact (isequiv_equiv_inhab_baut_bool_bool_lemma t Z
(merely_path_component _ _)).Defined.(** The names are getting pretty ridiculous; below we suggest a better name for this. *)Definitionequiv_equiv_inhab_baut_bool_bool (t : Bool)
(Z : BAut Bool)
: Z <~> (Bool <~> Z)
:= Build_Equiv _ _ (equiv_inhab_baut_bool_bool t Z) _.(** We compute its inverse in the case of [Bool]. *)
H: Univalence t: Bool e: Bool <~> Bool
(equiv_equiv_inhab_baut_bool_bool t pt)^-1%equiv e =
e t
H: Univalence t: Bool e: Bool <~> Bool
(equiv_equiv_inhab_baut_bool_bool t pt)^-1%equiv e =
e t
H: Univalence t: Bool e: Bool <~> Bool alt:= {|
equiv_fun := equiv_inhab_baut_bool_bool t pt;
equiv_isequiv :=
isequiv_equiv_inhab_baut_bool_bool_lemma t pt
(tr 1)
|}: pt <~> (Bool <~> pt) p: equiv_equiv_inhab_baut_bool_bool t pt = alt
(equiv_equiv_inhab_baut_bool_bool t pt)^-1%equiv e =
e t
exact (ap10_equiv (ap equiv_inverse p) e).Defined.(** ** Group structure *)(** Homotopically, [BAut Bool] is a [K(Z/2,1)]. In particular, it has a (coherent) abelian group structure induced from that of [Z/2]. With our definition of [BAut Bool], we can construct this operation as follows. *)
H: Univalence
BAut Bool -> BAut Bool -> BAut Bool
H: Univalence
BAut Bool -> BAut Bool -> BAut Bool
H: Univalence Z, W: BAut Bool
BAut Bool
H: Univalence Z, W: BAut Bool
merely ((Z <~> W) = Bool)
H: Univalence
Tr (-1) ((Bool <~> Bool) = Bool)
H: Univalence
Bool = (Bool <~> Bool)
exact (path_universe equiv_bool_aut_bool).Defined.Declare Scope baut_bool_scope.Notation"Z ** W" := (baut_bool_pairing Z W) : baut_bool_scope.LocalOpen Scope baut_bool_scope.(** Now [equiv_equiv_inhab_baut_bool_bool] is revealed as simply the left unit law of this pairing. *)
H: Univalence Z: BAut Bool
pt ** Z = Z
H: Univalence Z: BAut Bool
pt ** Z = Z
H: Univalence Z: BAut Bool
Bool
exact true. (** This is a choice! *)Defined.(** The pairing is obviously symmetric. *)
H: Univalence Z, W: BAut Bool
Z ** W = W ** Z
H: Univalence Z, W: BAut Bool
Z ** W = W ** Z
apply path_baut, equiv_equiv_inverse.Defined.(** Whence we get the right unit law as well. *)Definitionbaut_bool_pairing_Z1Z : Z ** pt = Z
:= baut_bool_pairing_symm Z pt @ baut_bool_pairing_1Z Z.(** Every element is its own inverse. *)
H: Univalence Z: BAut Bool
Z ** Z = pt
H: Univalence Z: BAut Bool
Z ** Z = pt
H: Univalence Z: BAut Bool
Z ** Z
exact equiv_idmap. (** A choice! Could be the flip. *)Defined.(** Associativity is easiest to think about in terms of "curried 2-variable equivalences". We start with some auxiliary lemmas. *)
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
Y ** W
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
Y ** W
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
Y -> W
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
W -> Y
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
?f o ?g == idmap
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
?g o ?f == idmap
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
Y -> W
exact (funy => e y z).
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
W -> Y
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z w: W
Y
H: Univalence Y, Z: BAut Bool e: Y ** Z ** pt z: Z w: pt
(** It might be tempting to just say [e^-1 (equiv_idmap _)] here, but for the rest of the proof to work, we actually need to choose between [idmap] and [negb] based on whether [z] and [w] are equal or not. *)
H: Univalence Y: BAut Bool e: Y ** pt ** pt z, w: pt p: z = w
Y
H: Univalence Y: BAut Bool e: Y ** pt ** pt z, w: pt n: z <> w
Y
H: Univalence Y: BAut Bool e: Y ** pt ** pt z, w: pt p: z = w
Y
exact (e^-1 (equiv_idmap _)).
H: Univalence Y: BAut Bool e: Y ** pt ** pt z, w: pt n: z <> w
Y
exact (e^-1 equiv_negb).
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
(funy : Y => e y z)
o (funw : W =>
letp := path_baut_bool_inhab W w inmatch
p in (_ = b) return (Y ** Z ** b -> b -> Y)
with
| 1 =>
fun (e : Y ** Z ** pt) (w0 : pt) =>
letp0 := path_baut_bool_inhab Z z inmatch
p0 in (_ = b) return (Y ** b ** pt -> b -> Y)
with
| 1 =>
fun (e0 : Y ** pt ** pt) (z : pt) =>
lets := dec (z = w0) inmatch s with
| inl p1 =>
(fun_ : z = w0 => e0^-11%equiv) p1
| inr n =>
(fun_ : z <> w0 => e0^-1 equiv_negb) n
endend e z
end e w) == idmap
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z w: W
e
(letp := path_baut_bool_inhab W w inmatch
p in (_ = b) return (Y ** Z ** b -> b -> Y)
with
| 1 =>
fun (e : Y ** Z ** pt) (w : pt) =>
letp0 := path_baut_bool_inhab Z z inmatch
p0 in (_ = b) return (Y ** b ** pt -> b -> Y)
with
| 1 =>
fun (e0 : Y ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e w) z = w
H: Univalence Y, Z: BAut Bool e: Y ** Z ** pt z: Z w: pt
e
(letp := 1inmatch
p in (_ = b) return (Y ** Z ** b -> b -> Y)
with
| 1 =>
fun (e : Y ** Z ** pt) (w : pt) =>
letp0 := path_baut_bool_inhab Z z inmatch
p0 in (_ = b) return (Y ** b ** pt -> b -> Y)
with
| 1 =>
fun (e0 : Y ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e w) z = w
e
(letp := 1inmatch
p in (_ = b) return (Y ** pt ** b -> b -> Y)
with
| 1 =>
fun (e : Y ** pt ** pt) (w : pt) =>
letp0 := 1inmatch
p0 in (_ = b) return (Y ** b ** pt -> b -> Y)
with
| 1 =>
fun (e0 : Y ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e w) z = w
e
match dec (z = w) with
| inl _ => e^-11%equiv
| inr _ => e^-1 equiv_negb
end z = w
destruct z,w; simpl; exact (ap10_equiv (eisretr e _) _).
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
(funw : W =>
letp := path_baut_bool_inhab W w inmatch
p in (_ = b) return (Y ** Z ** b -> b -> Y)
with
| 1 =>
fun (e : Y ** Z ** pt) (w0 : pt) =>
letp0 := path_baut_bool_inhab Z z inmatch
p0 in (_ = b) return (Y ** b ** pt -> b -> Y)
with
| 1 =>
fun (e0 : Y ** pt ** pt) (z : pt) =>
lets := dec (z = w0) inmatch s with
| inl p1 =>
(fun_ : z = w0 => e0^-11%equiv) p1
| inr n =>
(fun_ : z <> w0 => e0^-1 equiv_negb) n
endend e z
end e w) o (funy : Y => e y z) == idmap
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z y: Y
(letp := path_baut_bool_inhab W (e y z) inmatch
p in (_ = b) return (Y ** Z ** b -> b -> Y)
with
| 1 =>
fun (e : Y ** Z ** pt) (w : pt) =>
letp0 := path_baut_bool_inhab Z z inmatch
p0 in (_ = b) return (Y ** b ** pt -> b -> Y)
with
| 1 =>
fun (e0 : Y ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e (e y z)) = y
H: Univalence Z, W: BAut Bool e: pt ** Z ** W z: Z y: pt
(letp := path_baut_bool_inhab W (e y z) inmatch
p in (_ = b) return (pt ** Z ** b -> b -> pt)
with
| 1 =>
fun (e : pt ** Z ** pt) (w : pt) =>
letp0 := path_baut_bool_inhab Z z inmatch
p0 in (_ = b) return (pt ** b ** pt -> b -> pt)
with
| 1 =>
fun (e0 : pt ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e (e y z)) = y
(letp := path_baut_bool_inhab W (e y z) inmatch
p in (_ = b) return (pt ** pt ** b -> b -> pt)
with
| 1 =>
fun (e : pt ** pt ** pt) (w : pt) =>
letp0 := 1inmatch
p0 in (_ = b) return (pt ** b ** pt -> b -> pt)
with
| 1 =>
fun (e0 : pt ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e (e y z)) = y
H: Univalence e: pt ** pt ** pt z, y: pt
(letp := 1inmatch
p in (_ = b) return (pt ** pt ** b -> b -> pt)
with
| 1 =>
fun (e : pt ** pt ** pt) (w : pt) =>
letp0 := 1inmatch
p0 in (_ = b) return (pt ** b ** pt -> b -> pt)
with
| 1 =>
fun (e0 : pt ** pt ** pt) (z : pt) =>
lets := dec (z = w) inmatch s with
| inl _ => e0^-11%equiv
| inr _ => e0^-1 equiv_negb
endend e z
end e (e y z)) = y
H: Univalence e: pt ** pt ** pt z, y: pt
match dec (z = e y z) with
| inl _ => e^-11%equiv
| inr _ => e^-1 equiv_negb
end = y
H: Univalence e: pt ** pt ** pt z, y: pt p: z = e y z q: e y = 1%equiv
1%equiv = e y
H: Univalence e: pt ** pt ** pt z, y: pt p: z = e y z q: e y = equiv_negb
1%equiv = e y
H: Univalence e: pt ** pt ** pt z, y: pt p: z <> e y z q: e y = 1%equiv
equiv_negb = e y
H: Univalence e: pt ** pt ** pt z, y: pt p: z <> e y z q: e y = equiv_negb
equiv_negb = e y
H: Univalence e: pt ** pt ** pt z, y: pt p: z = e y z q: e y = 1%equiv
1%equiv = e y
symmetry; assumption.
H: Univalence e: pt ** pt ** pt z, y: pt p: z = e y z q: e y = equiv_negb
1%equiv = e y
case (not_fixed_negb z (p @ ap10_equiv q z)^).
H: Univalence e: pt ** pt ** pt z, y: pt p: z <> e y z q: e y = 1%equiv
equiv_negb = e y
case (p (ap10_equiv q z)^).
H: Univalence e: pt ** pt ** pt z, y: pt p: z <> e y z q: e y = equiv_negb
equiv_negb = e y
symmetry; assumption.Defined.
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W
merely Y -> Z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W
merely Y -> Z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W k:= funy : Y => (e y)^-1 (f y): Y -> Z
merely Y -> Z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W k:= funy : Y => (e y)^-1 (f y): Y -> Z y1, y2: Y
k y1 = k y2
H: Univalence Z, W: BAut Bool e: pt ** Z ** W f: pt ** W k:= funy : pt => (e y)^-1 (f y): pt -> Z y1, y2: pt
k y1 = k y2
H: Univalence Z: BAut Bool e: pt ** Z ** pt f: pt ** pt k:= funy : pt => (e y)^-1 (f y): pt -> Z y1, y2: pt
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W
Z
exact (baut_bool_pairing_ZZ_Z_symm_lemma e f
(merely_inhab_baut_bool Y)).
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W
baut_bool_pairing_ZZ_Z_symm_part1 e
o (funf : Y ** W =>
baut_bool_pairing_ZZ_Z_symm_lemma e f
(merely_inhab_baut_bool Y)) == idmap
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W
baut_bool_pairing_ZZ_Z_symm_part1 e
(baut_bool_pairing_ZZ_Z_symm_lemma e f
(merely_inhab_baut_bool Y)) = f
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W y: Y
baut_bool_pairing_ZZ_Z_symm_part1 e
(baut_bool_pairing_ZZ_Z_symm_lemma e f
(merely_inhab_baut_bool Y)) y = f y
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W y: Y
e y
(baut_bool_pairing_ZZ_Z_symm_lemma e f
(merely_inhab_baut_bool Y)) = f y
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W y: Y
e y (baut_bool_pairing_ZZ_Z_symm_lemma e f (tr y)) =
f y
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W f: Y ** W y: Y
e y (baut_bool_pairing_ZZ_Z_symm_lemma e f (tr y)) =
f y
apply eisretr.
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W
(funf : Y ** W =>
baut_bool_pairing_ZZ_Z_symm_lemma e f
(merely_inhab_baut_bool Y))
o baut_bool_pairing_ZZ_Z_symm_part1 e == idmap
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z
baut_bool_pairing_ZZ_Z_symm_lemma e
(baut_bool_pairing_ZZ_Z_symm_part1 e z)
(merely_inhab_baut_bool Y) = z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z X: IsHSet Z
baut_bool_pairing_ZZ_Z_symm_lemma e
(baut_bool_pairing_ZZ_Z_symm_part1 e z)
(merely_inhab_baut_bool Y) = z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z X: IsHSet Z y: Y
baut_bool_pairing_ZZ_Z_symm_lemma e
(baut_bool_pairing_ZZ_Z_symm_part1 e z)
(merely_inhab_baut_bool Y) = z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z X: IsHSet Z y: Y
baut_bool_pairing_ZZ_Z_symm_lemma e
(baut_bool_pairing_ZZ_Z_symm_part1 e z) (tr y) = z
H: Univalence Y, Z, W: BAut Bool e: Y ** Z ** W z: Z X: IsHSet Z y: Y
baut_bool_pairing_ZZ_Z_symm_lemma e
(baut_bool_pairing_ZZ_Z_symm_part1 e z) (tr y) = z
exact (eissect _ _).Defined.
H: Univalence Y, Z, W: BAut Bool
baut_bool_pairing_ZZ_Z_symm_map Y Z W
o baut_bool_pairing_ZZ_Z_symm_map Z Y W == idmap
H: Univalence Y, Z, W: BAut Bool
baut_bool_pairing_ZZ_Z_symm_map Y Z W
o baut_bool_pairing_ZZ_Z_symm_map Z Y W == idmap
H: Univalence Y, Z, W: BAut Bool e: Z ** Y ** W
baut_bool_pairing_ZZ_Z_symm_map Y Z W
(baut_bool_pairing_ZZ_Z_symm_map Z Y W e) = e
H: Univalence Y, Z, W: BAut Bool e: Z ** Y ** W z: Z
baut_bool_pairing_ZZ_Z_symm_map Y Z W
(baut_bool_pairing_ZZ_Z_symm_map Z Y W e) z = e z
H: Univalence Y, Z, W: BAut Bool e: Z ** Y ** W z: Z y: Y
baut_bool_pairing_ZZ_Z_symm_map Y Z W
(baut_bool_pairing_ZZ_Z_symm_map Z Y W e) z y =
e z y
reflexivity.Defined.
H: Univalence Y, Z, W: BAut Bool
Y ** Z ** W <~> Z ** Y ** W
H: Univalence Y, Z, W: BAut Bool
Y ** Z ** W <~> Z ** Y ** W
exact (equiv_adjointify
(baut_bool_pairing_ZZ_Z_symm_map Y Z W)
(baut_bool_pairing_ZZ_Z_symm_map Z Y W)
(baut_bool_pairing_ZZ_Z_symm_inv Y Z W)
(baut_bool_pairing_ZZ_Z_symm_inv Z Y W)).Defined.(** Finally, we can prove associativity. *)
H: Univalence Z, W, Y: BAut Bool
(Z ** W) ** Y = Z ** W ** Y
H: Univalence Z, W, Y: BAut Bool
(Z ** W) ** Y = Z ** W ** Y
H: Univalence Z, W, Y: BAut Bool
Y ** Z ** W = Z ** W ** Y
H: Univalence Z, W, Y: BAut Bool
Y ** Z ** W = Z ** Y ** W
apply path_baut, baut_bool_pairing_ZZ_Z_symm.Defined.(** Since [BAut Bool] is not a set, we ought to have some coherence for these operations too, but we'll leave that for another time. *)(** ** Automorphisms of [BAut Bool] *)(** Interestingly, like [Bool] itself, [BAut Bool] is equivalent to its own automorphism group. *)(** An initial lemma: every automorphism of [BAut Bool] and its inverse are "adjoint" with respect to the pairing. *)
(fune : BAut Bool <~> BAut Bool => e^-1 pt)
o (funZ : BAut Bool =>
equiv_involution (funW : BAut Bool => Z ** W)
((funW : BAut Bool =>
(baut_bool_pairing_ZZ_Z Z Z W)^ @
(ap (funY : BAut Bool => Y ** W)
(baut_bool_pairing_ZZ Z) @
baut_bool_pairing_1Z W))
:
(funx : BAut Bool => Z ** Z ** x) == idmap)) ==
idmap
H: Univalence Z: BAut Bool
(equiv_involution (funW : BAut Bool => Z ** W)
(funW : BAut Bool =>
(baut_bool_pairing_ZZ_Z Z Z W)^ @
(ap (funY : BAut Bool => Y ** W)
(baut_bool_pairing_ZZ Z) @
baut_bool_pairing_1Z W)))^-1 pt = Z
apply baut_bool_pairing_Z1.Defined.(** ** [BAut (BAut Bool)] *)(** Putting all of this together, we can construct a nontrivial 2-central element of [BAut (BAut Bool)]. *)