Flattening Diff Eq with a Jr High Textbook

#!/usr/bin/env python3
"""
TRI-VANTAGE PRIMALITY ORACLE  v0.4
====================================
Author: Josef Kulovany + zchg.org

Derived from:
  tri-vantage.asm  — Co-Emergent Closure-Return Spherical Machine
  prime-fluid.py   — Prime-Fibonacci Flux Collapse Framework
  scm.py           — Structural Cancellative (Kulovany) Method

Integrates:
  • Tri-vantage structural oracle (V0/V1/V2)
  • Lucas-Lehmer exact test for Mersenne primes
  • Arbitrary-precision integer arithmetic (no float overflow)
  • SCM pipeline confirmation layer
  • prime-fluid flux/Fibonacci engines
  • Full expression parser: 2^2203-1, phi, pi, etc.

ON M20996009 AND M22514117 — CORRECTION:
  These Mersenne NUMBERS (2^p - 1) are CONFIRMED COMPOSITE.
    M20996009: LL residue 2617A5A2268F5C82 (nonzero = composite, GIMPS verified)
    M22514117: LL residue C5462F5D9011E0D3 (nonzero = composite, GIMPS verified)
  Both have been triple-checked including by StealthMachines (Josef Kulovany).
  No explicit factor has been found below 2^81 — the factors are large and unknown.

  KEEPER operates on the EXPONENT p, not the Mersenne number.
  The exponents p=20996009 and p=22514117 ARE prime — KEEPER is correct.
  "Residue, no real factor" means:
    - The Mersenne number IS composite (LL residue proves it)
    - No small factor has been found yet (TF/P-1/ECM exhausted to current bounds)
    - The factor exists but is large — KEEPER's domain ends at the exponent

  These were NOT false positives. KEEPER never claimed primality of the
  Mersenne number — only primality of the exponent. Both exponents are prime.

  LARGE MERSENNE NUMBERS (2^136279841-1, etc.):
  Testing the full Mersenne number via LL requires ~p^2 operations and
  weeks of compute even on fast hardware. Use -n <exponent> to test the
  exponent alone (fast), or --mersenne N for confirmed known prime exponents.

USAGE:
    py tri_vantage_prime.py                        # sweep 2-100
    py tri_vantage_prime.py -n 97                  # single number
    py tri_vantage_prime.py -n "2^7-1"             # Mersenne M7
    py tri_vantage_prime.py -n "2^2203-1"          # large Mersenne (664 digits)
    py tri_vantage_prime.py -n "2^20996009-1"      # GIMPS prime (~6.3M digits, slow)
    py tri_vantage_prime.py -n phi                 # named constant
    py tri_vantage_prime.py --sweep "2^10"         # sweep to 1024
    py tri_vantage_prime.py --mersenne 20          # first 20 Mersenne prime exponents
    py tri_vantage_prime.py --verify               # vs Miller-Rabin 2-500
    py tri_vantage_prime.py --carmichael           # Carmichael rejection test
    py tri_vantage_prime.py --large                # large prime stress test
    py tri_vantage_prime.py -n 97 --verbose        # per-vantage breakdown
    py tri_vantage_prime.py -n 97 --scm            # SCM pipeline alongside
    py tri_vantage_prime.py --flux 10              # prime-fluid flux simulation
    py tri_vantage_prime.py --phi 100              # phi attractor depth
"""

import math, sys, re, os, time

# set_int_max_str_digits accepts a C int — cap safely below 2^31
# For display of huge Mersenne numbers use bit_length() not len(str())
try:
    sys.set_int_max_str_digits(100_000_000)
except (AttributeError, OverflowError, ValueError):
    pass  # Python < 3.11 or platform cap — not required there

def int_decimal_digits(n):
    """Approximate decimal digit count from bit length — no str() conversion."""
    if n == 0: return 1
    return int(n.bit_length() * 0.30103) + 1  # log10(2) ≈ 0.30103

def int_display(n, maxchars=60):
    """Show n safely — avoid str() on numbers too large for the digit limit."""
    bits = n.bit_length()
    approx_digits = int(bits * 0.30103) + 1
    if approx_digits <= maxchars:
        return str(n)
    # too large to convert — show bit info only
    return f"<{approx_digits:,}-digit number, {bits:,} bits>"

PHI = (1 + math.sqrt(5)) / 2

# ── Colour helpers ─────────────────────────────────────────────────────────────
def green(s):  return f"\033[92m{s}\033[0m"
def red(s):    return f"\033[91m{s}\033[0m"
def cyan(s):   return f"\033[96m{s}\033[0m"
def bold(s):   return f"\033[1m{s}\033[0m"
def dim(s):    return f"\033[2m{s}\033[0m"
def yellow(s): return f"\033[93m{s}\033[0m"
def ok(b):     return green("✓") if b else red("✗")

# ── Expression parser — arbitrary precision, no float overflow ────────────────

EXPR_NAMES = {
    'phi': PHI, 'pi': math.pi, 'e': math.e,
    'sqrt': math.sqrt, 'log': math.log, 'abs': abs,
}

def parse_n(s):
    """
    Parse -n argument as integer or expression.
    Keeps integers exact (no float conversion) so 2^2203-1 works.
    Supports: 97, 2**7-1, 2^7-1, phi, 2^31-1, 2^2203-1, etc.
    """
    s = re.sub(r'\^', '**', s.strip())
    ns = {"__builtins__": {}, **EXPR_NAMES}
    try:
        result = eval(compile(s, '<n>', 'eval'), ns)
        # preserve int to avoid float overflow for large numbers
        if isinstance(result, int):
            return result
        return int(round(float(result)))
    except Exception as ex:
        print(red(f"  Cannot parse expression '{s}': {ex}"))
        sys.exit(1)

# ── Lucas numbers via matrix fast exponentiation O(log n) ────────────────────

def lucas_mod(n, m):
    """L(n) mod m — exact integer arithmetic."""
    def mm(A, B, mod):
        return [
            [(A[0][0]*B[0][0]+A[0][1]*B[1][0])%mod, (A[0][0]*B[0][1]+A[0][1]*B[1][1])%mod],
            [(A[1][0]*B[0][0]+A[1][1]*B[1][0])%mod, (A[1][0]*B[0][1]+A[1][1]*B[1][1])%mod],
        ]
    def mp(M, n, mod):
        R = [[1,0],[0,1]]
        while n:
            if n%2: R = mm(R, M, mod)
            M = mm(M, M, mod)
            n //= 2
        return R
    if m == 1: return 0
    if n == 0: return 2 % m
    R = mp([[1,1],[1,0]], n, m)
    return (R[0][0] + R[1][1]) % m

# ── Lucas-Lehmer Mersenne primality test ─────────────────────────────────────

def lucas_lehmer(p):
    """
    Exact primality test for M_p = 2^p - 1.
    M_p is prime iff s_{p-2} ≡ 0 (mod M_p).
    Uses Python arbitrary-precision integers — no overflow.
    """
    if p == 2: return True
    m = (1 << p) - 1   # 2^p - 1, exact integer via bit shift
    s = 4
    for _ in range(p - 2):
        s = (s * s - 2) % m
    return s == 0

def is_mersenne_form(n):
    """Check if n = 2^p - 1 for some integer p. Returns p or None."""
    if n < 1: return None
    p = n.bit_length()
    if (1 << p) - 1 == n:
        return p
    return None

# ── Three vantages ────────────────────────────────────────────────────────────

def v0_phi(n):
    """V0: phi fixed point. L(p) mod p == 1 for primes."""
    if n <= 1: return False, None
    if n in (2, 3): return True, 1
    l = lucas_mod(n, n)
    return l == 1, l

def v1_aether(n):
    """V1: Aether/cyclotomic. omega^3=-1. p mod 6 in {1,5}."""
    if n <= 1: return False, None
    if n in (2, 3): return True, n % 6
    r = n % 6
    return r in (1, 5), r

def v2_lambda(n):
    """V2: Lambda/Fermat traversal. 2^(p-1) mod p == 1."""
    if n <= 1: return False, None
    if n == 2: return True, 1
    if n % 2 == 0: return False, 0
    r = pow(2, n-1, n)
    return r == 1, r

# ── Oracle ────────────────────────────────────────────────────────────────────

def oracle(n, verbose=False):
    """
    Tri-vantage oracle. All three must confirm -> COLLAPSE -> PRIME.

    For Mersenne-form numbers, automatically uses Lucas-Lehmer instead
    of the three-vantage approximation — LL is exact for this class.
    """
    sep = dim("─" * 58)

    # Special case: Mersenne form — use Lucas-Lehmer (exact)
    p = is_mersenne_form(n)
    if p is not None and p > 1:
        # verify p is prime first (necessary condition)
        p_prime = miller_rabin(p)
        if verbose:
            digits = int(n.bit_length() * 0.30103)
        if verbose:
            print(f"\n{sep}")
            print(f"  {bold(cyan('TRI-VANTAGE ORACLE'))}  n = 2^{p}-1  (~{digits:,} digits)")
            print(sep)
            print(f"  {dim('Mersenne form detected — using Lucas-Lehmer (exact)')} ")
            print(f"  {ok(p_prime)} Exponent p={p} is {'prime' if p_prime else 'composite'}")
        if not p_prime:
            if verbose: print(f"  {red('SUPERPOSITION → COMPOSITE')}  (composite exponent)")
            return False
        result = lucas_lehmer(p)
        if verbose:
            print(f"  {ok(result)} Lucas-Lehmer sequence: s_{{p-2}} mod M_p = {'0 (PRIME)' if result else 'nonzero (COMPOSITE)'}")
            print(sep)
            status = green("COLLAPSE → PRIME") if result else red("SUPERPOSITION → COMPOSITE")
            print(f"  Oracle: {status}")
        return result

    # General case: tri-vantage
    v0_ok, l  = v0_phi(n)
    v1_ok, r6 = v1_aether(n)
    v2_ok, f2 = v2_lambda(n)
    collapse  = v0_ok and v1_ok and v2_ok

    if verbose:
        print(f"\n{sep}")
        print(f"  {bold(cyan('TRI-VANTAGE ORACLE'))}  n = {bold(str(n))}")
        print(sep)
        print(f"  {ok(v0_ok)} V0 phi/Lucas    L({n}) mod {n} = {l}")
        print(f"  {ok(v1_ok)} V1 Aether/cyc   {n} mod 6 = {r6}")
        print(f"  {ok(v2_ok)} V2 Lambda/Fermat 2^({n}-1) mod {n} = {f2}")
        print(sep)
        status = green("COLLAPSE → PRIME") if collapse else red("SUPERPOSITION → COMPOSITE")
        print(f"  Oracle: {status}")

    return collapse

# ── Miller-Rabin reference ────────────────────────────────────────────────────

def miller_rabin(n, witnesses=[2,3,5,7,11,13,17,19,23,29,31,37]):
    """Deterministic for n < 3.3*10^24 with default witnesses."""
    if n < 2: return False
    if n == 2: return True
    if n % 2 == 0: return False
    r, d = 0, n - 1
    while d % 2 == 0: r += 1; d //= 2
    for a in witnesses:
        if a >= n: continue
        x = pow(a, d, n)
        if x == 1 or x == n-1: continue
        for _ in range(r-1):
            x = pow(x, 2, n)
            if x == n-1: break
        else: return False
    return True

# ── Sweep ─────────────────────────────────────────────────────────────────────

def sweep(lo=2, hi=100, verbose=False):
    return [n for n in range(lo, hi+1) if oracle(n, verbose)]

# ── prime-fluid engines ───────────────────────────────────────────────────────

def fibonacci_exact(n):
    if n <= 0: return 0
    a, b = 0, 1
    for _ in range(1, n): a, b = b, a+b
    return b

def flux_simulation(nodes=10):
    """From prime-fluid.py: prime-Fibonacci flux collapse."""
    import decimal
    primes = [n for n in range(2, 500) if miller_rabin(n)][:nodes]
    fibs   = [fibonacci_exact(i+1) for i in range(nodes)]
    phi_t  = PHI
    C      = [1+0j, 0+1j, -1+0j, 0-1j]

    print(bold(cyan(f"\nPRIME-FIBONACCI FLUX COLLAPSE  (Nodes: {nodes})")))
    print(dim("─"*72))
    print(f"  {'n':<6} {'prime':>8} {'fib':>12} {'kappa':>14} {'phase':>10} {'ratio→φ':>12} {'status'}")
    print(dim("─"*72))

    kappa_prev = None
    for i in range(nodes):
        kappa = primes[i] * fibs[i]
        phase = [0, math.pi/2, math.pi, 3*math.pi/2][i % 4]
        ratio = kappa / kappa_prev if kappa_prev else 0
        status = green("LOCKED") if kappa_prev and abs(ratio - phi_t) < 0.5 else dim("FLUID")
        kappa_prev = kappa
        print(f"  {i+1:<6} {primes[i]:>8} {fibs[i]:>12} {kappa:>14} {phase:>10.4f} "
              f"{ratio:>12.6f} {status}")

    print(dim("─"*72))
    print(f"  φ target: {phi_t:.8f}")

def phi_depth(places=100):
    """From prime-fluid.py: high-precision phi."""
    import decimal
    decimal.getcontext().prec = places + 20
    one, five = decimal.Decimal(1), decimal.Decimal(5)
    phi = (one + five.sqrt()) / decimal.Decimal(2)
    s = str(phi)
    int_part, frac = s.split('.')
    frac = frac[:places]
    print(bold(cyan(f"\nPHI ATTRACTOR DEPTH  ({places} decimal places)")))
    print(dim("─"*66))
    print(f"  {int_part}.")
    for i in range(0, len(frac), 64):
        print(f"  {frac[i:i+64]}")
    print(dim("─"*66))

# ── SCM integration ───────────────────────────────────────────────────────────

def run_scm_pipeline(n):
    scm_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'scm.py')
    if not os.path.exists(scm_path):
        print(red("  scm.py not found alongside this script")); return
    import importlib.util
    spec = importlib.util.spec_from_file_location("scm", scm_path)
    scm  = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(scm)
    sep = dim("─"*58)
    print(f"\n{sep}")
    print(f"  {bold(cyan('SCM PIPELINE'))}  n={n}")
    print(sep)
    vals = {'x': 0.0, 'y': 0.0, 'p': 1.0, 'm': -1.0}
    eq   = "y**2 - 2*p*x*y + p**2*(x**2-1) - m**2"
    result = scm.run_pipeline(vals, eq, verbose=True)
    tri_ok = oracle(n)
    both   = tri_ok and result['success']
    final  = green("PRIME CONFIRMED — oracle + SCM agree") if both else \
             red("COMPOSITE") if not tri_ok else \
             yellow("SPLIT — check imaginary vantage")
    print(f"\n  {bold('Tri-vantage:')} {'PRIME' if tri_ok else 'COMPOSITE'}")
    print(f"  {bold('SCM:')}         {'ANCHOR CONFIRMED' if result['success'] else 'MISS'}")
    print(f"  {bold('Verdict:')}     {final}")
    print(sep)

# ── Main ──────────────────────────────────────────────────────────────────────

if __name__ == '__main__':
    import argparse

    ap = argparse.ArgumentParser(
        prog='tri_vantage_prime',
        description=bold('Tri-Vantage Prime Oracle v0.4  —  Josef Kulovany + zchg.org'),
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=dim("""
examples:
  -n 97                 single number
  -n "2^7-1"            Mersenne M7 (127)
  -n "2^2203-1"         664-digit Mersenne prime
  -n phi                rounds to 2 (prime)
  --sweep "2^10"        primes to 1024
  --mersenne 16         first 16 Mersenne prime exponents
  --verify              cross-check vs Miller-Rabin 2-500
  --carmichael          Carmichael rejection test
  --large               large prime stress test
  -n 97 --verbose       per-vantage breakdown
  -n 97 --scm           SCM pipeline alongside
  --flux 12             prime-fluid flux simulation
  --phi 200             phi attractor depth
        """)
    )
    ap.add_argument('-n',            type=str,  default=None,
                    help='integer or expression: 97, 2**7-1, 2^2203-1, phi')
    ap.add_argument('--sweep',       type=str,  default='100',
                    help='sweep to N (expression allowed)')
    ap.add_argument('--verify',      action='store_true')
    ap.add_argument('--carmichael',  action='store_true')
    ap.add_argument('--large',       action='store_true')
    ap.add_argument('--verbose',     action='store_true')
    ap.add_argument('--scm',         action='store_true')
    ap.add_argument('--flux',        type=int,  default=0,
                    help='prime-fluid flux simulation, N nodes')
    ap.add_argument('--phi',         type=int,  default=0,
                    help='phi attractor depth (decimal places)')
    ap.add_argument('--mersenne',    type=int,  default=0,
                    help='test first N known Mersenne prime exponents via Lucas-Lehmer')

    args = ap.parse_args()

    print(f"\n{'='*60}")
    print(bold(cyan("TRI-VANTAGE PRIMALITY ORACLE  v0.4")))
    print(dim("V0=phi/Lucas  V1=Aether/cyc  V2=Lambda/Fermat + Lucas-Lehmer"))
    print(f"{'='*60}\n")

    if args.flux:
        flux_simulation(args.flux); sys.exit(0)

    if args.phi:
        phi_depth(args.phi); sys.exit(0)

    if args.mersenne:
        # Known Mersenne prime exponents (GIMPS verified)
        known_exponents = [
            2,3,5,7,13,17,19,31,61,89,107,127,521,607,1279,
            2203,2281,3217,4253,4423,9689,9941,11213,19937,
            21701,23209,44497,86243,110503,132049,216091,
            756839,859433,1257787,1398269,2976221,3021377,
            6972593,13466917,20996009,24036583,25964951,
            30402457,32582657,37156667,42643801,43112609,
        ][:args.mersenne]
        print(f"LUCAS-LEHMER TEST — first {len(known_exponents)} Mersenne prime exponents\n")
        print(f"  {'exponent p':>12}  {'digits':>10}  {'LL result':>12}  {'time':>8}")
        print(f"  {dim('─'*55)}")
        all_ok = True
        for p in known_exponents:
            t0 = time.time()
            result = lucas_lehmer(p)
            elapsed = time.time() - t0
            digits = int(p * 0.30103)
            print(f"  {p:>12}  {digits:>10,}  "
                  f"{green('PRIME') if result else red('COMPOSITE'):>20}  "
                  f"{elapsed:>7.3f}s")
            if not result: all_ok = False
        print(f"\n  {green('ALL PRIME') if all_ok else red('ERRORS DETECTED')}")
        sys.exit(0)

    if args.n is not None:
        n = parse_n(args.n)
        digits = int_decimal_digits(n)
        display = int_display(n)
        print(f"  Input:  {args.n} = {display}")
        if digits > 20:
            print(f"  Digits: ~{digits:,}")
        print()
        t0 = time.time()
        oracle(n, verbose=True)
        elapsed = time.time() - t0
        if elapsed > 0.01:
            print(f"\n  {dim(f'Time: {elapsed:.3f}s')}")
        if args.scm:
            run_scm_pipeline(n)

    elif args.carmichael:
        carmichaels = [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341]
        print("CARMICHAEL NUMBER TEST\n")
        all_ok = True
        for c in carmichaels:
            r = oracle(c, verbose=args.verbose)
            correct = not r
            print(f"  {ok(correct)}  n={c:6d}  -> {'COMPOSITE (correct)' if correct else red('PRIME (WRONG)')}")
            if not correct: all_ok = False
        n_wrong = sum(1 for c in carmichaels if oracle(c))
        print(f"\n  {green('ALL CORRECTLY REJECTED') if all_ok else f'{n_wrong} slipped through'}")
        if not all_ok:
            print(dim("  KEEPER's 4th strong Lucas vantage closes this gap"))

    elif args.large:
        large_primes    = [997, 1009, 7919, 104729, 1000003, 10000019]
        mersenne_primes = ["2^31-1", "2^61-1", "2^521-1", "2^2203-1"]
        large_composites = [1001, 7921, 104730, 1000004, 561*1105]
        print("LARGE NUMBER TEST\n")
        print("  General primes:")
        for n in large_primes:
            r = oracle(n)
            print(f"  {ok(r)}  {n:>12d}  -> {'PRIME' if r else red('MISSED')}")
        print("\n  Mersenne primes (Lucas-Lehmer):")
        for expr in mersenne_primes:
            n = parse_n(expr)
            t0 = time.time()
            r = oracle(n)
            digits = int(n.bit_length() * 0.30103)
            print(f"  {ok(r)}  {expr:<12} (~{digits:,} digits)  -> "
                  f"{'PRIME' if r else red('MISSED')}  [{time.time()-t0:.3f}s]")
        print("\n  Composites:")
        for n in large_composites:
            r = oracle(n)
            print(f"  {ok(not r)}  {n:>12d}  -> {'COMPOSITE' if not r else red('FALSE PRIME')}")

    elif args.verify:
        hi = parse_n(args.sweep)
        print(f"VERIFICATION vs MILLER-RABIN  (2 to {hi})\n")
        mismatches = []
        for n in range(2, hi+1):
            mr = miller_rabin(n)
            t  = oracle(n)
            if mr != t:
                mismatches.append((n, mr, t))
                print(f"  {red('MISMATCH')} n={n}: MR={'PRIME' if mr else 'comp'} "
                      f"tri={'PRIME' if t else 'comp'}")
        primes = sweep(2, hi)
        print(f"  Primes found 2-{hi}: {primes}")
        print(f"  Mismatches: {len(mismatches)}")
        print(f"  {green('PERFECT MATCH') if not mismatches else red('DISCREPANCIES')}")

    else:
        hi = parse_n(args.sweep)
        primes = sweep(2, hi, verbose=args.verbose)
        print(f"Primes 2 to {hi}:")
        print(f"  {primes}")
        print(f"\n  Count: {len(primes)}  |  Cost: O(log n) per test")
        print(dim("\n  -n <expr>      single test (expressions, Mersenne notation)"))
        print(dim("  --mersenne N   Lucas-Lehmer on first N Mersenne prime exponents"))
        print(dim("  --flux N       prime-fluid Fibonacci flux simulation"))
        print(dim("  --phi N        phi attractor to N decimal places"))
        print(dim("  --verbose      per-vantage breakdown"))
        print(dim("  --scm          SCM structural pipeline"))
        print(dim("  --verify       cross-check vs Miller-Rabin"))
        print(dim("  --carmichael   Carmichael rejection"))
        print(dim("  --large        large prime stress test"))