{-# OPTIONS --warning=error --safe --without-K #-} open import LogicalFormulae open import Functions open import Lists.Lists open import Numbers.Naturals.Naturals open import Numbers.Naturals.Definition open import Groups.Definition open import Semirings.Definition open import Orders module Numbers.BinaryNaturals.Definition where data Bit : Set where zero : Bit one : Bit BinNat : Set BinNat = List Bit ::Inj : {xs ys : BinNat} {i : Bit} → i :: xs ≡ i :: ys → xs ≡ ys ::Inj {i = zero} refl = refl ::Inj {i = one} refl = refl nonEmptyNotEmpty : {a : _} {A : Set a} {l1 : List A} {i : A} → i :: l1 ≡ [] → False nonEmptyNotEmpty {l1 = l1} {i} () -- TODO - maybe we should do the floating-point style of assuming there's a leading bit and not storing it. -- That way, everything is already canonical. canonical : BinNat → BinNat canonical [] = [] canonical (zero :: n) with canonical n canonical (zero :: n) | [] = [] canonical (zero :: n) | x :: bl = zero :: x :: bl canonical (one :: n) = one :: canonical n Canonicalised : Set Canonicalised = Sg BinNat (λ i → canonical i ≡ i) binNatToN : BinNat → ℕ binNatToN [] = 0 binNatToN (zero :: b) = 2 *N binNatToN b binNatToN (one :: b) = 1 +N (2 *N binNatToN b) incr : BinNat → BinNat incr [] = one :: [] incr (zero :: n) = one :: n incr (one :: n) = zero :: (incr n) incrNonzero : (x : BinNat) → canonical (incr x) ≡ [] → False incrPreservesCanonical : (x : BinNat) → (canonical x ≡ x) → canonical (incr x) ≡ incr x incrPreservesCanonical [] pr = refl incrPreservesCanonical (zero :: xs) pr with canonical xs incrPreservesCanonical (zero :: xs) pr | x :: t = applyEquality (one ::_) (::Inj pr) incrPreservesCanonical (one :: xs) pr with inspect (canonical (incr xs)) incrPreservesCanonical (one :: xs) pr | [] with≡ x = exFalso (incrNonzero xs x) incrPreservesCanonical (one :: xs) pr | (x₁ :: y) with≡ x rewrite x = applyEquality (zero ::_) (transitivity (equalityCommutative x) (incrPreservesCanonical xs (::Inj pr))) incrPreservesCanonical' : (x : BinNat) → canonical (incr x) ≡ incr (canonical x) incrC : Canonicalised → Canonicalised incrC (a , b) = incr a , incrPreservesCanonical a b NToBinNat : ℕ → BinNat NToBinNat zero = [] NToBinNat (succ n) with NToBinNat n NToBinNat (succ n) | t = incr t NToBinNatC : ℕ → Canonicalised NToBinNatC zero = [] , refl NToBinNatC (succ n) = incrC (NToBinNatC n) incrInj : {x y : BinNat} → incr x ≡ incr y → canonical x ≡ canonical y incrNonzero' : (x : BinNat) → (incr x) ≡ [] → False incrNonzero' (zero :: xs) () incrNonzero' (one :: xs) () canonicalRespectsIncr' : {x y : BinNat} → canonical (incr x) ≡ canonical (incr y) → canonical x ≡ canonical y binNatToNSucc : (n : BinNat) → binNatToN (incr n) ≡ succ (binNatToN n) NToBinNatSucc : (n : ℕ) → incr (NToBinNat n) ≡ NToBinNat (succ n) binNatToNZero : (x : BinNat) → binNatToN x ≡ 0 → canonical x ≡ [] binNatToNZero' : (x : BinNat) → canonical x ≡ [] → binNatToN x ≡ 0 canonicalAscends : {i : Bit} → (a : BinNat) → 0