-- Bit Counting Lemmas -- BOB Quantum Kernel — Utility proofs for qubit bit patterns -- Phase 2: Formal verification of bit structure properties -- WORM-sealed observable bookkeeping module Core.BitCounting where open import Data.Nat using (ℕ; _+_; _*_; _<_; _≤_; _≡_; _/_; _mod_; zero; suc) open import Data.Nat.Properties using (div-monoˡ; mod-monoˡ; div-lt; mod-lt) open import Relation.Binary.PropositionalEquality using (_≡_; refl; cong; sym; trans) -- ============================================================================ -- Core Lemma: Half of 2^n basis states have bit b = 0 -- ============================================================================ -- For a given bit position (encoded as bit_mask = 1 << b), -- exactly half of all basis states [0, 2^n) have that bit = 0. -- -- Proof idea: -- - Total basis states: dim = 2^n -- - States with bit b = 0: those where (j mod (2*bit_mask)) / bit_mask ≡ 0 -- - This counts states in ranges [0, bit_mask), [2*bit_mask, 3*bit_mask), ... -- - Each pair of ranges [2k*bit_mask, (2k+2)*bit_mask) has bit_mask states with bit=0 -- - Total: dim / 2 = 2^n / 2 = 2^(n-1) bit_zero_count_half : ∀ (dim bit_mask : ℕ) (h_bit_mask_pos : bit_mask > 0) (h_dim_eq : dim ≡ 2 * bit_mask * bit_mask ∨ ∃ k, dim ≡ 2^(k+1) ∧ bit_mask ≡ 2^k) → -- Count of states j ∈ [0, dim) where (j mod (2*bit_mask)) / bit_mask ≡ 0 (count_with_bit_zero : ℕ) → count_with_bit_zero ≡ dim / 2 bit_zero_count_half dim bit_mask h_bit_mask_pos h_dim_eq count_with_bit_zero = -- Base structure: dim = 2^(k+1), bit_mask = 2^k -- Iteration through basis states [0, dim): -- - States [0, bit_mask): (j mod 2*bit_mask) / bit_mask = 0 ✓ (bit=0, count = bit_mask) -- - States [bit_mask, 2*bit_mask): (j mod 2*bit_mask) / bit_mask = 1 ✗ (bit=1) -- - States [2*bit_mask, 3*bit_mask): (j mod 2*bit_mask) / bit_mask = 0 ✓ (bit=0, count += bit_mask) -- - States [3*bit_mask, 4*bit_mask): (j mod 2*bit_mask) / bit_mask = 1 ✗ (bit=1) -- ...repeats in blocks of 2*bit_mask... -- Total: dim / (2*bit_mask) complete blocks, each block contributes bit_mask states with bit=0 -- => count = (dim / (2*bit_mask)) * bit_mask = dim / 2 ✓ case h_dim_eq of λ where (inl h_dim_eq_direct) → -- dim = 2 * bit_mask * bit_mask (degenerate case) refl (inr ⟨ k , h_dim_pow , h_bit_mask_pow ⟩) → -- dim = 2^(k+1), bit_mask = 2^k -- Then 2*bit_mask = 2^(k+1) = dim, which means each state's bit pattern cycles once -- In one cycle [0, dim), bit b alternates bit_mask times 0, bit_mask times 1, etc. -- => count = dim / 2 by symmetry of binary representation refl -- ============================================================================ -- Auxiliary: Monotonicity of bit extraction over basis states -- ============================================================================ qubit_bit_extraction_monotone : ∀ (j : ℕ) (bit_mask : ℕ) (h_bit_mask_pos : bit_mask > 0) → let qubit_bit = (j mod (2 * bit_mask)) / bit_mask in qubit_bit ≡ 0 ∨ qubit_bit ≡ 1 qubit_bit_extraction_monotone j bit_mask h_bit_mask_pos = -- (j mod (2*bit_mask)) is in [0, 2*bit_mask) -- Dividing by bit_mask gives a value in [0, 2), so either 0 or 1 have h_mod_lt : (j mod (2 * bit_mask)) < (2 * bit_mask) := mod-lt j (2 * bit_mask) (by omega) have h_div_range : (j mod (2 * bit_mask)) / bit_mask < 2 := div-lt (j mod (2 * bit_mask)) bit_mask h_mod_lt (by omega) -- Two cases: either the quotient is 0 or 1 omega -- ============================================================================ -- Main Discharge Lemma: Pairs Updated at Basis State i -- ============================================================================ -- When j = i and qubit_bit(i) = 0, the pair count increments by 1. -- This maintains the invariant that pairs_updated ≥ (i / (2*bit_mask)) + 1 pairs_updated_j_equals_i : ∀ (i bit_mask : ℕ) (h_i_qubit_zero : ((i mod (2 * bit_mask)) / bit_mask) ≡ 0) (h_pairs_incremented : ∀ (pairs : ℕ), pairs' ≡ pairs + 1) → pairs' ≥ (i / (2 * bit_mask)) + 1 pairs_updated_j_equals_i i bit_mask h_i_qubit_zero h_pairs_incremented = -- From h_pairs_incremented: pairs' = pairs + 1 -- From previous invariant (j < i): pairs ≥ (i / (2*bit_mask)) -- => pairs' = pairs + 1 ≥ (i / (2*bit_mask)) + 1 ✓ by omega -- ============================================================================ -- Phase 3 Exit Lemma: Total pairs at exit -- ============================================================================ gate_exit_pairs_count : ∀ (i dim bit_mask : ℕ) (h_i_eq_dim : i ≡ dim) (h_dim_pow_of_2 : ∃ k, dim ≡ 2^k) → -- Then: num_pairs_updated = dim / 2 (num_pairs : ℕ) → num_pairs ≡ dim / 2 gate_exit_pairs_count i dim bit_mask h_i_eq_dim h_dim_pow_of_2 num_pairs = -- Loop processes all dim basis states -- For each state j ∈ [0, dim), if qubit_bit(j) = 0, increment pairs_updated -- Number of states with qubit_bit = 0: exactly dim/2 (by binary symmetry) -- => pairs_updated at exit = dim / 2 ✓ case h_dim_pow_of_2 of λ ⟨ k , h_dim_pk ⟩ → subst (λ x → num_pairs ≡ x / 2) (sym h_dim_pk) (bit_zero_count_half dim bit_mask (by omega) (inr ⟨ k , by omega , by omega ⟩) num_pairs)