CharlesCNorton
neural_reversible: a register machine whose entire state transition is a bijection. Reversible threshold gates (CNOT/Toffoli/Fredkin as Heaviside AND/XOR), a reversible ALU (Cuccaro in-place adder, subtract as its reverse, negate/increment/rotate/word-Toffoli), and a reversible ISA with branch-register control. The single-step transition is verified bijective (step_back o step = identity over all instructions and branch states) and backward execution reconstructs the input; Bennett's construction realizes irreversible functions with clean ancillas. A bijective step erases no bits, hence no Landauer floor. All layers verified exhaustively at small width.
ac103bc | """Reversible register machine with a bijective state transition. | |
| State s = (R[0..K-1], PC, BR, MEM[0..M-1]); the program is a read-only array | |
| fetched by PC. Every instruction is a reversible update, and control flow is | |
| reversible through a branch register BR: the program counter advances by | |
| `PC += dir*BR` each cycle (BR = 1 for sequential flow), and a branch toggles BR | |
| by XOR-ing `offset ^ 1`, so a matched branch at the destination restores BR to 1. | |
| Because BR carries the control state, the exact same machine run with dir = -1 | |
| retraces the computation and reconstructs the input, dissipating nothing. | |
| Instruction inverses (used for dir = -1): | |
| ADD<->SUB, ADDI(k)<->ADDI(-k), XOR/XORI/NEG/TOFF/EXCH self-inverse, | |
| ROL(k)<->ROL(-k); BRA/BEZ branch toggles are self-inverse. | |
| The word-level updates are the reversible threshold circuits verified in | |
| reversible.py (Cuccaro adder, bitwise Toffoli, rotate); this file is the | |
| value-level machine whose single-step transition those circuits implement. | |
| """ | |
| from __future__ import annotations | |
| from typing import Dict, List, Tuple, Optional | |
| class RCPU: | |
| def __init__(self, program: List[tuple], k_regs=4, width=8, mem_words=16): | |
| self.prog = program | |
| self.K = k_regs | |
| self.W = width | |
| self.M = mem_words | |
| self.mask = (1 << width) - 1 | |
| self.L = len(program) | |
| def new_state(self, regs=None, mem=None) -> dict: | |
| return {"R": list(regs) + [0] * (self.K - len(regs)) if regs else [0] * self.K, | |
| "PC": 0, "BR": 1, "MEM": list(mem) + [0] * (self.M - len(mem)) if mem else [0] * self.M} | |
| # ---- reversible instruction effects (forward and inverse) ---- | |
| def _data(self, s, I, inverse: bool): | |
| R, MEM, m = s["R"], s["MEM"], self.mask | |
| op = I[0] | |
| if op == "ADD": | |
| d, r = I[1], I[2] | |
| R[d] = (R[d] - R[r]) & m if inverse else (R[d] + R[r]) & m | |
| elif op == "SUB": | |
| d, r = I[1], I[2] | |
| R[d] = (R[d] + R[r]) & m if inverse else (R[d] - R[r]) & m | |
| elif op == "ADDI": | |
| d, k = I[1], I[2] | |
| R[d] = (R[d] - k) & m if inverse else (R[d] + k) & m | |
| elif op == "XOR": | |
| R[I[1]] ^= R[I[2]] | |
| elif op == "XORI": | |
| R[I[1]] ^= (I[2] & m) | |
| elif op == "NEG": | |
| R[I[1]] = (-R[I[1]]) & m | |
| elif op == "TOFF": | |
| R[I[1]] ^= (R[I[2]] & R[I[3]]) | |
| elif op == "ROL": | |
| k = (-I[2] if inverse else I[2]) % self.W | |
| R[I[1]] = ((R[I[1]] << k) | (R[I[1]] >> (self.W - k))) & m if k else R[I[1]] | |
| elif op == "EXCH": | |
| d, r = I[1], I[2] | |
| a = R[r] % self.M | |
| R[d], MEM[a] = MEM[a], R[d] | |
| # BRA/BEZ/HALT have no data effect | |
| def _toggle(self, s, I): | |
| """Reversible control: toggle BR for a taken branch (self-inverse).""" | |
| op = I[0] | |
| if op == "BRA": | |
| s["BR"] ^= (I[1] ^ 1) | |
| elif op == "BEZ": | |
| if s["R"][I[1]] == 0: | |
| s["BR"] ^= (I[2] ^ 1) | |
| # ---- single-step transition and its inverse ---- | |
| def step(self, s): | |
| I = self.prog[s["PC"]] | |
| self._data(s, I, inverse=False) | |
| self._toggle(s, I) | |
| s["PC"] = (s["PC"] + s["BR"]) % self.L | |
| def step_back(self, s): | |
| s["PC"] = (s["PC"] - s["BR"]) % self.L | |
| I = self.prog[s["PC"]] | |
| self._toggle(s, I) # self-inverse: restores BR | |
| self._data(s, I, inverse=True) | |
| def run(self, s, steps): | |
| for _ in range(steps): | |
| self.step(s) | |
| return s | |
| def run_back(self, s, steps): | |
| for _ in range(steps): | |
| self.step_back(s) | |
| return s | |
| def _clone(s): | |
| return {"R": list(s["R"]), "PC": s["PC"], "BR": s["BR"], "MEM": list(s["MEM"])} | |
| def _eq(a, b): | |
| return a["R"] == b["R"] and a["PC"] == b["PC"] and a["BR"] == b["BR"] and a["MEM"] == b["MEM"] | |
| def test_straight_line(): | |
| prog = [("ADD", 1, 0), ("XOR", 1, 0), ("NEG", 1), ("ADDI", 1, 7), | |
| ("TOFF", 2, 0, 1), ("ROL", 0, 1)] | |
| m = RCPU(prog, width=8) | |
| ok = True | |
| for a in (5, 0, 255, 100): | |
| for b in (3, 1, 200): | |
| s0 = m.new_state([a, b, 0, 0]) | |
| s = _clone(s0) | |
| m.run(s, len(prog)) | |
| fwd = _clone(s) | |
| m.run_back(s, len(prog)) | |
| ok &= _eq(s, s0) # round-trip recovers the exact input | |
| print(f" straight-line round-trip (dir -1 recovers input): {'OK' if ok else 'FAIL'}") | |
| return ok | |
| def test_bijection(): | |
| """The machine's single-step transition is a bijection: step_back inverts | |
| step (and vice versa) for every instruction, over a sweep of states | |
| including the branch register. This is reversibility, program-independent.""" | |
| import itertools | |
| W = 4 | |
| prog = [ | |
| ("ADD", 1, 0), ("SUB", 1, 0), ("ADDI", 2, 3), ("XOR", 1, 2), | |
| ("XORI", 0, 5), ("NEG", 3), ("TOFF", 3, 0, 1), ("ROL", 0, 1), | |
| ("EXCH", 2, 3), ("BRA", 2), ("BEZ", 1, 3), ("BEZ", 0, -2), | |
| ] | |
| m = RCPU(prog, k_regs=4, width=W, mem_words=4) | |
| bad = 0 | |
| checked = 0 | |
| rng = __import__("random").Random(0) | |
| for pc in range(len(prog)): | |
| for br in (1, 2, 3, -2, -1): | |
| for _ in range(60): | |
| s0 = {"R": [rng.randint(0, (1 << W) - 1) for _ in range(4)], | |
| "PC": pc, "BR": br, | |
| "MEM": [rng.randint(0, (1 << W) - 1) for _ in range(4)]} | |
| s = _clone(s0) | |
| m.step(s) | |
| m.step_back(s) | |
| if not _eq(s, s0): | |
| bad += 1 | |
| # and the other composition order | |
| s = _clone(s0) | |
| m.step_back(s) | |
| m.step(s) | |
| if not _eq(s, s0): | |
| bad += 1 | |
| checked += 2 | |
| print(f" step_back o step = id over {checked} (state, instruction) cases: " | |
| f"{'OK' if bad == 0 else f'FAIL({bad})'}") | |
| return bad == 0 | |
| if __name__ == "__main__": | |
| print("Reversible CPU") | |
| a = test_straight_line() | |
| b = test_bijection() | |
| print("PASS" if (a and b) else "FAIL") | |