OFFELLIA_Quantis / OFFELLIA_ONDA.py
Brunobkr's picture
Upload 4 files
e95c0bb verified
"""
╔══════════════════════════════════════════════════════════════════════════════╗
║ OFFELLIA_ONDA v1.0 — Busca de Primos pela Onda Única ║
║ ║
║ FUNDAMENTO: Os primos são cristalizações de UMA ÚNICA ONDA IRRACIONAL ║
║ ║
║ Ψ(x) = sin²(2πφx) φ = (1+√5)/2 ║
║ f(x) = (φ·x) mod 1 — fase da onda em x ║
║ ║
║ ESTRUTURA EM 3 CAMADAS: ║
║ ① ONDA: Ψ(x) — 100% determinística, calculável em O(1) para qualquer x ║
║ ② RODA: mod 42, 12 janelas coprimas — ordem das fases é FIXA ║
║ ③ SIEVE: Miller-Rabin determinístico — confirma cristalização ║
║ ║
║ TEOREMA DAS TRÊS DISTÂNCIAS (Steinhaus 1959): ║
║ A sequência φ·1, φ·2, φ·3, ... mod 1 divide o círculo em EXATAMENTE ║
║ 3 tamanhos de intervalo com razão φ — estrutura de Fibonacci. ║
║ ║
║ CINCO CANAIS GÊMEOS (únicos possíveis): ║
║ Canal I:11→13 II:17→19 III:23→25 IV:29→31 V:41→1(cruzador) ║
║ ║
║ IDENTIDADE GÊMEA (Teorema T4): ║
║ F(p) + F(p+2) = 1 − cos(4πφ)·cos(4πφ(p+1)) EXATA ║
╚══════════════════════════════════════════════════════════════════════════════╝
"""
import math
import time
import sys
from math import gcd, isqrt, sin, cos, pi, sqrt, log
from collections import Counter, defaultdict
from datetime import datetime
from decimal import Decimal, getcontext
# ══════════════════════════════════════════════════════════════════════
# CONSTANTES DA ONDA ÚNICA
# ══════════════════════════════════════════════════════════════════════
PHI = (1 + sqrt(5)) / 2 # Proporção áurea — frequência da onda
INV_PHI = PHI - 1 # 1/φ = φ-1 ≈ 0.6180...
TWO_PI_PHI = 2 * pi * PHI # 2πφ — frequência angular
FOUR_PI_PHI = 4 * pi * PHI # 4πφ — para identidade gêmea
COS_4PI_PHI = math.cos(FOUR_PI_PHI) # cos(4πφ) ≈ 0.08742572 — amplitude gêmea
# Três distâncias de Steinhaus para φ
S_PEQUENO = 2 - PHI # ≈ 0.3820 — intervalo menor
S_MEDIO = PHI - 1 # ≈ 0.6180 — intervalo médio = 1/φ
S_GRANDE = 1.0 # intervalo maior = círculo completo
# Roda helicoidal
MOD_42 = 42
MOD_420 = 420
PILARES = (2, 3, 5, 7)
# 12 braços coprimos de 42 — as janelas da onda
BRACOS_42 = tuple(r for r in range(1, 43) if gcd(r, 42) == 1)
BRACOS_SET = frozenset(BRACOS_42)
# 96 classes mod 420 — classificador O(1)
CLASSES_420 = tuple(r for r in range(1, 421) if all(r % p != 0 for p in PILARES))
CLASSES_420_SET = frozenset(CLASSES_420)
# Famílias dos braços
FAMILIA_A = frozenset(r for r in BRACOS_42 if r % 6 == 1) # {1,13,19,25,31,37}
FAMILIA_B = frozenset(r for r in BRACOS_42 if r % 6 == 5) # {5,11,17,23,29,41}
# Ordem das fases dos 12 braços (fixa — nunca muda)
BRACOS_POR_FASE = tuple(sorted(BRACOS_42, key=lambda r: (PHI * r) % 1))
# Cinco canais gêmeos
CANAIS_GEMEOS = {
(11, 13): "I (interno)",
(17, 19): "II (interno)",
(23, 25): "III (interno)",
(29, 31): "IV (interno)",
(41, 1): "V (cruzador k→k+1)",
}
BRACOS_GEMEO_INI = frozenset(r for r, _ in CANAIS_GEMEOS)
BRACOS_GEMEO_FIM = frozenset(r for _, r in CANAIS_GEMEOS)
CANAL_DE_BRACO = {r: c for (r, _), c in zip(CANAIS_GEMEOS.keys(), CANAIS_GEMEOS.values())}
# Progressão Δφ por ciclo de 42
DELTA_FASE_CICLO = (PHI * 42) % 1 # ≈ 0.9574 — avanço de fase por revolução
# ══════════════════════════════════════════════════════════════════════
# FUNÇÕES DA ONDA ÚNICA
# ══════════════════════════════════════════════════════════════════════
def onda(x: int) -> float:
"""Ψ(x) = sin²(2πφx) — valor da onda no ponto x."""
return sin(TWO_PI_PHI * x) ** 2
def fase(x: int) -> float:
"""f(x) = (φ·x) mod 1 — fase da onda em x ∈ [0, 1)."""
return (PHI * x) % 1
def onda_ciclo(x: int) -> float:
"""Ψ do ciclo k = x//42: sin²(2πφ·k)."""
return onda(x // MOD_42)
def grau_angular(x: int) -> int:
"""Projeção angular: (x·42) mod 360 — 16 valores possíveis para primos > 7."""
return (x * MOD_42) % 360
def identidade_gemea(p: int) -> float:
"""Valor exato da Identidade Gêmea: 1 − cos(4πφ)·cos(4πφ(p+1))."""
return 1.0 - COS_4PI_PHI * math.cos(FOUR_PI_PHI * (p + 1))
def tipo_no(fn: float) -> str:
"""Classifica o ponto da onda pelo valor Fn."""
if fn < 0.05: return "NÓ"
if fn > 0.95: return "ANTI-NÓDULO"
if fn < 0.25: return "próx-nó"
if fn > 0.75: return "próx-anti"
return "transição"
def salto_fase(p1: int, p2: int) -> float:
"""Δφ = (φ·(p2-p1)) mod 1 — salto de fase entre dois primos consecutivos."""
return (PHI * (p2 - p1)) % 1
# ══════════════════════════════════════════════════════════════════════
# CAMADA 3 — MILLER-RABIN DETERMINÍSTICO
# Correto para n < 3.317×10²⁴ com estas witnesses.
# ══════════════════════════════════════════════════════════════════════
_WITNESSES = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37)
def _miller_rabin_core(n: int) -> bool:
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 = x * x % n
if x == n - 1:
break
else:
return False
return True
def eh_primo(n: int) -> bool:
"""
Teste de primalidade helicoidal em 3 fases:
① Pilares {2,3,5,7} — O(1)
② Classificador mod 420 — O(1), elimina 77.1%
③ Miller-Rabin determinístico — confirma
"""
if n < 2:
return False
if n in (2, 3, 5, 7):
return True
if any(n % p == 0 for p in PILARES):
return False
if (n % MOD_420) not in CLASSES_420_SET: # ← filtro da onda mod 420
return False
return _miller_rabin_core(n)
# ══════════════════════════════════════════════════════════════════════
# GERADOR HELICOIDAL — VARREDURA DAS JANELAS DA ONDA
# ══════════════════════════════════════════════════════════════════════
def gerar_primos_onda(N: int):
"""
Gera todos os primos até N percorrendo as janelas da onda.
A onda varre os ciclos k=0,1,2,...,⌊N/42⌋.
Em cada ciclo, testa apenas as 12 janelas coprimas de 42.
As janelas são visitadas em ORDEM DE FASE CRESCENTE
(sequência determinística de Fibonacci).
"""
# Pilares primeiro
for p in PILARES:
if p <= N:
yield p
k = 0
while True:
base = MOD_42 * k
if base > N:
break
# Visita janelas em ordem de fase (estrutura de Fibonacci)
for r in BRACOS_POR_FASE:
c = base + r
if c < 8:
continue
if c > N:
continue
if eh_primo(c):
yield c
k += 1
# ══════════════════════════════════════════════════════════════════════
# ASSINATURA HELICOIDAL COMPLETA
# ══════════════════════════════════════════════════════════════════════
def assinatura(p: int, primos_set: set = None) -> dict:
"""Retorna a assinatura helicoidal completa do primo p."""
r42 = p % MOD_42
r420 = p % MOD_420
k = p // MOD_42
fn_p = onda(p)
fn_k = onda(k)
f_p = fase(p)
grau = grau_angular(p)
# Família
fam = 'A' if r42 in FAMILIA_A else ('B' if r42 in FAMILIA_B else '?')
# Canal gêmeo
canal = None
for (r1, r2), nome in CANAIS_GEMEOS.items():
if r42 == r1 or r42 == r2:
canal = nome
break
# Par gêmeo (se primos_set fornecido)
eh_gem = False
if primos_set is not None:
eh_gem = (p + 2 in primos_set) or (p - 2 in primos_set)
# Identidade gêmea
sig_gem = fn_p + onda(p + 2)
sig_prevista = identidade_gemea(p)
# Tipo de nó
no = tipo_no(fn_p)
# Três distâncias — tamanho do intervalo de fase deste braço
idx = BRACOS_POR_FASE.index(r42) if r42 in BRACOS_SET else -1
if idx >= 0:
r_prox = BRACOS_POR_FASE[(idx + 1) % 12]
df_steinhaus = (fase(r_prox) - fase(r42)) % 1
else:
df_steinhaus = 0.0
return {
'p': p,
'braco_42': r42,
'classe_420': r420,
'ciclo_k': k,
'Fn_onda': fn_p,
'Fn_ciclo': fn_k,
'fase': f_p,
'grau': grau,
'familia': fam,
'canal_gemeo': canal,
'eh_gemeo': eh_gem,
'sig_gemea': sig_gem,
'sig_prevista': sig_prevista,
'erro_gemea': abs(sig_gem - sig_prevista),
'tipo_no': no,
'df_steinhaus': df_steinhaus,
}
# ══════════════════════════════════════════════════════════════════════
# GERAÇÃO DO RELATÓRIO COMPLETO
# ══════════════════════════════════════════════════════════════════════
def gerar_relatorio(N: int, primos: list, t_busca: float, arquivo: str):
primos_set = set(primos)
L = []
SEP = "═" * 76
SEP2 = "─" * 76
def linha(s=""): L.append(s)
# ── CABEÇALHO
linha(SEP)
linha(" OFFELLIA_ONDA v1.0 — Relatório da Onda Única dos Primos")
linha(f" Gerado em: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
linha(f" Busca até N = {N:,} | Tempo: {t_busca:.6f} s | Primos: {len(primos):,}")
linha(SEP)
linha()
# ── SEÇÃO 1: Fundamento da onda
linha(SEP2)
linha(" [ 1. FUNDAMENTO — A ONDA ÚNICA ]")
linha()
linha(" Ψ(x) = sin²(2πφx) φ = (1+√5)/2 = proporção áurea")
linha(" f(x) = (φ·x) mod 1 = fase da onda em x")
linha()
linha(f" φ = {PHI:.15f}")
linha(f" 2πφ = {TWO_PI_PHI:.15f}")
linha(f" cos(4πφ) = {COS_4PI_PHI:.15f} ← amplitude gêmea")
linha(f" Δφ/ciclo de 42 = {DELTA_FASE_CICLO:.15f}")
linha()
linha(" TRÊS DISTÂNCIAS DE STEINHAUS para φ:")
linha(f" s_pequeno = 2-φ = {S_PEQUENO:.10f}")
linha(f" s_médio = φ-1 = {S_MEDIO:.10f} = 1/φ")
linha(f" s_grande = 1 = s_pequeno + s_médio (círculo completo)")
linha(f" razão: s_médio/s_pequeno = {S_MEDIO/S_PEQUENO:.10f} → φ = {PHI:.10f}")
linha()
linha(" Ordem das fases dos 12 braços (FIXA — estrutura de Fibonacci):")
linha()
linha(f" {'braço':>6} {'fase φ·r':>12} {'Fn(r)':>8} {'intervalo Δf':>14}")
linha(" " + "─" * 46)
for i, r in enumerate(BRACOS_POR_FASE):
f_r = fase(r)
fn_r = onda(r)
r_prox = BRACOS_POR_FASE[(i + 1) % 12]
df = (fase(r_prox) - f_r) % 1
linha(f" {r:>6} {f_r:>12.8f} {fn_r:>8.5f} {df:>14.8f}")
linha()
# ── SEÇÃO 2: Parâmetros da busca
linha(SEP2)
linha(" [ 2. PARÂMETROS DA BUSCA ]")
linha()
n_ciclos = N // MOD_42 + 1
n_candidatos = n_ciclos * 12
taxa_candidatos = n_candidatos / N * 100 if N > 0 else 0
taxa_eliminados = 100 - taxa_candidatos
linha(f" N buscado: {N:>15,}")
linha(f" Ciclos de 42: {n_ciclos:>15,}")
linha(f" Candidatos testados:{n_candidatos:>15,} ({taxa_candidatos:.2f}% dos inteiros)")
linha(f" Eliminados sem teste:{N - n_candidatos:>14,} ({taxa_eliminados:.2f}% dos inteiros)")
linha(f" Primos encontrados: {len(primos):>15,}")
if t_busca > 0:
linha(f" Velocidade: {len(primos)/t_busca:>15,.0f} primos/s")
linha()
# ── SEÇÃO 3: Distribuição por fase (a onda)
linha(SEP2)
linha(" [ 3. DISTRIBUIÇÃO DOS PRIMOS NA ONDA — FASES ]")
linha()
linha(" A fase f(p) = (φ·p) mod 1 distribui os primos em [0,1]")
linha(" Por Weyl: distribuição uniforme (equidistribuição)")
linha()
N_faixas = 20
faixas_fase = defaultdict(int)
faixas_fn = defaultdict(list)
for p in primos:
if p > 7:
b = min(N_faixas - 1, int(fase(p) * N_faixas))
faixas_fase[b] += 1
faixas_fn[b].append(onda(p))
total_gt7 = len([p for p in primos if p > 7])
linha(f" {'Faixa fase':>14} {'Fn médio':>9} {'count':>7} {'% total':>8} Barra (equidist. esperada)")
linha(" " + "─" * 72)
esperado = total_gt7 / N_faixas
for i in range(N_faixas):
a = i / N_faixas; b = (i + 1) / N_faixas
cnt = faixas_fase[i]
fn_list = faixas_fn[i]
fn_med = sum(fn_list) / len(fn_list) if fn_list else 0
pct = cnt / total_gt7 * 100 if total_gt7 else 0
desvio = (cnt - esperado) / esperado * 100 if esperado else 0
barra = "█" * int(pct / 5 * 10)
linha(f" [{a:.2f},{b:.2f}) {fn_med:>9.5f} {cnt:>7,} {pct:>7.2f}% {barra}")
linha()
# ── SEÇÃO 4: Nós e anti-nódulos
linha(SEP2)
linha(" [ 4. NÓS E ANTI-NÓDULOS DA ONDA ]")
linha()
linha(" NÓ → Fn < 0.05 (fase próxima de 0 ou 1)")
linha(" ANTI-NÓD. → Fn > 0.95 (fase próxima de 0.5)")
linha()
nos = [p for p in primos if p > 7 and onda(p) < 0.05]
antinos = [p for p in primos if p > 7 and onda(p) > 0.95]
trans = [p for p in primos if p > 7 and 0.05 <= onda(p) <= 0.95]
linha(f" NÓS (Fn < 0.05): {len(nos):>7,} ({len(nos)/total_gt7*100:.2f}%)")
linha(f" ANTI-NÓDULOS (Fn > 0.95): {len(antinos):>7,} ({len(antinos)/total_gt7*100:.2f}%)")
linha(f" TRANSIÇÃO (0.05-0.95): {len(trans):>7,} ({len(trans)/total_gt7*100:.2f}%)")
linha()
if nos:
fn_nos = [onda(p) for p in nos]
linha(f" Fn mín nos nós: {min(fn_nos):.10f}")
linha(f" Fn máx nos nós: {max(fn_nos):.10f}")
if antinos:
fn_an = [onda(p) for p in antinos]
linha(f" Fn mín anti-nódulos: {min(fn_an):.10f}")
linha(f" Fn máx anti-nódulos: {max(fn_an):.10f}")
linha()
linha(" Primeiros 10 primos NÓ (Fn≈0):")
linha(f" {'p':>10} {'fase':>10} {'Fn':>12} {'braço':>6} {'k(ciclo)':>9}")
linha(" " + "─" * 55)
for p in nos[:10]:
linha(f" {p:>10,} {fase(p):>10.6f} {onda(p):>12.8f} {p%42:>6} {p//42:>9,}")
linha()
linha(" Primeiros 10 primos ANTI-NÓDULO (Fn≈1):")
linha(f" {'p':>10} {'fase':>10} {'Fn':>12} {'braço':>6} {'k(ciclo)':>9}")
linha(" " + "─" * 55)
for p in antinos[:10]:
linha(f" {p:>10,} {fase(p):>10.6f} {onda(p):>12.8f} {p%42:>6} {p//42:>9,}")
linha()
# ── SEÇÃO 5: Os 12 braços — assinaturas
linha(SEP2)
linha(" [ 5. OS 12 BRAÇOS DA ONDA — ASSINATURAS ]")
linha()
linha(f" {'r':>4} {'Fam':>3} {'grau°':>6} {'fase φr':>10} {'count':>7} "
f"{'Fn med':>7} {'σ':>6} {'tipo':>20}")
linha(" " + "─" * 78)
for r in BRACOS_42:
ps_r = [p for p in primos if p > 7 and p % 42 == r]
if not ps_r:
continue
fns = [onda(p) for p in ps_r]
med = sum(fns) / len(fns)
sig = (sum((x - med) ** 2 for x in fns) / len(fns)) ** 0.5
fam = 'A' if r in FAMILIA_A else 'B'
grau = (r * 42) % 360
f_r = fase(r)
# tipo
viz = []
if (r + 2) % 42 in BRACOS_SET: viz.append(f"+2→{(r+2)%42}")
if (r - 2) % 42 in BRACOS_SET: viz.append(f"-2→{(r-2)%42}")
tipo = ("gêmeo " + str(viz[0])) if viz else "isolado"
linha(f" {r:>4} {fam:>3} {grau:>6}° {f_r:>10.6f} {len(ps_r):>7,} "
f"{med:>7.5f} {sig:>6.4f} {tipo:>20}")
linha()
# ── SEÇÃO 6: Cinco canais gêmeos
linha(SEP2)
linha(" [ 6. OS 5 CANAIS GÊMEOS DA ONDA ]")
linha()
linha(" Único conjuntos de braços a distância 2 que são ambos coprimos de 42.")
linha(" O elemento médio p+1 tem sempre gcd(p+1, 42) > 1 — janela fechada.")
linha()
gemeos = [(p, p + 2) for p in primos if p + 2 in primos_set and p > 7]
linha(f" Total de pares gêmeos: {len(gemeos):,}")
linha()
linha(f" {'Canal':>25} {'braços':>9} {'pares':>7} {'Σ F(p)+F(q) med':>16} {'σ':>7}")
linha(" " + "─" * 72)
for (r1, r2), nome in CANAIS_GEMEOS.items():
canal_g = [(p, q) for p, q in gemeos if p % 42 == r1]
somas = [onda(p) + onda(q) for p, q in canal_g]
med = sum(somas) / len(somas) if somas else 0
sig = (sum((x - med) ** 2 for x in somas) / len(somas)) ** 0.5 if somas else 0
linha(f" Canal {nome:>19} ({r1:>2},{r2:>2}) {len(canal_g):>7,} {med:>16.8f} {sig:>7.5f}")
linha()
linha(" Identidade Gêmea (T4): F(p)+F(p+2) = 1 − cos(4πφ)·cos(4πφ(p+1))")
linha(f" cos(4πφ) = {COS_4PI_PHI:.10f}")
linha(f" Intervalo da soma: [{1-abs(COS_4PI_PHI):.8f}, {1+abs(COS_4PI_PHI):.8f}]")
linha()
if gemeos:
erros = [abs(onda(p) + onda(q) - identidade_gemea(p)) for p, q in gemeos[:500]]
linha(f" Verificação T4 em {min(500,len(gemeos))} pares:")
linha(f" Erro máximo: {max(erros):.2e}")
linha(f" Erro médio: {sum(erros)/len(erros):.2e}")
linha()
# ── SEÇÃO 7: Saltos de fase
linha(SEP2)
linha(" [ 7. SALTOS DE FASE — PROGRESSÃO DA ONDA ]")
linha()
linha(" Δφ(gap) = (φ·gap) mod 1 — cada gap tem Δφ determinístico")
linha()
gaps_obs = Counter(primos[i+1] - primos[i] for i in range(len(primos)-1))
linha(f" {'gap':>5} {'Δφ=φ·gap mod 1':>18} {'count':>8} {'% total':>8} Significado")
linha(" " + "─" * 70)
total_gaps = sum(gaps_obs.values())
for gap, cnt in sorted(gaps_obs.items(), key=lambda x: -x[1])[:15]:
df = (PHI * gap) % 1
pct = cnt / total_gaps * 100
sig = ""
if gap == 2: sig = "← gap mínimo (gêmeos)"
elif gap == 6: sig = "← gap dominante"
elif gap == 4: sig = "← 2° mais comum"
elif gap == 1: sig = "← 2→3 (único gap ímpar)"
linha(f" {gap:>5} {df:>18.8f} {cnt:>8,} {pct:>7.2f}% {sig}")
linha()
# ── SEÇÃO 8: Taxonomia dos 7 tipos
linha(SEP2)
linha(" [ 8. TAXONOMIA COMPLETA — 7 TIPOS NATURAIS DE PRIMO ]")
linha()
bracos_gemeo_set = {r for r, _ in CANAIS_GEMEOS} | {r for _, r in CANAIS_GEMEOS}
tipos = {
'Pilares': [p for p in primos if p in (2,3,5,7)],
'Órfãos k=0': [p for p in primos if 7 < p < 42],
'Harmônicos r=1': [p for p in primos if p > 42 and p % 42 == 1],
'Gêmeos internos': [p for p in primos if p > 7 and p % 42 in {11,13,17,19,23,25,29,31}
and (p+2 in primos_set or p-2 in primos_set)],
'Gêmeos cruzadores':[p for p in primos if p > 7 and p % 42 in {41,1}
and (p+2 in primos_set or p-2 in primos_set)],
'Isolados r={5,37}':[p for p in primos if p > 7 and p % 42 in {5, 37}],
'Solitários': [p for p in primos if p > 7 and p % 42 in bracos_gemeo_set
and p+2 not in primos_set and p-2 not in primos_set],
}
linha(f" {'Tipo':>22} {'count':>8} {'%':>6} Fn médio Descrição")
linha(" " + "─" * 78)
for nome, lista in tipos.items():
cnt = len(lista)
pct = cnt / total_gt7 * 100 if total_gt7 and nome != 'Pilares' else 0
fns = [onda(p) for p in lista if p > 7] or [0]
med = sum(fns) / len(fns)
descs = {
'Pilares': "Base: 2,3,5,7",
'Órfãos k=0': "ciclo zero, Fn_ciclo=0",
'Harmônicos r=1': "p^n sempre no braço 1",
'Gêmeos internos': "braços {11,13,17,19,23,25,29,31}",
'Gêmeos cruzadores': "braços {41,1}, cruza fronteira k",
'Isolados r={5,37}': "gap mínimo ≥ 4, nunca gêmeos",
'Solitários': "braço gêmeo mas sem par vizinho",
}
linha(f" {nome:>22} {cnt:>8,} {pct:>6.2f}% {med:>8.5f} {descs.get(nome,'')}")
linha()
# ── SEÇÃO 9: Assinaturas — primeiros 50 primos > 7
linha(SEP2)
linha(" [ 9. ASSINATURAS HELICOIDAIS — PRIMEIROS 50 PRIMOS > 7 ]")
linha()
linha(f" {'p':>10} {'r42':>4} {'k':>7} {'fase':>10} {'Fn(p)':>8} "
f"{'grau':>5} {'tipo_nó':>11} {'canal':>5} {'gêmeo':>6}")
linha(" " + "─" * 80)
count = 0
for p in primos:
if p <= 7:
continue
fn = onda(p)
f = fase(p)
k = p // 42
r = p % 42
gr = grau_angular(p)
no = tipo_no(fn)
# canal
canal_str = ""
for (r1, r2), nome_c in CANAIS_GEMEOS.items():
if r == r1 or r == r2:
canal_str = f"C{nome_c[1]}"
break
gem = "✓" if (p+2 in primos_set or p-2 in primos_set) else ""
linha(f" {p:>10,} {r:>4} {k:>7,} {f:>10.6f} {fn:>8.5f} "
f"{gr:>5}° {no:>11} {canal_str:>5} {gem:>6}")
count += 1
if count >= 50:
break
linha()
# ── SEÇÃO 10: Últimos 20 primos encontrados
linha(SEP2)
linha(" [ 10. ÚLTIMOS 20 PRIMOS ENCONTRADOS ]")
linha()
linha(f" {'p':>12} {'r42':>4} {'k':>9} {'fase':>10} {'Fn(p)':>8} "
f"{'grau':>5} {'tipo_nó':>11}")
linha(" " + "─" * 70)
for p in primos[-20:]:
fn = onda(p)
f = fase(p)
k = p // 42
r = p % 42
gr = grau_angular(p)
no = tipo_no(fn)
linha(f" {p:>12,} {r:>4} {k:>9,} {f:>10.6f} {fn:>8.5f} {gr:>5}° {no:>11}")
linha()
# ── SEÇÃO 11: Estatísticas globais da onda
linha(SEP2)
linha(" [ 11. ESTATÍSTICAS GLOBAIS DA ONDA ]")
linha()
fn_todos = [onda(p) for p in primos if p > 7]
if fn_todos:
media_fn = sum(fn_todos) / len(fn_todos)
var_fn = sum((x - media_fn) ** 2 for x in fn_todos) / len(fn_todos)
sigma_fn = var_fn ** 0.5
fn_min = min(fn_todos)
fn_max = max(fn_todos)
# primo com Fn mais próximo de 0 (nó mais puro)
p_no = min((p for p in primos if p > 7), key=lambda p: onda(p))
p_an = max((p for p in primos if p > 7), key=lambda p: onda(p))
linha(f" Fn médio sobre todos primos > 7: {media_fn:.10f}")
linha(f" (teórico pela equidistribuição: 0.5000000000)")
linha(f" Desvio padrão Fn: {sigma_fn:.10f}")
linha(f" Fn mínimo: {fn_min:.12f} → primo {p_no:,} (NÓ mais puro)")
linha(f" Fn máximo: {fn_max:.12f} → primo {p_an:,} (ANTI-NÓ mais puro)")
linha()
# Fase média
fases = [fase(p) for p in primos if p > 7]
media_fase = sum(fases) / len(fases)
linha(f" Fase média: {media_fase:.10f} (teórico: 0.5000000000)")
linha()
# Verificação do Teorema T5 (equidistribuição)
desv_weyl = abs(media_fn - 0.5)
linha(f" Desvio de Weyl |E[Fn] - 0.5|: {desv_weyl:.2e}")
linha(f" Ordem esperada por Weyl: O(1/√N) ≈ {1/len(fn_todos)**0.5:.2e}")
linha()
# ── SEÇÃO 12: Ciclos notáveis — quasi-periodicidade
linha(SEP2)
linha(" [ 12. QUASI-PERIODICIDADE — ESTRUTURA DE FIBONACCI ]")
linha()
linha(f" Δφ por ciclo de 42 = {DELTA_FASE_CICLO:.10f}")
linha()
linha(" Sequência de convergentes Fibonacci da fase:")
linha()
linha(f" {'F(n)':>8} {'Δφ·F(n) mod 1':>16} {'distância a 0':>14} {'nível'}")
linha(" " + "─" * 52)
fibs = [1, 1]
while fibs[-1] < 5000:
fibs.append(fibs[-1] + fibs[-2])
for f_n in fibs[:14]:
acum = (DELTA_FASE_CICLO * f_n) % 1
dist = min(acum, 1 - acum)
nivel = "← quasi-período" if dist < 0.01 else ""
linha(f" {f_n:>8,} {acum:>16.8f} {dist:>14.8f} {nivel}")
linha()
# ── SEÇÃO 13: Teoremas e limites
linha(SEP2)
linha(" [ 13. TEOREMAS PROVADOS E LIMITES HONESTOS ]")
linha()
linha(" ┌─── PROVADO ──────────────────────────────────────────────────┐")
linha(" │ T1: Arm Sieve — p>7 ⟹ p mod 42 ∈ {12 braços coprimos} │")
linha(" │ T2: 96 Classes — p>7 ∈ exatamente 1 das 96 classes mod 420 │")
linha(" │ T3: Colapso — grau(p) = (r₄₂₀·42) mod 360 │")
linha(" │ T4: Id.Gêmea — F(p)+F(p+2) = 1−cos(4πφ)·cos(4πφ(p+1)) │")
linha(" │ T5: Equidist. — F(p) uniforme em [0,1] (Weyl+Vinogradov) │")
linha(" │ T6: Grupo — (Z/42Z)* abeliano, ord 12, 144 proporções │")
linha(" │ T7: 3 Distâncias— φ·n mod 1 cria exatamente 3 intervalos │")
linha(" │ com razão φ (Teorema de Steinhaus, 1959) │")
linha(" └──────────────────────────────────────────────────────────────┘")
linha()
linha(" ┌─── LIMITES (o que a teoria NÃO faz) ─────────────────────────┐")
linha(" │ L1: A fase f(p) é uniforme → NÃO discrimina primo/composto │")
linha(" │ dentro de uma classe mod 420 │")
linha(" │ L2: Não existe fórmula fechada f(n)→p_n (Conj. Hardy-Litt.) │")
linha(" │ L3: O sieve reduz (77-99%) mas NÃO elimina o teste │")
linha(" │ L4: Fn(p) não prediz se p é gêmeo ou solitário │")
linha(" └───────────────────────────────────────────────────────────────┘")
linha()
# ── RODAPÉ
linha(SEP)
linha(f" OFFELLIA_ONDA v1.0 — Fim do Relatório")
linha(f" N={N:,} | {len(primos):,} primos | {t_busca:.6f} s")
linha(SEP)
with open(arquivo, "w", encoding="utf-8") as fh:
fh.write("\n".join(L) + "\n")
return arquivo
# ══════════════════════════════════════════════════════════════════════
# INTERFACE PRINCIPAL
# ══════════════════════════════════════════════════════════════════════
def run():
SEP = "═" * 76
SEP2 = "─" * 76
print()
print(SEP)
print(" OFFELLIA_ONDA v1.0")
print(" Busca de Primos pela Onda Única Irracional")
print()
print(f" Ψ(x) = sin²(2πφx) φ = {PHI:.10f}")
print(f" Fase: f(x) = (φ·x) mod 1 | 3 distâncias de Steinhaus")
print(f" 12 janelas por ciclo de 42 | 96 classes mod 420 | 5 canais gêmeos")
print(SEP)
print()
# ── Entrada
try:
entrada = input(" Buscar primos até N: ").strip()
N = int(entrada)
except (ValueError, EOFError):
N = 10000
if N < 2:
print(" N deve ser ≥ 2.")
return
print()
print(f" Iniciando busca até N = {N:,} ...")
print(f" Varredura das 12 janelas em ordem de fase (Fibonacci) ...")
print()
# ── Busca
t0 = time.perf_counter()
primos = list(gerar_primos_onda(N))
t_busca = time.perf_counter() - t0
primos_set = set(primos)
# ── Resumo imediato
print(SEP)
print(f" RESULTADO DA BUSCA")
print(SEP2)
print(f" N buscado: {N:>15,}")
print(f" Primos encontrados: {len(primos):>15,}")
print(f" Tempo total: {t_busca:>15.6f} s")
if t_busca > 0:
print(f" Velocidade: {len(primos)/t_busca:>15,.0f} primos/s")
print(SEP2)
if primos:
gemeos = [(p, p+2) for p in primos if p+2 in primos_set and p > 7]
fn_todos = [onda(p) for p in primos if p > 7]
media_fn = sum(fn_todos) / len(fn_todos) if fn_todos else 0
print(f" Maior primo: {primos[-1]:>15,}")
print(f" Pares gêmeos: {len(gemeos):>15,}")
print(f" Fn médio (Weyl→0.5): {media_fn:>15.8f}")
print()
# Resumo dos 5 canais
print(f" Distribuição pelos 5 canais gêmeos:")
for (r1, r2), nome in CANAIS_GEMEOS.items():
cnt = sum(1 for p, q in gemeos if p % 42 == r1)
print(f" Canal {nome}: {cnt:,}")
print()
# Últimos 5 primos
print(f" Últimos 5 primos encontrados:")
for p in primos[-5:]:
fn = onda(p); f = fase(p)
no = tipo_no(fn)
gem = "✓ gêmeo" if (p+2 in primos_set or p-2 in primos_set) else ""
print(f" {p:>12,} fase={f:.6f} Fn={fn:.5f} [{no}] {gem}")
print()
# ── Relatório
nome_arq = f"onda_relatorio_{N}.txt"
print(f" Gerando relatório completo: '{nome_arq}' ...")
gerar_relatorio(N, primos, t_busca, nome_arq)
print(f" ✓ Relatório salvo em '{nome_arq}'")
print()
print(SEP)
if __name__ == "__main__":
run()