"""
phi.charclass — Layer 1: Character classification → Δ₇ byte histogram

Each ASCII character maps to 1 of 8 archetypal classes. The histogram
over these 8 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

# ── 8 character classes ──────────────────────────────────────────────────

# Each class corresponds to a dimension of Δ₇ (the 7-simplex).
# The classes partition the visible ASCII range into 8 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.)
}

OPERATOR_CHARS = set("+-*/^%=<>!&|~")
BRACKET_CHARS = set("()[]{}")
PUNCT_CHARS = set(".,;:'\"@#$ _\\")


def classify_char(c: str) -> int:
    """Classify a single character into 1 of 8 classes (0-7)."""
    if c.isdigit():
        return 0
    if c.isalpha():
        return 1 if c.islower() else 2
    if c in OPERATOR_CHARS:
        return 3
    if c in BRACKET_CHARS:
        return 4
    if c in PUNCT_CHARS:
        return 5
    if c in (" ", "\t", "\n", "\r"):
        return 6
    return 7


def compute_F(equation: str) -> List[float]:
    """Compute F(E) — normalized byte-class histogram on Δ₇.

    Returns 8 floats summing to 1.0. This is Layer 1 of the Φ embedding.

    Pure function: no state, no side effects.
    """
    counts = [0] * 8
    for c in equation:
        counts[classify_char(c)] += 1
    total = sum(counts)
    if total == 0:
        return [1.0 / 8] * 8
    return [c / total for c in counts]
