BioSight/python/phi/charclass.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

184 lines
6.3 KiB
Python
Raw 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.

"""
phi.charclass — Layer 1: Character classification → Δ₁₁ byte histogram
Each ASCII or TeX character maps to 1 of 12 archetypal classes. The histogram
over these 12 classes is the F(E) feature vector. Note that the 30-base DNA layout
maps only the first 8 classes (indices 0-7) to Layer 1 (bases 0-7) as defined by
SilverSight's HachimojiCharClass.lean.
Dependencies: none (stdlib only)
"""
from __future__ import annotations
from typing import List
# ── 12 character classes ─────────────────────────────────────────────────
# Each class corresponds to a dimension of Δ₁₁ (the 11-simplex).
# The classes partition the visible ASCII range into 12 bins.
CHAR_CLASSES = {
"digit": 0, # 0-9
"lower_alpha": 1, # a-z
"upper_alpha": 2, # A-Z
"operator": 3, # + - * / ^ % = < > ! & | ~
"bracket": 4, # ( ) [ ] { }
"punctuation": 5, # . , ; : ' " @ # $ _ \
"whitespace": 6, # space, tab, newline
"other": 7, # everything else (Greek, Unicode math, etc.)
"symmetry": 8, # = $\approx$ $\equiv$ $\sim$
"periodicity": 9, # $\pi$ $\infty$ $\theta$ $\lambda$
"continuity": 10, # $\rightarrow$ $\Delta$ $\nabla$ $\int$
"meta_math": 11, # $\sqrt{}$ $\sum$ $\prod$ $\partial$
}
OPERATOR_CHARS = set("+-*/^%=<>!&|~")
BRACKET_CHARS = set("()[]{}")
PUNCT_CHARS = set(".,;:'\"@#$\\")
def classify_char(c: str) -> int:
"""Classify a single character into 1 of 12 archetypal classes (0-11).
The 12 classes partition the visible ASCII and common TeX range:
+------+--------------+-------------------------------+
| Class | Name | Characters |
+------+--------------+-------------------------------+
| 0 | digit | 0-9 |
| 1 | lower_alpha | a-z |
| 2 | upper_alpha | A-Z |
| 3 | operator | + - * / ^ % = < > ! & | ~ |
| 4 | bracket | ( ) [ ] { } |
| 5 | punctuation | . , ; : ' \" @ # $ \\\\ _ |
| 6 | whitespace | space, tab, newline, CR |
| 7 | other | Unicode, non-ASCII, unassigned |
| 8 | symmetry | ≈ ≡ |
| 9 | periodicity | π θ λ ∞ |
| 10 | continuity | → Δ ∇ ∫ |
| 11 | meta_math | √ ∑ ∏ ∂ |
+------+--------------+-------------------------------+
Args:
c: A single-character string.
Returns:
An integer 0-11 identifying the character's class.
Examples:
>>> classify_char("3")
0
>>> classify_char("x")
1
>>> classify_char("X")
2
>>> classify_char("+")
3
>>> classify_char(")")
4
>>> classify_char(".")
5
>>> classify_char(" ")
6
>>> classify_char("©")
7
"""
if c.isdigit():
return 0
if c.isalpha():
return 1 if c.islower() else 2
# Operator chars
if c in "+-*/^%=<>!&|~":
return 3
# Bracket chars
if c in "()[]{}":
return 4
# Punctuation
if c in ".,;:'\"@#$\\":
return 5
# Whitespace
if c in (" ", "\t", "\n", "\r"):
return 6
# Other (General)
if c in "$\\pi\\theta\\lambda\\infty$": # Periodicity
return 9
if c in "$\\rightarrow\\Delta\\nabla\\int$": # Continuity
return 10
if c in "=$\\approx\\equiv\\sim$": # Symmetry
return 8
if c in "$\\sqrt{}\\sum\\prod\\partial$": # Meta-math
return 11
return 7
def compute_F(equation: str) -> List[float]:
"""Compute F(E) — normalized byte-class histogram on Δ₁₂.
Returns 12 floats summing to 1.0. The first 8 classes (indices 0-7)
map directly to Layer 1 of the Φ DNA embedding (bases 0-7).
Pure function: no state, no side effects.
Examples:
>>> result = compute_F("x + 1")
>>> round(sum(result), 10)
1.0
"""
counts = [0] * 12
for c in equation:
counts[classify_char(c)] += 1
total = sum(counts)
if total == 0:
return [1.0 / 12] * 12
return [c / total for c in counts]
if __name__ == "__main__":
import math
# ── 1. Test every character class ─────────────────────────────────────
assert classify_char("0") == 0
assert classify_char("9") == 0
assert classify_char("a") == 1
assert classify_char("z") == 1
assert classify_char("A") == 2
assert classify_char("Z") == 2
assert classify_char("+") == 3
assert classify_char("*") == 3
assert classify_char("(") == 4
assert classify_char("}") == 4
assert classify_char(".") == 5
assert classify_char(",") == 5
assert classify_char(" ") == 6
assert classify_char("\t") == 6
assert classify_char("\n") == 6
assert classify_char("©") == 7 # non-ASCII, non-alpha → other
# ── 2. compute_F output sums to 1.0 for various equations ─────────────
for eq in ["x + 1", "E = mc^2", "a = b = c", "12345", " ", "((()))"]:
result = compute_F(eq)
assert len(result) == 12
assert abs(sum(result) - 1.0) < 1e-10, f"F({eq!r}) sum = {sum(result)}"
# ── 3. Edge cases ─────────────────────────────────────────────────────
# Empty string → uniform distribution
assert compute_F("") == [1.0 / 12] * 12
# All-same-class string
F_digits = compute_F("12345")
assert abs(F_digits[0] - 1.0) < 1e-10
# Mixed content
F_mixed = compute_F("a1 + b2")
assert abs(sum(F_mixed) - 1.0) < 1e-10
# ── 4. classify_char returns int in 0..11 for every printable ASCII ───
for code in range(32, 127):
c = chr(code)
cls = classify_char(c)
assert 0 <= cls <= 11, f"char {c!r} (code {code}) class {cls} out of 0..11"
assert isinstance(cls, int)
print("charclass.py: all verifications PASSED")