{-# OPTIONS --safe #-}
module Data.Binary.Skew where
open import Prelude
open import Data.Nat
open import Data.List
πΉ : Type
πΉ = List β
inc : πΉ β πΉ
inc [] = zero β· []
inc (x β· []) = zero β· x β· []
inc (xβ β· zero β· xs) = suc xβ β· xs
inc (xβ β· suc xβ β· xs) = zero β· xβ β· xβ β· xs
β¦_ββ§ : β β πΉ
β¦ zero ββ§ = []
β¦ suc n ββ§ = inc β¦ n ββ§
2Γ_ : β β β
2Γ n = n + n
infixr 5 1πβ·_ 1πβ―_β·_
1πβ·_ : β β β
1πβ· n = 1 + 2Γ n
1πβ―_β·_ : β β β β β
1πβ― zero β· a = a
1πβ― suc n β· a = 1πβ· 1πβ― n β· a
β¦β·_ββ§^ : (β β β) β β β β
β¦β· xs ββ§^ aβ² = aβ² + xs (1πβ· aβ²)
β¦_β·_ββ§^ : β β (β β β) β β β β
β¦ x β· xs ββ§^ a = β¦β· xs ββ§^ (1πβ― x β· a)
β¦_ββ§β² : πΉ β β β β
β¦ [] ββ§β² = const 0
β¦ x β· xs ββ§β² = β¦ x β· β¦ xs ββ§β² ββ§^
β¦_ββ§ : πΉ β β
β¦ [] ββ§ = zero
β¦ x β· xs ββ§ = let a = 1πβ― x β· 1 in a + β¦ xs ββ§β² a
open import Path.Reasoning
import Data.Nat.Properties as β
1π-distrib : β n x β 1πβ― n β· 1πβ· x β‘ 1πβ― suc n β· x
1π-distrib zero x = refl
1π-distrib (suc n) x = cong 1πβ·_ (1π-distrib n x)
inc-suc : β x β β¦ inc x ββ§ β‘ suc β¦ x ββ§
inc-suc [] = refl
inc-suc (x β· []) = refl
inc-suc (x β· zero β· xs) = cong suc (β.+-assoc (1πβ― x β· 1) (1πβ― x β· 1) _)
inc-suc (xβ β· suc xβ β· xs) = cong (suc β ((1πβ― xβ β· 1) +_) β β¦β· β¦ xs ββ§β² ββ§^) (1π-distrib xβ (1πβ― xβ β· 1))
πΉ-rightInv : β x β β¦ β¦ x ββ§ ββ§ β‘ x
πΉ-rightInv zero = refl
πΉ-rightInv (suc x) = inc-suc β¦ x ββ§ ΝΎ cong suc (πΉ-rightInv x)