{-# OPTIONS --without-K #-} module Data.Nat.Log2 where import Data.Nat.Logarithm as Logarithm open import Data.Nat open import Data.Nat.Properties open import Relation.Nullary open import Relation.Binary open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl) ⌈log₂_⌉ : ℕ → ℕ ⌈log₂_⌉ = Logarithm.⌈log₂_⌉ log₂-mono : ⌈log₂_⌉ Preserves _≤_ ⟶ _≤_ log₂-mono = Logarithm.⌈log₂⌉-mono-≤ ⌈log₂n⌉≤n : ∀ n → ⌈log₂ n ⌉ ≤ n ⌈log₂n⌉≤n n = let open ≤-Reasoning in begin ⌈log₂ n ⌉ ≤⟨ Logarithm.⌈log₂⌉-mono-≤ (n≤2^n n) ⟩ ⌈log₂ (2 ^ n) ⌉ ≡⟨ Logarithm.⌈log₂2^n⌉≡n n ⟩ n ∎ where n≤2^n : (n : ℕ) → n ≤ 2 ^ n n≤2^n zero = z≤n n≤2^n (suc n) = let open ≤-Reasoning in begin 1 + n ≤⟨ +-mono-≤ (^-monoʳ-≤ 2 (z≤n {n})) (n≤2^n n) ⟩ 2 ^ n + 2 ^ n ≡˘⟨ Eq.cong ((2 ^ n) +_) (+-identityʳ (2 ^ n)) ⟩ 2 ^ n + (2 ^ n + 0) ≡⟨⟩ 2 * 2 ^ n ∎ log₂-suc : ∀ n {k} → ⌈log₂ n ⌉ ≤ suc k → ⌈log₂ ⌈ n /2⌉ ⌉ ≤ k log₂-suc n {k} h = let open ≤-Reasoning in begin ⌈log₂ ⌈ n /2⌉ ⌉ ≡⟨ Logarithm.⌈log₂⌈n/2⌉⌉≡⌈log₂n⌉∸1 n ⟩ pred ⌈log₂ n ⌉ ≤⟨ ∸-monoˡ-≤ 1 h ⟩ k ∎ ⌈log₂n⌉≡0⇒n≤1 : {n : ℕ} → ⌈log₂ n ⌉ ≡ 0 → n ≤ 1 ⌈log₂n⌉≡0⇒n≤1 {zero} refl = z≤n ⌈log₂n⌉≡0⇒n≤1 {suc zero} refl = s≤s z≤n