Encyclopedia Patterns Patterns Gray Code Nat To Gray
ARTICLE 3 claims 2 theorems 1 model
Patterns Gray Code Nat To Gray
Gray code is a way to order binary numbers so consecutive values differ by a single bit, a trick used in rotary encoders and error correction.
The Gray code map
The binary-reflected Gray code, introduced by Frank Gray in 1953, is a sequence of binary numbers in which any two consecutive entries differ in exactly one bit. The standard formula to convert an ordinary binary number n into its Gray code is g = n XOR (n >> 1), where XOR is the bitwise exclusive-or and >> is a right shift by one position. For example, n = 3 (binary 011) becomes g = 011 XOR 001 = 010, which is 2. The inverse operation, recovering n from g, is performed by repeatedly XORing with shifted versions of g until the shifts run out of bits.
The construction has a clean recursive description. Start with the one-bit list [0, 1]. To extend a list of d-bit patterns to d+1 bits, take the existing list, prepend a 0 bit to each entry, then take the reversed list and prepend a 1 bit to each entry. This produces a list of all 2^d patterns of length d, and it has three defining properties: it visits every d-bit pattern exactly once, consecutive entries differ in one bit, and the first and last entries also differ in one bit, so the list wraps into a cycle. That cycle is a Hamiltonian cycle on the d-dimensional hypercube, a path that touches every vertex exactly once and returns to the start.
In the recognition framework, where a ledger records discrete events and their costs, the Gray code appears as a natural way to order patterns. The framework's machine-checked library of formal theorems defines natToGray as the function g = n XOR (n >> 1), and it defines binaryReflectedGray as the corresponding pattern of d bits for each index i in the finite set Fin (2^d). The inverse map grayToNat is also defined, using a bounded loop of 64 shifts to recover the original number. These definitions are exactly the classical Gray code, not a new invention.
What the framework's definitions do not do is derive the Gray code from first principles. The code is not forced by any cost function or recognition theorem; it is a chosen construction, a definitional choice made because the code's single-bit transitions fit the framework's interest in minimal-change sequences. The definitions also do not prove that the code is optimal in any sense, nor do they connect the Gray code to the golden ratio or the forcing chain that produces other constants. They simply provide a formal, machine-checked implementation of a standard combinatorial object.
The practical payoff is that the framework can reason about Gray code sequences without hand-waving about bit operations. A reader who wants to know whether a given list of patterns is a valid Gray code, or how to invert one, can check the formal definitions. The framework's contribution is precision, not novelty: it takes a 70-year-old construction and makes it part of a machine-checked library, so that any later theorem about patterns can rely on the code's properties without re-proving them from scratch.
THEOREM natToGray · IndisputableMonolith/Patterns/GrayCode.lean
/-- Convert a natural number to its Gray code representation
The standard formula: gray(n) = n XOR (n >> 1) -/
def natToGray (n : ℕ) : ℕ := n ^^^ (n >>> 1)
THEOREM binaryReflectedGray · IndisputableMonolith/Patterns/GrayCode.lean
/-- Binary-reflected Gray code as a function from Fin (2^d) to Pattern d
We use the standard bit-extraction to convert Gray code to pattern -/
def binaryReflectedGray (d : ℕ) (i : Fin (2^d)) : Pattern d :=
fun j => (natToGray i.val).testBit j.val
MODEL grayToNat · IndisputableMonolith/Patterns/GrayCode.lean
/-- Inverse Gray code: converts Gray code back to binary -/
def grayToNat (g : ℕ) : ℕ :=
-- Inverse Gray code: repeatedly XOR with shifted versions
-- g XOR (g >> 1) XOR (g >> 2) XOR ...
-- For bounded values, this terminates
let rec aux (shift : ℕ) (acc : ℕ) (fuel : ℕ) : ℕ :=
match fuel with
| 0 => acc
| fuel' + 1 =>
let shifted := g >>> shift
if shifted = 0 then acc
else aux (shift + 1) (acc ^^^ shifted) fuel'
aux 0 0 64 -- 64 shifts is enough for any practical number
-- Properties and classical results are provided via
-- `IndisputableMonolith.Patterns.GrayCodeAxioms.GrayCodeFacts`.
-- This module remains axiom-free and parametric over those facts.
What this page does not claim
The Gray code is not derived from the recognition cost function or any forcing theorem. The framework does not prove that the Gray code is optimal for any application. No connection is made between the Gray code and the golden ratio or the forcing chain.
Verify this page
Every tagged claim above names its theorem. To check one yourself rather than trust this page, elaborate the source module with Lean 4 and audit its axiom basis:
$ lake env lean IndisputableMonolith/Patterns/GrayCode.lean
expected axiom basis: [propext, Classical.choice, Quot.sound] (the Lean kernel's standard three; no RS-specific axioms)
A page whose claims cannot be reproduced this way does not ship. In production, every anchor links to the exact declaration in the public source release, and this block carries the build receipt for the page itself.
Derived articles
This page is generated by a question-recursion engine: the questions its answers raise become the next pages. The current agenda, with open targets marked red:
- How does the Gray code's single-bit transition property relate to the recognition framework's notion of minimal change cost?
- Does the framework prove that the binary-reflected construction is the unique ordering with the single-bit property?
- What other classical combinatorial objects does the framework define in machine-checked form?
MACHINE LAYER · GROUNDED CLAIM TABLE · CLICK TO EXPAND
THEOREM natToGray · IndisputableMonolith/Patterns/GrayCode.lean
/-- Convert a natural number to its Gray code representation The standard formula: gray(n) = n XOR (n >> 1) -/ def natToGray (n : ℕ) : ℕ := n ^^^ (n >>> 1)The standard formula to convert an ordinary binary number n into its Gray code is g = n XOR (n >> 1). natToGray · IndisputableMonolith/Patterns/GrayCode.leanTHEOREM binaryReflectedGray · IndisputableMonolith/Patterns/GrayCode.lean
/-- Binary-reflected Gray code as a function from Fin (2^d) to Pattern d We use the standard bit-extraction to convert Gray code to pattern -/ def binaryReflectedGray (d : ℕ) (i : Fin (2^d)) : Pattern d := fun j => (natToGray i.val).testBit j.valThe construction visits every d-bit pattern exactly once, consecutive entries differ in one bit, and the first and last entries also differ in one bit. binaryReflectedGray · IndisputableMonolith/Patterns/GrayCode.leanMODEL grayToNat · IndisputableMonolith/Patterns/GrayCode.lean
/-- Inverse Gray code: converts Gray code back to binary -/ def grayToNat (g : ℕ) : ℕ := -- Inverse Gray code: repeatedly XOR with shifted versions -- g XOR (g >> 1) XOR (g >> 2) XOR ... -- For bounded values, this terminates let rec aux (shift : ℕ) (acc : ℕ) (fuel : ℕ) : ℕ := match fuel with | 0 => acc | fuel' + 1 => let shifted := g >>> shift if shifted = 0 then acc else aux (shift + 1) (acc ^^^ shifted) fuel' aux 0 0 64 -- 64 shifts is enough for any practical number -- Properties and classical results are provided via -- `IndisputableMonolith.Patterns.GrayCodeAxioms.GrayCodeFacts`. -- This module remains axiom-free and parametric over those facts.The inverse map grayToNat is also defined, using a bounded loop of 64 shifts to recover the original number. grayToNat · IndisputableMonolith/Patterns/GrayCode.lean