module Algebra.Monoid.Reasoning {β„“} (M : Monoid β„“) where

Reasoning combinators for monoidsπŸ”—

id-comm : a * 1m ≑ 1m * a
id-comm = idr βˆ™ sym idl

id-comm-sym : 1m * a ≑ a * 1m
id-comm-sym = idl βˆ™ sym idr

module _ (p : x ≑ 1m) where
  eliml : x * a ≑ a
  eliml = apβ‚‚ _*_ p refl βˆ™ idl

  elimr : a * x ≑ a
  elimr = apβ‚‚ _*_ refl p βˆ™ idr

  introl : a ≑ x * a
  introl = sym eliml

  intror : a ≑ a * x
  intror = sym elimr

module _ (p : x * y ≑ z) where
  pulll : x * (y * a) ≑ z * a
  pulll = associative βˆ™ apβ‚‚ _*_ p refl

  pullr : (a * x) * y ≑ a * z
  pullr = sym associative βˆ™ apβ‚‚ _*_ refl p

module _ (p : z ≑ x * y) where
  pushl : z * a ≑ x * (y * a)
  pushl = sym (pulll (sym p))

  pushr : a * z ≑ (a * x) * y
  pushr = sym (pullr (sym p))

module _ (p : w * x ≑ y * z) where
  extendl : w * (x * a) ≑ y * (z * a)
  extendl = pulll refl βˆ™ apβ‚‚ _*_ p refl βˆ™ pullr refl

  extendr : (a * w) * x ≑ (a * y) * z
  extendr = pullr refl βˆ™ apβ‚‚ _*_ refl p βˆ™ pulll refl

module _ (p : x * y ≑ 1m) where
  cancell : x * (y * a) ≑ a
  cancell = pulll p βˆ™ idl

  cancelr : (a * x) * y ≑ a
  cancelr = pullr p βˆ™ idr

  insertl : a ≑ x * (y * a)
  insertl = sym cancell

  insertr : a ≑ (a * x) * y
  insertr = sym cancelr

lswizzle : g ≑ h * i β†’ f * h ≑ 1m β†’ f * g ≑ i
lswizzle p q = apβ‚‚ _*_ refl p βˆ™ cancell q

rswizzle : g ≑ i * h β†’ h * f ≑ 1m β†’ g * f ≑ i
rswizzle p q = apβ‚‚ _*_ p refl βˆ™ cancelr q

swizzle : f * g ≑ h * i β†’ g * g' ≑ 1m β†’ h' * h ≑ 1m β†’ h' * f ≑ i * g'
swizzle p q r = lswizzle (sym (associative βˆ™ rswizzle (sym p) q)) r