BioSight/python/phi/charclass.py
allaun e0b2283972 feat(phi): full docstring + verification hardening pass
Every function in all 5 phi modules now has:
- Google-style docstring with Args/Returns/Examples
- Verified behavior via doctest examples (46 total)
- Self-verification assertion blocks on direct execution

Verification results:
  charclass: 10 doctests, 16 assertions  — PASS
  ast_parse: 21 doctests, 7 assertions   — PASS
  consistency: 6 assertions               — PASS
  embed: multiple assertions              — PASS
  output: 15 doctests, 16 assertions      — PASS
  CLI wrapper: 3 checks                   — PASS
  End-to-end: 9 equation domains          — PASS

Also added:
- .opencode/opencode.jsonc (gemma4 MCP config)
- phi/AGENTS.md (module-level contract)
- phi/test_phi.py (unittest test file)
- phi/encoding_rationale.md (design docs)
- dag/ (project dependency graph)
- harness/ (Lean formalism constraints)
- 7-Pipeline/ (rigour verification harness)

Build: python3 -W error -m py_compile — 0 warnings
2026-06-24 03:57:50 -05:00

182 lines
6.1 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 — the first component
of the Φ embedding.
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. This is Layer 1 of the Φ embedding.
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")