module 1Lab.Path.Reasoning where

Reasoning combinators for path spacesπŸ”—

Identity pathsπŸ”—

βˆ™-id-comm : p βˆ™ refl ≑ refl βˆ™ p
βˆ™-id-comm {p = p} i j =
  hcomp (βˆ‚ i ∨ βˆ‚ j) Ξ» where
    k (i = i0) β†’ βˆ™-filler p refl k j
    k (i = i1) β†’ βˆ™-filler'' refl p j k
    k (j = i0) β†’ p i0
    k (j = i1) β†’ p (~ i ∨ k)
    k (k = i0) β†’ (p (~ i ∧ j))

module _ (p≑refl : p ≑ refl) where opaque
  βˆ™-eliml : p βˆ™ q ≑ q
  βˆ™-eliml {q = q} = sym $ paste (ap sym p≑refl) refl refl refl (βˆ™-filler' p q)

  βˆ™-elimr : q βˆ™ p ≑ q
  βˆ™-elimr {q = q} = sym $ paste refl refl refl p≑refl (βˆ™-filler q p)

  βˆ™-introl : q ≑ p βˆ™ q
  βˆ™-introl = sym βˆ™-eliml

  βˆ™-intror : q ≑ q βˆ™ p
  βˆ™-intror = sym βˆ™-elimr

ReassocationsπŸ”—

We often find ourselves in situations where we have an equality involving the composition of 2 morphisms, but the association is a bit off. These combinators aim to address that situation.

module _ (pq≑s : p βˆ™ q ≑ s) where
  βˆ™-pulll : p βˆ™ q βˆ™ r ≑ s βˆ™ r
  βˆ™-pulll {r = r} = βˆ™-assoc p q r βˆ™ ap (_βˆ™ r) pq≑s

  double-left : p Β·Β· q Β·Β· r ≑ s βˆ™ r
  double-left {r = r} = double-composite p q r βˆ™ βˆ™-pulll

  βˆ™-pullr : (r βˆ™ p) βˆ™ q ≑ r βˆ™ s
  βˆ™-pullr {r = r} = sym (βˆ™-assoc r p q) βˆ™ ap (r βˆ™_) pq≑s

  βˆ™-swapl : q ≑ sym p βˆ™ s
  βˆ™-swapl = βˆ™-introl (βˆ™-invl p) βˆ™ βˆ™-pullr

  βˆ™-swapr : p ≑ s βˆ™ sym q
  βˆ™-swapr = βˆ™-intror (βˆ™-invr q) βˆ™ βˆ™-pulll

module _ (s≑pq : s ≑ p βˆ™ q) where
  βˆ™-pushl : s βˆ™ r ≑ p βˆ™ q βˆ™ r
  βˆ™-pushl = sym (βˆ™-pulll (sym s≑pq))

  βˆ™-pushr : r βˆ™ s ≑ (r βˆ™ p) βˆ™ q
  βˆ™-pushr = sym (βˆ™-pullr (sym s≑pq))

  βˆ™β†’square : Square refl p s q
  βˆ™β†’square = βˆ™-filler p q β–· sym s≑pq

  βˆ™β†’square' : Square (sym p) q s refl
  βˆ™β†’square' = βˆ™-filler' p q β–· sym s≑pq

  βˆ™β†’square'' : Square (sym p) refl s q
  βˆ™β†’square'' = transpose (βˆ™-filler'' p q) β–· sym s≑pq

module _ (pq≑rs : p βˆ™ q ≑ r βˆ™ s) where
  βˆ™-extendl : p βˆ™ (q βˆ™ t) ≑ r βˆ™ (s βˆ™ t)
  βˆ™-extendl {t = t} = βˆ™-assoc _ _ _ Β·Β· ap (_βˆ™ t) pq≑rs Β·Β· sym (βˆ™-assoc _ _ _)

  βˆ™-extendr : (t βˆ™ p) βˆ™ q ≑ (t βˆ™ r) βˆ™ s
  βˆ™-extendr {t = t} = sym (βˆ™-assoc _ _ _) Β·Β· ap (t βˆ™_) pq≑rs Β·Β· βˆ™-assoc _ _ _

Β·Β·-stack : (sym p' Β·Β· (sym p Β·Β· q Β·Β· r) Β·Β· r') ≑ (sym (p βˆ™ p') Β·Β· q Β·Β· (r βˆ™ r'))
Β·Β·-stack = Β·Β·-unique' (Β·Β·-filler _ _ _ βˆ™β‚‚ Β·Β·-filler _ _ _)

Β·Β·-chain : (sym p Β·Β· q Β·Β· r) βˆ™ (sym r Β·Β· q' Β·Β· s) ≑ sym p Β·Β· (q βˆ™ q') Β·Β· s
Β·Β·-chain {p = p} {q = q} {r = r} {q' = q'} {s = s} = sym (βˆ™-unique _ square) where
  square : Square refl (sym p Β·Β· q Β·Β· r) (sym p Β·Β· (q βˆ™ q') Β·Β· s) (sym r Β·Β· q' Β·Β· s)
  square i j = hcomp (~ j ∨ (j ∧ (i ∨ ~ i))) λ where
    k (k = i0) β†’ βˆ™-filler q q' i j
    k (j = i0) β†’ p k
    k (j = i1) (i = i0) β†’ r k
    k (j = i1) (i = i1) β†’ s k

Β·Β·-βˆ™-assoc : p Β·Β· q Β·Β· (r βˆ™ s) ≑ (p Β·Β· q Β·Β· r) βˆ™ s
Β·Β·-βˆ™-assoc {p = p} {q = q} {r = r} {s = s} = sym (Β·Β·-unique' square) where
  square : Square (sym p) q ((p Β·Β· q Β·Β· r) βˆ™ s) (r βˆ™ s)
  square i j = hcomp (~ i ∨ ~ j ∨ (i ∧ j)) λ where
    k (k = i0) β†’ Β·Β·-filler p q r i j
    k (i = i0) β†’ q j
    k (j = i0) β†’ p (~ i)
    k (i = i1) (j = i1) β†’ s k

CancellationπŸ”—

These lemmas do 2 things at once: rearrange parenthesis, and also remove things that are equal to id.

module _ (inv : p βˆ™ q ≑ refl) where abstract
  βˆ™-cancelsl : p βˆ™ (q βˆ™ r) ≑ r
  βˆ™-cancelsl = βˆ™-pulll inv βˆ™ βˆ™-idl _

  βˆ™-cancelsr : (r βˆ™ p) βˆ™ q ≑ r
  βˆ™-cancelsr = βˆ™-pullr inv βˆ™ βˆ™-idr _

  βˆ™-insertl : r ≑ p βˆ™ (q βˆ™ r)
  βˆ™-insertl = sym βˆ™-cancelsl

  βˆ™-insertr : r ≑ (r βˆ™ p) βˆ™ q
  βˆ™-insertr = sym βˆ™-cancelsr

NotationπŸ”—

When doing equational reasoning, it’s often somewhat clumsy to have to write ap (f βˆ™_) p when proving that f βˆ™ g ≑ f βˆ™ h. To fix this, we steal some cute mixfix notation from agda-categories which allows us to write β‰‘βŸ¨ reflβŸ©βˆ™βŸ¨ p ⟩ instead, which is much more aesthetically pleasing!

_βŸ©βˆ™βŸ¨_ : p ≑ q β†’ r ≑ s β†’ p βˆ™ r ≑ q βˆ™ s
_βŸ©βˆ™βŸ¨_ p q i = p i βˆ™ q i

reflβŸ©βˆ™βŸ¨_ : p ≑ q β†’ r βˆ™ p ≑ r βˆ™ q
reflβŸ©βˆ™βŸ¨_ {r = r} p = ap (r βˆ™_) p

_βŸ©βˆ™βŸ¨refl : p ≑ q β†’ p βˆ™ r ≑ q βˆ™ r
_βŸ©βˆ™βŸ¨refl {r = r} p = ap (_βˆ™ r) p