{-# OPTIONS --warning=error --safe --without-K #-} open import LogicalFormulae open import Functions open import Lists.Lists open import Numbers.Naturals.Semiring open import Numbers.Naturals.Order 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 NToBinNatZero : (n : ℕ) → NToBinNat n ≡ [] → n ≡ 0 NToBinNatZero zero pr = refl NToBinNatZero (succ n) pr with NToBinNat n NToBinNatZero (succ n) pr | zero :: bl = exFalso (nonEmptyNotEmpty pr) NToBinNatZero (succ n) pr | one :: bl = exFalso (nonEmptyNotEmpty pr) canonicalAscends : {i : Bit} → (a : BinNat) → 0