mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
- SDPVerify.lean: certificate verification engine (714 lines, compiles cleanly) - GoormaghtighCert.lean: Goormaghtigh conjecture SDP certificate - HachimojiManifoldAxiom/HachimojiSubstitution: Hachimoji DNA encoding - GeneticBraidBridge.lean: genetic algorithm braid bridge - load_dependency_graph/load_module_graph: Gremlin Cosmos DB graph loaders - test_graph_queries/rrc_math_xref: graph verification queries - Gremlin mathblob DB provisioned and accessible - Branch cleanup: deleted 11 stale remote branches Build: 3297 jobs, 0 errors (lake build Semantics.SDPVerify)
513 lines
18 KiB
Python
513 lines
18 KiB
Python
#!/usr/bin/env python3
|
|
"""GeneticBraidBridge — map ANY genetic alphabet to BraidState.
|
|
|
|
Accepts DNA, RNA, mRNA, Hachimoji (8-letter), XNA (16-letter hex),
|
|
6-state (genetic ground-up), and custom alphabets. Each symbol maps to a
|
|
braid generator on one of 8 strands (BraidStorm topology). Codons compose
|
|
into braid words. The bridge emits a BraidState JSON ready for:
|
|
- eigensolid_convergence (Lean)
|
|
- receipt_invertible (Lean)
|
|
- RRC classification (LogogramProjection)
|
|
- crossStep iteration
|
|
- Sidon slack measurement
|
|
|
|
Usage:
|
|
python3 genetic_braid_bridge.py --alphabet dna --seq ATGCCGTAA
|
|
python3 genetic_braid_bridge.py --alphabet hachimoji --seq ACGTZPSB
|
|
python3 genetic_braid_bridge.py --alphabet xna --seq 0123456789ABCDEF
|
|
python3 genetic_braid_bridge.py --alphabet rna --seq AUGCCGUAA --translate
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import math
|
|
import sys
|
|
from dataclasses import dataclass, field, asdict
|
|
from typing import Optional
|
|
|
|
|
|
# ── Canonical BraidStorm constants ──────────────────────────────────────
|
|
|
|
SIDON_LABELS: list[int] = [1, 2, 4, 8, 16, 32, 64, 128]
|
|
N_STRANDS = 8
|
|
|
|
# Golden ratio inverse Q16_16: φ⁻¹ ≈ 0x00009E70
|
|
PHI_INV_Q16 = 0x9E70
|
|
|
|
|
|
# ── Genetic alphabet definitions ────────────────────────────────────────
|
|
|
|
@dataclass(frozen=True)
|
|
class GeneticAlphabet:
|
|
name: str
|
|
symbols: str
|
|
bits_per_symbol: int
|
|
strand_map: dict[str, int] # symbol → strand index (0..N_STRANDS-1)
|
|
complement_map: dict[str, str]
|
|
codon_length: int = 3
|
|
description: str = ""
|
|
|
|
|
|
# Strand-to-Sidon mapping:
|
|
# Each symbol claims a primary strand; the braid generator crosses
|
|
# that strand with its pair (strand ^ 1).
|
|
# For alphabets ≤4, symbols map to strands 0-3 (4 pairs).
|
|
# For alphabets ≤8, symbols map to strands 0-7 (4 pairs).
|
|
# For 16-letter alphabets, symbols map in pairs to strands 0-7.
|
|
|
|
def _build_4sym_strand_map(symbols: str) -> dict[str, int]:
|
|
return {s: i for i, s in enumerate(symbols)}
|
|
|
|
def _build_8sym_strand_map(symbols: str) -> dict[str, int]:
|
|
return {s: i for i, s in enumerate(symbols)}
|
|
|
|
def _build_16sym_strand_map(symbols: str) -> dict[str, int]:
|
|
return {s: i % 8 for i, s in enumerate(symbols)}
|
|
|
|
|
|
ALPHABETS: dict[str, GeneticAlphabet] = {
|
|
"dna": GeneticAlphabet(
|
|
name="dna",
|
|
symbols="ACGT",
|
|
bits_per_symbol=2,
|
|
strand_map=_build_4sym_strand_map("ACGT"),
|
|
complement_map={"A": "T", "C": "G", "G": "C", "T": "A"},
|
|
codon_length=3,
|
|
description="Standard DNA: 4 bases, 64 codons (NCBI Table 1)",
|
|
),
|
|
"rna": GeneticAlphabet(
|
|
name="rna",
|
|
symbols="ACGU",
|
|
bits_per_symbol=2,
|
|
strand_map=_build_4sym_strand_map("ACGU"),
|
|
complement_map={"A": "U", "C": "G", "G": "C", "U": "A"},
|
|
codon_length=3,
|
|
description="RNA: 4 bases, catalytic/regulatory",
|
|
),
|
|
"mrna": GeneticAlphabet(
|
|
name="mrna",
|
|
symbols="ACGU",
|
|
bits_per_symbol=2,
|
|
strand_map=_build_4sym_strand_map("ACGU"),
|
|
complement_map={"A": "U", "C": "G", "G": "C", "U": "A"},
|
|
codon_length=3,
|
|
description="mRNA: messenger RNA, same alphabet as RNA",
|
|
),
|
|
"hachimoji": GeneticAlphabet(
|
|
name="hachimoji",
|
|
symbols="ACGTZPSB",
|
|
bits_per_symbol=3,
|
|
strand_map=_build_8sym_strand_map("ACGTZPSB"),
|
|
complement_map={
|
|
"A": "T", "C": "G", "G": "C", "T": "A",
|
|
"Z": "P", "P": "Z", "S": "B", "B": "S",
|
|
},
|
|
codon_length=3,
|
|
description="Hachimoji: 8 bases, 512 codons (Benner et al.)",
|
|
),
|
|
"xna": GeneticAlphabet(
|
|
name="xna",
|
|
symbols="0123456789ABCDEF",
|
|
bits_per_symbol=4,
|
|
strand_map=_build_16sym_strand_map("0123456789ABCDEF"),
|
|
complement_map={}, # no canonical complement for generic XNA
|
|
codon_length=2,
|
|
description="XNA: 16-symbol hex, 256 2-codons",
|
|
),
|
|
"genetic6": GeneticAlphabet(
|
|
name="genetic6",
|
|
symbols="ACGTUX",
|
|
bits_per_symbol=3,
|
|
strand_map=_build_8sym_strand_map("ACGTUX"), # uses 6 of 8 strands
|
|
complement_map={"A": "U", "C": "G", "G": "C", "U": "A", "X": "X"},
|
|
codon_length=3,
|
|
description="6-state quantum nucleotide (A/C/G/T/U/X from GeneticGroundUp)",
|
|
),
|
|
}
|
|
|
|
|
|
# ── Sidon / Braid Core ──────────────────────────────────────────────────
|
|
|
|
@dataclass
|
|
class BraidStrand:
|
|
phase_x: int = 0
|
|
phase_y: int = 0
|
|
slot: int = 0
|
|
residue: int = 0
|
|
jitter: int = 0
|
|
bracket_lower: int = 0
|
|
bracket_upper: int = 0
|
|
bracket_gap: int = 0
|
|
bracket_kappa: int = 0
|
|
bracket_phi: int = 0
|
|
admissible: bool = True
|
|
|
|
|
|
@dataclass
|
|
class BraidState:
|
|
strands: list[BraidStrand] = field(default_factory=lambda: [BraidStrand() for _ in range(N_STRANDS)])
|
|
step_count: int = 0
|
|
|
|
|
|
def _xor_slot(a: int, b: int) -> int:
|
|
return a ^ b
|
|
|
|
|
|
def _braid_cross(si: BraidStrand, sj: BraidStrand) -> tuple[BraidStrand, int]:
|
|
"""Simulate braidCross: merge two strands, return merged strand + residual."""
|
|
zx = si.phase_x + sj.phase_x
|
|
zy = si.phase_y + sj.phase_y
|
|
slot = _xor_slot(si.slot, sj.slot)
|
|
residue = abs(zx - si.phase_x) + abs(zy - si.phase_y)
|
|
jitter = si.jitter + sj.jitter
|
|
|
|
merged = BraidStrand(
|
|
phase_x=zx, phase_y=zy, slot=slot,
|
|
residue=residue, jitter=jitter,
|
|
admissible=True,
|
|
)
|
|
return merged, residue
|
|
|
|
|
|
def cross_step(state: BraidState) -> BraidState:
|
|
"""One BraidStorm crossStep iteration on 4 adjacent pairs."""
|
|
def _cross_pair(i: int, j: int) -> BraidStrand:
|
|
merged, _ = _braid_cross(state.strands[i], state.strands[j])
|
|
return merged
|
|
|
|
pairs = [(0, 1), (2, 3), (4, 5), (6, 7)]
|
|
new_strands = list(state.strands)
|
|
for i, j in pairs:
|
|
new_strands[i] = _cross_pair(i, j)
|
|
new_strands[j] = _braid_cross(state.strands[j], state.strands[i])[0]
|
|
|
|
return BraidState(strands=new_strands, step_count=state.step_count + 1)
|
|
|
|
|
|
def is_eigensolid(state: BraidState) -> bool:
|
|
"""Check if crossStep(state) == state (strand data unchanged)."""
|
|
stepped = cross_step(state)
|
|
for i in range(N_STRANDS):
|
|
s1 = state.strands[i]
|
|
s2 = stepped.strands[i]
|
|
if (s1.phase_x != s2.phase_x or s1.phase_y != s2.phase_y or
|
|
s1.slot != s2.slot or s1.residue != s2.residue):
|
|
return False
|
|
return True
|
|
|
|
|
|
def iterate_to_convergence(state: BraidState, max_steps: int = 100) -> BraidState:
|
|
"""Apply crossStep until eigensolid or max_steps."""
|
|
for _ in range(max_steps):
|
|
if is_eigensolid(state):
|
|
break
|
|
state = cross_step(state)
|
|
return state
|
|
|
|
|
|
# ── Genetic → Braid translation ────────────────────────────────────────
|
|
|
|
def normalize_sequence(alphabet: GeneticAlphabet, seq: str) -> str:
|
|
allowed = set(alphabet.symbols)
|
|
clean = "".join(ch.upper() for ch in seq if not ch.isspace())
|
|
bad = sorted({ch for ch in clean if ch not in allowed})
|
|
if bad:
|
|
raise ValueError(f"{alphabet.name}: unsupported symbols: {''.join(bad)}")
|
|
return clean
|
|
|
|
|
|
def symbols_to_braid_word(alphabet: GeneticAlphabet, seq: str) -> list[tuple[int, int]]:
|
|
"""Map a genetic sequence to a list of (strand_i, strand_j) crossings.
|
|
|
|
Each symbol maps to its assigned strand. The braid generator crosses
|
|
that strand with its pair (strand ^ 1). Codons (3 symbols) produce
|
|
3 crossings that engage their respective strand pairs.
|
|
"""
|
|
clean = normalize_sequence(alphabet, seq)
|
|
word: list[tuple[int, int]] = []
|
|
for sym in clean:
|
|
s = alphabet.strand_map[sym]
|
|
word.append((s, s ^ 1))
|
|
return word
|
|
|
|
|
|
def braid_word_to_state(word: list[tuple[int, int]], initial_slots: Optional[list[int]] = None) -> BraidState:
|
|
"""Apply a braid word to an initial BraidState.
|
|
|
|
Each crossing (i, j) XORs the slots and accumulates phase.
|
|
"""
|
|
slots = list(initial_slots) if initial_slots else list(SIDON_LABELS)
|
|
strands = [BraidStrand(slot=slots[i]) for i in range(N_STRANDS)]
|
|
state = BraidState(strands=strands, step_count=0)
|
|
|
|
for i, j in word:
|
|
merged, _ = _braid_cross(state.strands[i], state.strands[j])
|
|
state.strands[i] = merged
|
|
|
|
return state
|
|
|
|
|
|
def sequence_to_braid_state(
|
|
alphabet: GeneticAlphabet,
|
|
seq: str,
|
|
initial_slots: Optional[list[int]] = None,
|
|
) -> tuple[BraidState, list[tuple[int, int]]]:
|
|
"""Full pipeline: genetic sequence → braid word → BraidState."""
|
|
word = symbols_to_braid_word(alphabet, seq)
|
|
state = braid_word_to_state(word, initial_slots)
|
|
return state, word
|
|
|
|
|
|
# ── Receipt emission ────────────────────────────────────────────────────
|
|
|
|
def encode_receipt(state: BraidState, alphabet: GeneticAlphabet,
|
|
seq: str, seq_hash: str, word: list[tuple[int, int]],
|
|
logogram_hash: str = "",
|
|
) -> dict:
|
|
"""Emit a genetic braid receipt JSON.
|
|
|
|
Matches BraidReceipt structure from BraidEigensolid.lean:
|
|
crossing_matrix, sidon_slack, step_count, residuals, write_time, scar_absent
|
|
"""
|
|
strand0 = state.strands[0]
|
|
strand7 = state.strands[7]
|
|
sidon_slack = 128 - strand7.slot
|
|
|
|
residuals = [s.residue for s in state.strands]
|
|
|
|
max_slot = max(s.slot for s in state.strands)
|
|
max_slot_index = max(range(N_STRANDS), key=lambda i: state.strands[i].slot)
|
|
|
|
receipt = {
|
|
"schema": "genetic_braid_receipt_v1",
|
|
"generated_at_utc": __import__("datetime").datetime.utcnow().isoformat() + "Z",
|
|
|
|
"genetic": {
|
|
"alphabet": alphabet.name,
|
|
"symbols": alphabet.symbols,
|
|
"codon_length": alphabet.codon_length,
|
|
"sequence_length": len(seq),
|
|
"sequence_hash_sha256": seq_hash,
|
|
"sequence": seq if len(seq) <= 200 else seq[:100] + "...[truncated]..." + seq[-100:],
|
|
},
|
|
|
|
"braid": {
|
|
"word_length": len(word),
|
|
"sidon_labels": SIDON_LABELS,
|
|
"sidon_slack": max(0, sidon_slack),
|
|
"max_slot_used": max_slot,
|
|
"max_slot_strand": max_slot_index,
|
|
"slots": [s.slot for s in state.strands],
|
|
"residues": residuals,
|
|
"residue_sum": sum(residuals),
|
|
},
|
|
|
|
"receipt": {
|
|
"crossing_matrix": {
|
|
"lower": strand0.bracket_lower,
|
|
"upper": strand0.bracket_upper,
|
|
"gap": strand0.bracket_gap,
|
|
"kappa": strand0.bracket_kappa,
|
|
"phi": strand0.bracket_phi,
|
|
"admissible": strand0.admissible,
|
|
},
|
|
"sidon_slack": max(0, sidon_slack),
|
|
"step_count": state.step_count,
|
|
"residuals": residuals,
|
|
"write_time": 0,
|
|
"scar_absent": all(s.admissible for s in state.strands),
|
|
},
|
|
|
|
"meta_solid": {
|
|
"sidon_doublings_total": 7,
|
|
"sidon_doublings_consumed": int(math.log2(max(max_slot, 1))).bit_length()
|
|
if max_slot > 0 else 0,
|
|
"capacity_ratio": round(max_slot / 128.0, 4) if max_slot > 0 else 0,
|
|
},
|
|
|
|
"logogram_hash_sha256": logogram_hash or seq_hash,
|
|
"claim_boundary": "genetic-to-braid-bridge;no-lean-spectral;no-classifier",
|
|
}
|
|
|
|
preimage = json.dumps(receipt, sort_keys=True)
|
|
receipt["receipt_hash_sha256"] = hashlib.sha256(preimage.encode()).hexdigest()
|
|
return receipt
|
|
|
|
|
|
# ── Codon tables ────────────────────────────────────────────────────────
|
|
|
|
CODON_TABLES: dict[str, dict[str, str]] = {
|
|
"standard": {
|
|
"TTT": "Phe", "TTC": "Phe", "TTA": "Leu", "TTG": "Leu",
|
|
"TCT": "Ser", "TCC": "Ser", "TCA": "Ser", "TCG": "Ser",
|
|
"TAT": "Tyr", "TAC": "Tyr", "TAA": "Stop", "TAG": "Stop",
|
|
"TGT": "Cys", "TGC": "Cys", "TGA": "Stop", "TGG": "Trp",
|
|
"CTT": "Leu", "CTC": "Leu", "CTA": "Leu", "CTG": "Leu",
|
|
"CCT": "Pro", "CCC": "Pro", "CCA": "Pro", "CCG": "Pro",
|
|
"CAT": "His", "CAC": "His", "CAA": "Gln", "CAG": "Gln",
|
|
"CGT": "Arg", "CGC": "Arg", "CGA": "Arg", "CGG": "Arg",
|
|
"ATT": "Ile", "ATC": "Ile", "ATA": "Ile", "ATG": "Met",
|
|
"ACT": "Thr", "ACC": "Thr", "ACA": "Thr", "ACG": "Thr",
|
|
"AAT": "Asn", "AAC": "Asn", "AAA": "Lys", "AAG": "Lys",
|
|
"AGT": "Ser", "AGC": "Ser", "AGA": "Arg", "AGG": "Arg",
|
|
"GTT": "Val", "GTC": "Val", "GTA": "Val", "GTG": "Val",
|
|
"GCT": "Ala", "GCC": "Ala", "GCA": "Ala", "GCG": "Ala",
|
|
"GAT": "Asp", "GAC": "Asp", "GAA": "Glu", "GAG": "Glu",
|
|
"GGT": "Gly", "GGC": "Gly", "GGA": "Gly", "GGG": "Gly",
|
|
},
|
|
}
|
|
|
|
|
|
# ── CLI ─────────────────────────────────────────────────────────────────
|
|
|
|
def _build_arg_parser() -> argparse.ArgumentParser:
|
|
p = argparse.ArgumentParser(description=__doc__)
|
|
p.add_argument("--alphabet", choices=sorted(ALPHABETS), default="dna",
|
|
help="Genetic alphabet")
|
|
p.add_argument("--seq", default="",
|
|
help="Genetic sequence (raw text)")
|
|
p.add_argument("--seq-file", default="",
|
|
help="Read sequence from file (FASTA or raw)")
|
|
p.add_argument("--codon-table", choices=list(CODON_TABLES),
|
|
help="Codon translation table")
|
|
p.add_argument("--translate", action="store_true",
|
|
help="Translate to amino acids (requires --codon-table or standard)")
|
|
p.add_argument("--complement", action="store_true",
|
|
help="Show complement sequence")
|
|
p.add_argument("--converge", action="store_true",
|
|
help="Run crossStep to eigensolid convergence")
|
|
p.add_argument("--output", default="",
|
|
help="Write receipt JSON to file")
|
|
p.add_argument("--table", action="store_true",
|
|
help="List supported alphabets")
|
|
return p
|
|
|
|
|
|
def main() -> int:
|
|
args = _build_arg_parser().parse_args()
|
|
|
|
if args.table:
|
|
rows = []
|
|
for name, alpha in sorted(ALPHABETS.items()):
|
|
rows.append({
|
|
"name": alpha.name,
|
|
"symbols": alpha.symbols,
|
|
"bits_per_symbol": alpha.bits_per_symbol,
|
|
"codon_length": alpha.codon_length,
|
|
"n_codons": len(alpha.symbols) ** alpha.codon_length,
|
|
"description": alpha.description,
|
|
})
|
|
print(json.dumps(rows, indent=2))
|
|
return 0
|
|
|
|
alphabet = ALPHABETS[args.alphabet]
|
|
|
|
# Read sequence
|
|
seq = args.seq
|
|
if args.seq_file:
|
|
with open(args.seq_file) as f:
|
|
content = f.read().strip()
|
|
if content.startswith(">"):
|
|
lines = content.splitlines()
|
|
seq = "".join(l for l in lines[1:] if not l.startswith(">"))
|
|
else:
|
|
seq = content
|
|
|
|
if not seq:
|
|
print("Error: no sequence provided (use --seq or --seq-file)", file=sys.stderr)
|
|
return 1
|
|
|
|
seq = normalize_sequence(alphabet, seq)
|
|
seq_hash = hashlib.sha256(seq.encode()).hexdigest()
|
|
|
|
# Complement
|
|
if args.complement:
|
|
comp = "".join(alphabet.complement_map.get(s, s) for s in seq)
|
|
print(f"Complement: {comp}")
|
|
return 0
|
|
|
|
# Translation
|
|
if args.translate:
|
|
table_name = args.codon_table or "standard"
|
|
table = CODON_TABLES.get(table_name, {})
|
|
if not table:
|
|
print(f"Error: unknown codon table '{table_name}'", file=sys.stderr)
|
|
return 1
|
|
|
|
# Convert T→U for RNA alphabets
|
|
working_seq = seq
|
|
if alphabet.name in ("rna", "mrna"):
|
|
working_seq = working_seq.replace("T", "U")
|
|
|
|
codons = [working_seq[i:i+3] for i in range(0, len(working_seq) - 2, 3)]
|
|
aa_seq = []
|
|
for codon in codons:
|
|
aa = table.get(codon, "?")
|
|
aa_seq.append(aa)
|
|
if aa == "Stop":
|
|
break
|
|
|
|
print(f"Sequence ({alphabet.name}, {len(seq)} bp):")
|
|
print(f" {seq}")
|
|
print(f"Translation ({table_name}):")
|
|
print(f" {'-'.join(aa_seq)}")
|
|
|
|
degeneracy_map = {
|
|
"Phe": 2, "Leu": 6, "Ile": 3, "Met": 1, "Val": 4,
|
|
"Ser": 6, "Pro": 4, "Thr": 4, "Ala": 4, "Tyr": 2,
|
|
"His": 2, "Gln": 2, "Asn": 2, "Lys": 2, "Asp": 2,
|
|
"Glu": 2, "Cys": 2, "Trp": 1, "Arg": 6, "Gly": 4,
|
|
"Stop": 3,
|
|
}
|
|
degeneracies = [degeneracy_map.get(aa, 0) for aa in aa_seq]
|
|
avg_degeneracy = round(sum(degeneracies) / max(len(degeneracies), 1), 2)
|
|
print(f"\nAvg degeneracy: {avg_degeneracy}")
|
|
|
|
# Braid bridge
|
|
state, word = sequence_to_braid_state(alphabet, seq)
|
|
|
|
if args.converge:
|
|
initial_state = BraidState(
|
|
strands=[BraidStrand(slot=SIDON_LABELS[i]) for i in range(N_STRANDS)],
|
|
step_count=0,
|
|
)
|
|
pre_state, pre_word = sequence_to_braid_state(alphabet, seq)
|
|
state = iterate_to_convergence(pre_state)
|
|
|
|
receipt = encode_receipt(state, alphabet, seq, seq_hash, word)
|
|
|
|
receipt["sidon_meta"] = {
|
|
"standard_code_capacity_pct": round(64 / 128 * 100, 1),
|
|
"actual_capacity_pct": round(max(s.slot for s in state.strands) / 128 * 100, 1),
|
|
"sidon_doublings_consumed": int(math.log2(max(max(s.slot for s in state.strands), 1))) + 1,
|
|
"slack_regime": _classify_slack(state),
|
|
}
|
|
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
json.dump(receipt, f, indent=2)
|
|
print(f"Receipt written to {args.output}")
|
|
else:
|
|
print(json.dumps(receipt, indent=2))
|
|
|
|
return 0
|
|
|
|
|
|
def _classify_slack(state: BraidState) -> str:
|
|
max_slot = max(s.slot for s in state.strands)
|
|
slack = 128 - max_slot
|
|
if slack >= 64:
|
|
return "gas (abundant slack, sparse encoding)"
|
|
elif slack >= 8:
|
|
return "liquid (moderate slack, efficient encoding)"
|
|
elif slack > 0:
|
|
return "meta-solid (tight encoding, near capacity)"
|
|
else:
|
|
return "solid (capacity exceeded, compression regime)"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|