#!/usr/bin/env python3 """ Spherion 16D Multi-Polar Transition Domain Twin-Prime Walk. Extends the classic twin-prime priority-queue enumeration of the 4 obstruction sheets 6ab ┬▒ a ┬▒ b with a per-sheet polarity parameter that tunes the energy of each obstruction, controlling the density of twin-prime witnesses. Theory: Twin primes (p, p+2) are characterized by the polynomial n = 6ab ┬▒ a ┬▒ b. An integer n is a *witness* (twin-prime candidate) iff no positive integers a,b and signs ┬▒1 satisfy the obstruction: n = 6ab + σ₁·a + σ₂·b (σ₁, σ₂ ∈ {+1, -1}) The 4 obstruction sheets are: Sheet (+1, +1): 6ab + a + b Sheet (+1, -1): 6ab + a - b Sheet (-1, +1): 6ab - a + b Sheet (-1, -1): 6ab - a - b Polarity scales the obstruction energy: E = p ┬À (6ab + σ₁┬Àa + σ₂┬Àb) p = 1.0 → standard algorithm (OEIS A002822) p < 1.0 → shed energy (lower barrier, more obstructions → fewer witnesses) p > 1.0 → accumulate energy (higher barrier, fewer obstructions → more witnesses) p = 0 → no obstructions (false positives: all integers are witnesses) p → ∞ → obstructions at infinity (false negatives: no finite witnesses) Energy = polarity ┬À raw_value defines the peak position. Integer n is obstructed iff there exists (a,b,σ₁,σ₂) such that n = p ┬À (6ab + σ₁┬Àa + σ₂┬Àb). References: - OEIS A002822: Numbers n such that 6n-1 and 6n+1 are twin primes. - "Twin-prime generating polynomials" via 6ab ┬▒ a ┬▒ b. """ from __future__ import annotations import argparse import hashlib import heapq import json import sys from datetime import datetime, timezone from typing import Dict, List, Optional, Set, Tuple # --------------------------------------------------------------------------- # Sheet-generator ── lazy priority-queue enumeration of one obstruction sheet # --------------------------------------------------------------------------- class SheetGenerator: """Lazily yield values from one obstruction sheet in increasing order. F(a,b) = polarity ┬À (6┬Àa┬Àb + σ₁┬Àa + σ₂┬Àb) for a,b ≥ 1. Uses a priority-queue frontier (standard sorted-matrix traversal). When *max_value* is given, stops as soon as the popped value exceeds it, enabling bounded scans that terminate even for extreme polarities. """ def __init__( self, σ1: int, σ2: int, polarity: float, max_value: Optional[float] = None, ) -> None: if polarity < 0: raise ValueError(f"polarity must be ≥ 0, got {polarity}") self.σ1 = σ1 self.σ2 = σ2 self.polarity = polarity self.max_value = max_value self._heap: List[Tuple[float, int, int]] = [] self._visited: Set[Tuple[int, int]] = set() self._push(1, 1) def _row(self, a: int, b: int) -> float: raw = 6 * a * b + self.σ1 * a + self.σ2 * b return self.polarity * raw def _push(self, a: int, b: int) -> None: if self.max_value is not None: lo = self._row(a, b) if lo > self.max_value: return key = (a, b) if key not in self._visited: self._visited.add(key) heapq.heappush(self._heap, (self._row(a, b), a, b)) def __iter__(self) -> SheetGenerator: return self def __next__(self) -> float: while self._heap: v, a, b = heapq.heappop(self._heap) if self.max_value is not None and v > self.max_value: self._heap.clear() raise StopIteration self._push(a + 1, b) self._push(a, b + 1) return v raise StopIteration # --------------------------------------------------------------------------- # Spherion 16D twin-prime walk # --------------------------------------------------------------------------- SIGNS: List[Tuple[int, int]] = [(1, 1), (1, -1), (-1, 1), (-1, -1)] class SpherionTwinPrimeWalk: """Priority-queue walk over the 4 obstruction sheets with energy tuning. Parameters ---------- polarities : dict, optional Per-sheet energy tuning. Keys are (σ₁, σ₂) tuples, values are floats. Missing sheets default to 1.0. """ def __init__( self, polarities: Optional[Dict[Tuple[int, int], float]] = None ) -> None: if polarities is None: polarities = {s: 1.0 for s in SIGNS} self.polarities = polarities # ── Public API ────────────────────────────────────────────────────── def obstruction(self, a: int, b: int, σ1: int, σ2: int) -> float: """Obstruction energy at (a, b, σ₁, σ₂).""" raw = 6 * a * b + σ1 * a + σ2 * b p = self.polarities.get((σ1, σ2), 1.0) return p * raw def _merged(self, max_value: Optional[float] = None) -> heapq.merge: """Merge all 4 sheet streams into one sorted obstruction stream.""" gens = [ SheetGenerator( σ1, σ2, self.polarities.get((σ1, σ2), 1.0), max_value=max_value, ) for σ1, σ2 in SIGNS ] return heapq.merge(*gens) def energy_spectrum(self, limit: int = 1000) -> List[float]: """First *limit* obstruction energies from the merged stream.""" out: List[float] = [] for i, v in enumerate(self._merged()): if i >= limit: break out.append(v) return out def _enumerate_bounded(self, limit: int) -> Set[int]: """Enumerate all obstructed integers ≤ *limit* via direct nested loops. For bounded enumeration this is faster and terminates reliably even for extreme polarities (p=0, p→∞) where the PQ-based generator would loop indefinitely or never reach the threshold. """ covered: Set[int] = set() limit_f = float(limit) for σ1, σ2 in SIGNS: p = self.polarities.get((σ1, σ2), 1.0) if p == 0.0: continue # a,b ≥ 1, raw = 6ab + σ1·a + σ2·b ≥ 4 for a=b=1, (-1,-1) sheet # bound: p * (6ab - a - b) ≤ limit ⇒ ab ≤ limit/p/4 (rough bound) max_ab = max(1, int(limit_f / p / 4) + 2) for a in range(1, max_ab + 1): for b in range(1, max_ab + 1): raw = 6 * a * b + σ1 * a + σ2 * b v = p * raw if v > limit_f: break iv = int(v) if v == iv and iv >= 1: covered.add(iv) return covered def obstructions_up_to(self, limit: int) -> Set[int]: """Set of integers n ≤ *limit* that are obstructed (energy lands on n).""" return self._enumerate_bounded(limit) def witnesses(self, limit: int = 500) -> List[int]: """Integers 1..limit NOT obstructed at the current polarities.""" obs = self.obstructions_up_to(limit) return [i for i in range(1, limit + 1) if i not in obs] def witness_density(self, limit: int = 500) -> float: """Fraction of integers ≤ *limit* that are witnesses.""" return len(self.witnesses(limit)) / max(limit, 1) def betti_gaps(self, limit: int = 500) -> List[int]: """Witness numbers as Betti scars — the uncovered (gap) region.""" return self.witnesses(limit) def per_sheet_coverage( self, limit: int = 500 ) -> Dict[Tuple[int, int], List[int]]: """Which integers each sheet obstructs individually.""" result: Dict[Tuple[int, int], List[int]] = {} for σ1, σ2 in SIGNS: p = self.polarities.get((σ1, σ2), 1.0) hits: Set[int] = set() if p > 0.0: max_ab = max(1, int(float(limit) / p / 4) + 2) for a in range(1, max_ab + 1): for b in range(1, max_ab + 1): raw = 6 * a * b + σ1 * a + σ2 * b v = p * raw if v > limit: break iv = int(v) if v == iv and iv >= 1: hits.add(iv) result[(σ1, σ2)] = sorted(hits) return result def report(self, limit: int = 500) -> dict: """Full JSON-serialisible report for the current polarity configuration.""" energy = self.energy_spectrum(min(limit, 200)) w = self.witnesses(limit) psc = self.per_sheet_coverage(limit) psc_serial = {f"({s1},{s2})": vals for (s1, s2), vals in psc.items()} return { "schema": "spherion_twin_prime_report_v1", "polarities": { f"({s1},{s2})": self.polarities[(s1, s2)] for s1, s2 in SIGNS }, "limit": limit, "witness_count": len(w), "witness_density": len(w) / max(limit, 1), "first_20_witnesses": w[:20], "first_20_energies": [round(e, 6) for e in energy[:20]], "per_sheet_coverage": {k: v[:10] for k, v in psc_serial.items()}, } # --------------------------------------------------------------------------- # Analysis helpers # --------------------------------------------------------------------------- def witness_density_vs_polarity( polarities: List[float], limit: int = 500 ) -> List[Tuple[float, float, int]]: """Compute witness density for each uniform polarity in *polarities*.""" results: List[Tuple[float, float, int]] = [] for p in polarities: walk = SpherionTwinPrimeWalk({s: p for s in SIGNS}) w = walk.witnesses(limit) density = len(w) / max(limit, 1) results.append((p, density, len(w))) return results def standard_oeis_check(limit: int = 200) -> Tuple[int, List[int]]: """Check that polarity=1.0 gives OEIS A002822 (twin-prime witnesses).""" walk = SpherionTwinPrimeWalk() w = walk.witnesses(limit) # OEIS A002822 starts: 1, 2, 3, 5, 7, 10, 12, 15, 17, 18, 23, 25, 30, ... return (len(w), w) # --------------------------------------------------------------------------- # CLI # --------------------------------------------------------------------------- def build_arg_parser() -> argparse.ArgumentParser: p = argparse.ArgumentParser( description="Spherion 16D twin-prime walk with polarity tuning" ) p.add_argument("--test", action="store_true", help="Run test suite") p.add_argument( "--limit", type=int, default=500, help="Search limit (default 500)" ) p.add_argument( "--polarity", type=float, default=None, help="Uniform polarity override (omit for per-sheet defaults)", ) p.add_argument("--json", action="store_true", help="Output JSON report") return p def run_tests(limit: int = 500) -> dict: """Execute the full test matrix and return a summary dict.""" results: dict = { "schema": "spherion_twin_prime_test_v1", "generated_at_utc": datetime.now(timezone.utc).isoformat(), "limit": limit, "tests": {}, } do_small = min(limit, 300) # ── 1. polarity = 0: no obstructions → all witnesses ──────────────── walk0 = SpherionTwinPrimeWalk({s: 0.0 for s in SIGNS}) w0 = walk0.witnesses(do_small) results["tests"]["polarity_0"] = { "description": "p=0 → no obstructions, all witnesses", "witness_count": len(w0), "expected_count": do_small, "all_witnesses": len(w0) == do_small, } # ── 2. polarity = 1.0: standard OEIS A002822 ──────────────────────── walk1 = SpherionTwinPrimeWalk() w1 = walk1.witnesses(do_small) results["tests"]["polarity_1_0"] = { "description": "p=1.0 → standard OEIS A002822", "witness_count": len(w1), "witness_density": len(w1) / do_small, "first_20": w1[:20], } # ── 3. polarity → ∞: very large → obstructions drift to infinity ──── walk_inf = SpherionTwinPrimeWalk({s: 1e9 for s in SIGNS}) w_inf = walk_inf.witnesses(do_small) results["tests"]["polarity_inf"] = { "description": "p=1e9 → obstructions at ≈1e9×raw, no finite hits", "witness_count": len(w_inf), "expected_count": do_small, "all_witnesses": len(w_inf) == do_small, } # ── 4. shed energy (p < 1.0) ──────────────────────────────────────── walk_low = SpherionTwinPrimeWalk({s: 0.5 for s in SIGNS}) # p = 0.5 w_low = walk_low.witnesses(do_small) results["tests"]["polarity_shed"] = { "description": "p=0.5 → shed energy, more obstructions, fewer witnesses", "witness_count": len(w_low), "density": len(w_low) / do_small, "vs_nominal_density": ( round(len(w_low) / do_small, 4), round(len(w1) / do_small, 4), ), } # ── 5. accumulate energy (p > 1.0) ────────────────────────────────── walk_high = SpherionTwinPrimeWalk({s: 3.0 for s in SIGNS}) w_high = walk_high.witnesses(do_small) results["tests"]["polarity_accumulate"] = { "description": "p=3.0 → accumulate energy, fewer obstructions, more witnesses", "witness_count": len(w_high), "density": len(w_high) / do_small, "vs_nominal_density": ( round(len(w_high) / do_small, 4), round(len(w1) / do_small, 4), ), } # ── 6. per-sheet tuning ───────────────────────────────────────────── per_sheet_polarities = { (1, 1): 1.0, (1, -1): 0.5, (-1, 1): 2.0, (-1, -1): 1.0, } walk_ps = SpherionTwinPrimeWalk(per_sheet_polarities) w_ps = walk_ps.witnesses(do_small) psc = walk_ps.per_sheet_coverage(do_small) results["tests"]["per_sheet_tuning"] = { "description": "Per-sheet polarities (1,1)=1.0 (1,-1)=0.5 (-1,1)=2.0 (-1,-1)=1.0", "polarities": { f"({s1},{s2})": p for (s1, s2), p in per_sheet_polarities.items() }, "witness_count": len(w_ps), "density": len(w_ps) / do_small, "per_sheet_obstruction_counts": { f"({s1},{s2})": len(vals) for (s1, s2), vals in psc.items() }, } # ── 7. Density sweep ──────────────────────────────────────────────── sweep_points = [0.0, 0.25, 0.5, 0.75, 1.0, 2.0, 5.0, 10.0] sweep = witness_density_vs_polarity(sweep_points, limit=do_small) results["tests"]["density_sweep"] = { "description": "Witness density vs uniform polarity", "sweep": [ {"polarity": p, "density": round(d, 4), "witnesses": n} for p, d, n in sweep ], } # ── 8. Betti-style gap analysis ───────────────────────────────────── gaps = walk1.betti_gaps(do_small) max_run = 0 cur = 0 for i in range(1, do_small + 1): if i in gaps: cur += 1 if cur > max_run: max_run = cur else: cur = 0 results["tests"]["betti_gaps"] = { "description": "Betti-style gap analysis at p=1.0", "gap_count": len(gaps), "longest_witness_run": max_run, "first_20_gaps": gaps[:20], } return results def main() -> None: args = build_arg_parser().parse_args() if args.test: results = run_tests(limit=args.limit) if args.json: print(json.dumps(results, indent=2)) else: tests = results["tests"] print(f"╔══ Spherion 16D Twin-Prime Walk — Test Results ═══╗") print(f" Limit: {results['limit']}\n") t = tests["polarity_0"] print( f"[polarity=0] {t['witness_count']}/{results['limit']} " f"witnesses — {'✓' if t['all_witnesses'] else '✗'} all witnesses" ) t = tests["polarity_1_0"] print( f"[polarity=1.0] {t['witness_count']}/{results['limit']} " f"witnesses — density {t['witness_density']:.4f}" ) print(f" First 20 witnesses: {t['first_20']}") t = tests["polarity_shed"] d_nom = tests["polarity_1_0"]["witness_density"] print( f"[polarity=1/3 — shed] {t['witness_count']}/{results['limit']} " f"witnesses — density {t['density']:.4f} " f"(nominal {d_nom:.4f}) {'✓ shed < nominal' if t['density'] < d_nom else ''}" ) t = tests["polarity_accumulate"] print( f"[polarity=3.0 — accumulate] {t['witness_count']}/{results['limit']} " f"witnesses — density {t['density']:.4f} " f"(nominal {d_nom:.4f}) {'✓ accumulate > nominal' if t['density'] > d_nom else ''}" ) t = tests["polarity_inf"] print( f"[polarity=1e9 — ∞ limit] {t['witness_count']}/{results['limit']} " f"witnesses — {'✓' if t['all_witnesses'] else '✗'} all finite witnesses" ) t = tests["per_sheet_tuning"] print(f"\n[per-sheet tuning] {t['witness_count']}/{results['limit']} witnesses") print(f" Sheet obstructions: {t['per_sheet_obstruction_counts']}") print(f" Polarities: {t['polarities']}") t = tests["density_sweep"] print(f"\n[Density sweep]") for pt in t["sweep"]: marker = " ← nominal" if pt["polarity"] == 1.0 else "" print( f" p={pt['polarity']:<8} → density {pt['density']:.4f} " f"({pt['witnesses']} witnesses)" + marker ) t = tests["betti_gaps"] print( f"\n[Betti gaps] {t['gap_count']} gaps, longest run = " f"{t['longest_witness_run']}" ) print(f" First 20 gaps (witnesses): {t['first_20_gaps']}") print(f"\n Key finding: gaps = twin-prime candidate scars.") print(f" The uncovered integers are the Betti-0 homology of") print(f" the obstruction complex.") # Generate SHA256 of results for audit trail h = hashlib.sha256(json.dumps(results, sort_keys=True).encode()).hexdigest() print(f"\n receipt_hash: {h}") print(f"╚{'═' * 50}╝") else: walk = SpherionTwinPrimeWalk() limit = args.limit if args.polarity is not None: walk = SpherionTwinPrimeWalk( {s: args.polarity for s in SIGNS} ) rep = walk.report(limit) if args.json: print(json.dumps(rep, indent=2)) else: print(f"Spherion Twin-Prime Walk — limit={limit}") print(f" Polarities: {rep['polarities']}") print(f" Witnesses: {rep['witness_count']}/{limit} " f"(density {rep['witness_density']:.4f})") print(f" First 20: {rep['first_20_witnesses']}") print(f" First 20 energies: {rep['first_20_energies']}") if __name__ == "__main__": main()