A self-delimiting binary code for natural numbers #
The prefix-free code used by the machine-description format
(planning/tm-infrastructure.md, Milestone C, normative):
encodeNat n = 1^L 0 d₀ … d_{L-1}
where d₀ … d_{L-1} are the little-endian binary digits of n (Turing.natToBits;
canonical: the empty string for 0, and the last digit of a nonzero number is true)
and L is their count. So encodeNat 0 = [false], and in general
(encodeNat n).length = 2·L + 1 with L = ⌈log₂ (n+1)⌉, characterized here without
Nat.log2 by lt_two_pow_natToBits and natToBits_length_le.
The parser parseNat accepts only canonical digit strings (a digit block ending in
false is rejected), which gives genuine canonicality: parseNat_sound says every
accepted prefix is encodeNat of the parsed value. Together with the prefix property
parseNat_encodeNat, all downstream codec soundness proofs are compositional
(decision D11).
Everything is structurally recursive — natToBits runs on an explicit fuel, with a
fuel-irrelevance lemma — so the kernel can evaluate the whole codec and tests can be
by decide (decision D10).
Little-endian binary digits #
Little-endian binary digits, structurally recursive in an explicit fuel (so that the
kernel can evaluate it); use Turing.natToBits, which instantiates the fuel.
Equations
- Turing.natToBitsAux x✝ 0 = []
- Turing.natToBitsAux 0 n.succ = []
- Turing.natToBitsAux fuel.succ n.succ = ((n + 1) % 2 == 1) :: Turing.natToBitsAux fuel ((n + 1) / 2)
Instances For
The little-endian binary digits of a natural number: [] for 0; the last digit of
a nonzero number is true.
Equations
Instances For
The digits do not depend on the fuel, as long as there is enough of it.
The length of the digit string #
The self-delimiting code #
The self-delimiting code of a natural number: the digit count in unary, a false
separator, then the digits.