I am trying to fill the remaining one hole in the following program:
{-# OPTIONS --cubical #-}
module _ where
open import Cubical.Core.Everything
open import Cubical.Foundations.Everything
data S1 : Type where
base : S1
loop : base ≡ base
data NS : Type where
N : NS
S : NS
W : S ≡ N
E : N ≡ S
module _ where
open Iso
NS-Iso : Iso NS S1
NS-Iso .fun N = base
NS-Iso .fun S = base
NS-Iso .fun (W i) = base
NS-Iso .fun (E i) = loop i
NS-Iso .inv base = N
NS-Iso .inv (loop i) = (E ∙ W) i
NS-Iso .leftInv N = refl
NS-Iso .leftInv S = sym W
NS-Iso .leftInv (W i) = λ j → W (i ∨ ~ j)
NS-Iso .leftInv (E i) = λ j → compPath-filler E W (~ j) i
NS-Iso .rightInv base = refl
NS-Iso .rightInv (loop i) = ?
The type of the hole is:
fun NS-Iso (inv NS-Iso (loop i)) ≡ loop i
inv NS-Iso (loop i) of course definitionally equal to (E ∙ W) i, but what is then fun NS-Iso ((E ∙ W) i)? Is there some kind of homomorphism / continuity / similar property with which I can use the definitions of fun NS-Iso (E i) and fun NS-Iso (W i) to figure out what it is?
Since fun NS-Iso (E i) = loop i and fun NS-Iso (W i) = base, I thought this might be a valid filling (pun intended) of the hole:
NS-Iso .rightInv (loop i) = λ j → compPath-filler loop (refl {x = base}) (~ j) i
But that gives a type error:
hcomp (doubleComp-faces (λ _ → base) (λ _ → base) i) (loop i)
!=
fun NS-Iso (hcomp (doubleComp-faces (λ _ → N) W i) (E i))
I have found that the answer is, basically, yes!
Let's add a local binding of our goal in
NS-Iso .rightInv (loop i)just to keep an eye on the type:Since we have
the type of
goalreduces to:And now comes the crucial step, the actual answer to my question: can we push in
fun NS-IsointoE ∙ W?Let's draw wavy lines between the points and paths where
fun NS-Isois directly defined, or where we know its value bycong _ refl = refl:E ∙ Wis the lid of the inner box, and it turns out yes, its image byfun NS-Isois indeed the lid of the outer box:In graphical form:
So we can reduce the
fun NS-Isoapplications now:which we can finally solve with a library function
doubleCompPath-filler.The complete code:
I don't know why I needed to eta-expand
goalandstep1, but otherwise Agda doesn't recognize that they meet the boundary conditions.