Algorithm: Carryless Pairing

1Navigation 2Abstract 3Notes and References 4Realization via JavaScript 5Group Transformations 6Algorithmic Display

Abstract

A pairing function takes two natural numbers $x$ and $y$ and returns a single natural number from which both can be recovered. The construction here works in the Fibonacci basis: each input is written as a sum of distinct, non-consecutive Fibonacci numbers (its Zeckendorf support), and the two supports are placed on disjoint even and offset odd index bands. Because the bands cannot overlap, the encoding and its inverse use only addition and bounded search, never a carry.

Key materials:

  • Repository A001 (Rocq) GitHub
  • Main paper arXiv
  • A subsequent specialization by Dr. Zoltán Sóstai adapts the present mechanism for a linear-size existential encoding; arXiv.

Secondary literature and prerequisites for comprehension:

  • Fibonacci and Lucas Numbers DOI
  • Boolos, Burgess, Jeffrey: Computability and Logic DOI
  • On “Zeckendorf's Theorem” Wikipedia

We first describe a mechanism, then turn it into a pairing function.

(i) A chosen collection of Fibonacci numbers is added together into a single value. (ii) The list of chosen indices is then discarded, and only the resulting sum is handed to a Greedy Algorithm. (iii) From that sum alone, the original collection of indices is reconstructed in a bounded number of steps arithmetically.

This round trip, from an arbitrary input to its canonical additive form and back, relies on Binet’s Formula, Hurwitz’s Theorem, and Zeckendorf’s Theorem. Together they yield a stable, reversible, and fully bounded encoding-decoding scheme.

(iv) The same machinery yields a constructive, and therefore injective, arithmetical pairing function. Writing $Z(n)$ for the set of Zeckendorf indices of $n$, we set $Z(0):=\varnothing$ and let $x, y \in \mathbb{N}$:

For $x,y\in\mathbb{N}$ we define the even-band and odd-band supports,

$$\begin{align} E(x) &:= \{\, 2k : k \in Z(x) \,\},\\ r(x) &:= \min\{\, m \ge 2 : F_m > x \,\},\\ B(x) &:= 2r(x),\\ O(x,y) &:= \{\, B(x) + (2j - 1) : j \in Z(y) \,\}. \end{align}$$

Carryless Pairing (recommended when $0$ is reserved, e.g. for $\varnothing$) is the function

$$\pi_{\mathrm{CL}}:\mathbb{N}^2\to\mathbb{N}$$

given by:

$$\pi_{\mathrm{CL}}(x,y) \;:=\; F_2 \;+\; \sum_{k\in Z(x)} F_{2k} \;+\; \sum_{j\in Z(y)} F_{\,B(x)+(2j-1)}.$$

Equivalently,

$$\pi_{\mathrm{CL}}(x,y)=F_2+\sum_{i\in E(x)\cup O(x,y)} F_i,$$

The offset term $F_2$ shifts the output away from zero, so that

$$\pi_{\mathrm{CL}}(x,y)\ge 1, \quad \pi_{\mathrm{CL}}(0,0)\neq 0.$$

This keeps $0$ free as a reserved value (for example, to denote the empty support $\varnothing$).

Demo

Realization. The demo executes the carryless construction in four stages, each fully effective: bounded Fibonacci decomposition, reconstruction by local search, forward pairing, and inverse unpairing.


Step 1. Select at least two integers. JavaScript decomposes each one uniquely into non-consecutive Fibonacci summands.

Waiting for summands.

Step 2. Forget the supporting Fibonacci indices.

Then reconstruct them through a series of local search steps.

Waiting for command.

Step 3. Use this correspondence to build an injective $\Delta_0$ pairing function that takes any two natural numbers and returns a single one.

$x \in \mathbb{N}:$

$y \in \mathbb{N}:$

Waiting for input.

Step 4. The inverse — recovering $(x, y)$ from $n$ — is computed by a bounded search that runs in subpolynomial time.

$n \in \mathbb{N}:$

Waiting for input.

Remark. The pairing $\pi_{\mathrm{CL}}^\tau$ is finitary: each step uses a finite, explicitly bounded amount of arithmetic. Its correctness depends on the fact that every natural number has exactly one Zeckendorf decomposition, and that this decomposition is preserved under the standard order on $\mathbb{N}$. What looks like division is modular arithmetic, in fact a bounded $\mathcal{O}(\log n)$ search. These guarantees, however, presuppose that the underlying number model is faithful to $\{\,\mathbb{N},\, +,\, \le\,\}$; IEEE-754 floating point past $2^{53}$ is a familiar case where this assumption breaks down. We note a recurring theme in computation: exact arithmetical structure is routinely simulated inside hardware that is only approximate.

Acknowledgment. Thanks to Albert Visser Utrecht University for timely criticism and guidance.

Illustration: Recurrence relations are computationally expressive.

Algorithmic Display

The display below states the pairing as a finite arithmetic procedure. The input numbers are first converted to their canonical Zeckendorf supports; those supports are then placed on disjoint Fibonacci index bands. Decoding reverses the construction by decomposing the output, separating the even and offset odd bands, and summing the recovered Fibonacci terms.

Carryless Pairing Algorithm Input: x, y natural numbers F Fibonacci sequence, with indices available up to a finite bound Z Zeckendorf support function Conventions: Z(0) := empty set Z(n) := unique finite set A such that n = sum_{k in A} F_k and no two indices in A are consecutive r(x) := least m >= 2 such that F_m > x B(x) := 2 * r(x) Forward construction: Zx := Z(x) Zy := Z(y) E := empty set O := empty set for each k in Zx: append 2*k to E for each j in Zy: append B(x) + (2*j - 1) to O Because every member of E is even, and every member of O is odd and greater than B(x), the two bands are disjoint. Define: pi_CL(x, y) := F_2 + sum_{i in E} F_i + sum_{i in O} F_i Return pi_CL(x, y). Inverse construction: Input: n a realized carryless-pairing value If n < F_2: reject n as outside the reserved-zero pairing range m := n - F_2 Zn := Z(m) X := empty set for each i in Zn: if i is even: append i/2 to X x := sum_{k in X} F_k r := least m >= 2 such that F_m > x B := 2 * r Y := empty set for each i in Zn: if i is odd and i >= B + 1: append (i - B + 1)/2 to Y y := sum_{j in Y} F_j Return (x, y). Correctness checks: Zeckendorf.ok(n) iff the greedy decomposition of n returns a finite nonconsecutive support whose Fibonacci sum is n. BAND.ok(x, y) iff E(x) and O(x, y) are disjoint, all members of E(x) are even, and all members of O(x, y) are odd and greater than B(x). PAIR.ok(x, y) iff unpair(pair(x, y)) = (x, y). UNPAIR.ok(n) iff pair(unpair(n)) = n. Procedure: pair(x, y): assert x, y are natural numbers compute Zx, Zy, r(x), B(x), E(x), O(x, y) assert BAND.ok(x, y) return F_2 + sum_{i in E(x) union O(x, y)} F_i unpair(n): assert n is a natural number subtract the reserved offset F_2 compute the Zeckendorf support of the remaining value recover x from even indices recompute r(x) and B(x) recover y from odd indices at or beyond B(x) + 1 return (x, y) Output: pi_CL(x, y) one natural number encoding the ordered pair inverse the bounded arithmetic recovery of x and y certificate Zeckendorf.ok, BAND.ok, PAIR.ok, and UNPAIR.ok