orthonym.data.group_split_rules#

Note

Internal API. Names and behaviour may change between releases.

a phase Plan-01: Group-split topology-table loader.

Loads group_split_rules.json — the locked, TOPOLOGY-ONLY split-decomposition table (internal notes /) — into a Dict[str, SplitRule] keyed by fg_name.

The split fires at the polyfunctional.py:get_fg_prefix_form / substituent_no_prefix_form site (internal notes /F2 — a coarse string path, NOT an IR tree visitor). When a non-principal composite functional group has no clean strict-IUPAC prefix and would otherwise be dropped, the splitter (Plan-02) decomposes it into its component sub-prefixes per the topology recorded here.

Single source of truth (internal notes): this table records ONLY the decomposition TOPOLOGY — which sub-fragments (chalcogen / heteroatom linker) the composite splits into, and a resolves_via pointer naming the existing fg_name / dispatcher key whose seniority.PREFIX_FORMS / assembly.substituent_prefix_forms entry supplies the prefix STRING at runtime. The prefix output strings (oxo, the alkoxy/sulfanyl forms,…) are NEVER stored here — duplicating them would fork the authority and invite drift.

Frozen-dataclass discipline mirrors a phase SACRED + a phase’s triviality_controller_seed.py: SplitRule / SplitComponent are @dataclass(frozen=True) and are never mutated after construction.

Graceful degradation (PATTERNS correction): a missing JSON or schema error degrades SPLIT_RULES to {} so the Plan-02 splitter sees no rules and every substituent_no_prefix_form still drops (status quo) — never a crash. This is the no-crash invariant.

Self-contained loader (PATTERNS NOTE): the Phase-168 seed precedent uses its OWN module, NOT a data/__init__.py merge — this module mirrors that path and does not touch data/__init__.py.

Source: 169-internal notes,,,; internal notes section “The #1 Gate” + “Code Examples”; internal notes “data/group_split_rules.json + loader”.

class orthonym.data.group_split_rules.SplitComponent(role, resolves_via, bond=None, atom=None)#

Bases: object

One sub-fragment a composite FG decomposes into (TOPOLOGY ONLY).

resolves_via names the existing fg_name / dispatcher key whose PREFIX_FORMS / substituent_prefix_forms entry supplies the prefix STRING at runtime — the string itself is never stored here (internal notes).

role: str#
resolves_via: str#
bond: str | None = None#
atom: str | None = None#
class orthonym.data.group_split_rules.SplitRule(fg_name, composite_smarts, components, encoding, iupac_p_section, opsin_rt_verified_at, notes)#

Bases: object

One locked split-decomposition entry, keyed by fg_name (internal notes).

Immutable by a phase SACRED discipline. Holds ONLY topology + provenance — no prefix output strings (internal notes).

fg_name: str#
composite_smarts: str#
components: Tuple[SplitComponent, ...]#
encoding: str#
iupac_p_section: str#
opsin_rt_verified_at: str#
notes: str#
orthonym.data.group_split_rules.load_split_rules(json_path, *, validate=False)#

Load the topology table into an fg_name-keyed dict.

Warns (does not fail) if the table’s rdkit_version_pin differs from the running RDKit — re-run scripts/lint_group_split_rules.py --rt to re-confirm round-trips (mirrors the a phase R-10 warning).

With validate=True additionally runs the internal notes design-time OPSIN-RT re-confirmation of each entry’s documented example (off by default — runs at CI lint time, not at every import). Raises ValueError on the first entry that fails to round-trip. Raises the JSON-load errors on a malformed file (caught by the module-load wrapper below).