Files
OFFELLIA_Quantis/OFFELLIA_ONDA.py
ModelHub XC 86836ec189 初始化项目,由ModelHub XC社区提供模型
Model: Brunobkr/OFFELLIA_Quantis
Source: Original Platform
2026-08-11 10:11:17 +08:00

756 lines
32 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
╔══════════════════════════════════════════════════════════════════════════════╗
║ 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 ""
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) = 1cos(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()