BioSight/python/phi/embed.py
allaun 295130c078 feat(dna): align layer naming and integrate SilverSight receipt verification
- Aligned layer naming and numbering (1 to 4) with the formal Lean specifications in SilverSight.
- Implemented phi.silversight to verify rule ordering, N=8 necessity, and Lean compilation status.
- Integrated SilverSight validation checks into equation_dna_encoder.py and rigour_pipeline.py.

Build: 3307 jobs, 0 errors (lake build)
2026-06-27 22:51:03 -05:00

226 lines
8.7 KiB
Python

"""
phi.embed — Core Φ embedding: (F, τ, δ) → 30-base hachimoji DNA
Combines all four layers into a single encoding pass. This is the
only module that knows about the hachimoji alphabet and the DNA
sequence layout.
DNA layout (30 bases total):
bases 0-7: Layer 1: F(E) — byte-class frequencies (first 8 of 12 classes)
bases 8-15: Layer 2: τ(E) — parse tree node-type frequencies (first 8 of 18 classes)
bases 16-23: Layer 3: δ(E) — child-ordering frequencies (first 8 of 648 dimensions)
bases 24-29: Layer 4: Consistency rules (G=pass, T=fail)
Dependencies: phi.charclass, phi.ast_parse, phi.consistency
"""
from __future__ import annotations
import hashlib
import os
import sys
from typing import Dict, List, Optional
# Allow direct execution without package context
if not __package__:
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)) or ".")
from charclass import compute_F
from ast_parse import compute_tau, compute_delta, compute_lambda_and_r, NODE_TYPES
from consistency import check_consistency, RULE_ORDER
else:
from .charclass import compute_F
from .ast_parse import compute_tau, compute_delta, compute_lambda_and_r, NODE_TYPES
from .consistency import check_consistency, RULE_ORDER
# ── Hachimoji alphabet ───────────────────────────────────────────────────
HACHIMOJI_BASES = list("ABCGPSTZ")
INDEX_TO_BASE = dict(enumerate(HACHIMOJI_BASES))
BASE_TO_INDEX = {b: i for i, b in enumerate(HACHIMOJI_BASES)}
# ── Float-to-base conversion ─────────────────────────────────────────────
def _float_to_3bit(x: float) -> int:
"""Quantize a float in [0, 1] to a 3-bit integer in {0..7}.
Maps the unit interval onto 8 discrete values via ``round(x * 7)``,
then clamps to [0, 7]. Each integer maps to one of the 8 hachimoji
bases via INDEX_TO_BASE.
Args:
x: Float in [0, 1] (values outside are silently clamped).
Returns:
Integer in {0, 1, 2, 3, 4, 5, 6, 7}.
Examples:
>>> _float_to_3bit(0.0)
0
>>> _float_to_3bit(1.0)
7
"""
return min(7, max(0, round(x * 7)))
def _vec_to_bases(values: List[float]) -> str:
"""Map a list of floats in [0, 1] to hachimoji DNA bases.
Each float is independently quantized to a 3-bit index via
``_float_to_3bit``, then mapped through INDEX_TO_BASE so that:
{0 → A, 1 → B, 2 → C, 3 → G, 4 → P, 5 → S, 6 → T, 7 → Z}
Args:
values: Sequence of floats in [0, 1].
Returns:
String of hachimoji bases, one per input value.
Examples:
>>> _vec_to_bases([0.0, 1.0])
'AZ'
"""
return "".join(INDEX_TO_BASE[_float_to_3bit(v)] for v in values)
# ── Core encoding ────────────────────────────────────────────────────────
def encode_phi(equation: str) -> Optional[Dict]:
"""Apply Φ mapping: equation string → 30-base hachimoji DNA sequence.
The four layers are:
1. Layer 1: F(E) — byte-class frequencies on Δ₇ (bases 0-7)
2. Layer 2: τ(E) — AST node-type frequencies (bases 8-15)
3. Layer 3: δ(E) — child-ordering frequencies (bases 16-23)
4. Layer 4: Consistency rules (bases 24-29)
Returns a dict with the DNA sequence and all intermediate values,
or None if the equation is empty.
The returned dict is the standard Φ encoding record consumed by
phi.output (FASTQ, Adleman graph, PCR protocol).
Examples:
>>> r = encode_phi("x + 1")
>>> r is not None
True
>>> r['length']
30
>>> all(c in 'ABCGPSTZ' for c in r['dna_sequence'])
True
>>> r['consistency_dna'] == r['dna_sequence'][-6:]
True
>>> r['schema']
'phi_embedding_v2'
>>> encode_phi("") is None
True
"""
if not equation or not equation.strip():
return None
F = compute_F(equation)
consistency = check_consistency(equation)
tau = compute_tau(equation)
delta = compute_delta(equation)
lambda_val, r = compute_lambda_and_r(equation)
# Fallback for unparseable equations: uniform distribution
# (encodes as all-A — "null structural signal")
if tau is None:
tau = [1.0 / len(NODE_TYPES)] * len(NODE_TYPES)
# Encode each layer as exactly 8 hachimoji bases
F_dna = _vec_to_bases(F[:8])
tau_dna = _vec_to_bases(tau[:8] if tau else [0.5]*8)
delta_dna = _vec_to_bases((delta + [0.5]*8)[:8] if delta else [0.5]*8)
# Layer 4: encode consistency G=pass T=fail
consistency_dna = "".join("G" if consistency[r] else "T" for r in RULE_ORDER)
full_sequence = F_dna + tau_dna + delta_dna + consistency_dna
quality_scores = "".join("A" if v else "P" for v in consistency.values())
seq_hash = hashlib.sha256(full_sequence.encode()).hexdigest()[:16]
return {
"equation": equation,
"dna_sequence": full_sequence,
"length": len(full_sequence),
"bases": list(HACHIMOJI_BASES),
"schema": "phi_embedding_v2",
"F": [round(x, 4) for x in F],
"tau": [round(x, 4) for x in tau],
"delta": [round(x, 4) for x in delta] if delta else None,
"lambda": lambda_val,
"r": r,
"F_dna": F_dna,
"tau_dna": tau_dna,
"delta_dna": delta_dna,
"consistency": consistency,
"consistency_pass": all(consistency.values()),
"consistency_dna": consistency_dna,
"quality_scores": quality_scores,
"sha256_prefix": seq_hash,
"pas_primer": "CCCCCC",
"fail_primer": "AAAAAA",
}
if __name__ == "__main__":
# ──────────────────────────────────────────────────────────────────────
# Verification block — run with python -m phi.embed
# ──────────────────────────────────────────────────────────────────────
# --- _float_to_3bit ---------------------------------------------------
assert _float_to_3bit(0.0) == 0, f"_float_to_3bit(0.0) = {_float_to_3bit(0.0)}"
assert _float_to_3bit(1.0) == 7, f"_float_to_3bit(1.0) = {_float_to_3bit(1.0)}"
mid = _float_to_3bit(0.5)
assert mid in (3, 4), f"_float_to_3bit(0.5) = {mid}, expected 3 or 4"
# --- _vec_to_bases ----------------------------------------------------
vb = _vec_to_bases([0.0, 1.0, 0.5])
assert len(vb) == 3, f"Expected 3 bases, got {len(vb)}"
assert vb[0] == INDEX_TO_BASE[0], f"First base {vb[0]} != A"
assert vb[1] == INDEX_TO_BASE[7], f"Second base {vb[1]} != Z"
assert all(c in HACHIMOJI_BASES for c in vb), f"Invalid base in {vb}"
# --- encode_phi (simple equation) --------------------------------------
r = encode_phi("x + 1")
assert r is not None, "encode_phi('x + 1') returned None"
assert r["length"] == 30, f"length = {r['length']}, expected 30"
assert len(r["dna_sequence"]) == 30, \
f"dna_sequence len = {len(r['dna_sequence'])}, expected 30"
assert all(c in HACHIMOJI_BASES for c in r["dna_sequence"]), \
f"Unknown base in {r['dna_sequence']}"
# consistency_dna is the last 6 bases
assert r["consistency_dna"] == r["dna_sequence"][-6:], \
f"consistency_dna mismatch: {r['consistency_dna']} vs {r['dna_sequence'][-6:]}"
# Sub-field lengths
assert len(r["F_dna"]) == 8, f"F_dna len = {len(r['F_dna'])}"
assert len(r["tau_dna"]) == 8, f"tau_dna len = {len(r['tau_dna'])}"
assert len(r["delta_dna"]) == 8, f"delta_dna len = {len(r['delta_dna'])}"
# Schema
assert r["schema"] == "phi_embedding_v2", \
f"schema = {r['schema']}, expected phi_embedding_v2"
# --- Empty string ------------------------------------------------------
assert encode_phi("") is None, "encode_phi('') should be None"
assert encode_phi(" ") is None, "encode_phi(' ') should be None"
# --- Determinism -------------------------------------------------------
r1 = encode_phi("sin(x) + cos(y)")
r2 = encode_phi("sin(x) + cos(y)")
assert r1 is not None and r2 is not None
assert r1["dna_sequence"] == r2["dna_sequence"], \
f"Determinism broken: {r1['dna_sequence']} != {r2['dna_sequence']}"
assert r1["sha256_prefix"] == r2["sha256_prefix"], \
f"Determinism broken for hash: {r1['sha256_prefix']} != {r2['sha256_prefix']}"
print("embed: all verification assertions passed.")