orthonym.assembly.handlers.tier_a_ring#

Note

Internal API. Names and behaviour may change between releases.

a phase Plan-06 composite handler: Tier-A ring cascade.

Per internal notes (gap-closure) + -02 Option A: encodes the Tier-A pool-compete cascade as a SINGLE composite handler so the dispatch_inner first-match-wins interface (internal notes) stays untouched.

LIFT SOURCE: composer.py:996-1322 (verbatim, with return pool.best.name or return candidate_name replaced by return NamingResult(name=..., tree=<coarse NameTreeNode>, atom_to_locant_hint=None) — a phase SCORE-01 attaches a coarse tree at EVERY return site, including the early returns).

Internal cascade order (preserved verbatim from composer.py inline body): 1. complex_ring detection + assembly (composer.py:1014-1066) — pushed to pool 2. polycyclic fallback when complex_ring rejected (composer.py:1083-1098) — direct return 3. partial_sat fallback when complex_ring rejected (composer.py:1103-1110) — direct return 4. heterocycle + lactone safety net (composer.py:1122-1152) 5. benzene (composer.py:1159-1173) 6. a phase chain push-to-pool (composer.py:1185-1192) 7. select_best_candidate selector + handler-level stereo injection (composer.py:1197-1305)

Returns None if all sub-paths fall through AND no Tier-A candidate ratio gate accepted. The surrounding dispatch_inner loop then continues to general_acyclic catch-all (Plan-08).

CRITICAL PRESERVATION CONSTRAINTS: - The _tier_a_pool_count_before_complex slicing pattern at

composer.py:1197 MUST be preserved verbatim per a phase + the PHASE 146 PRESERVE block at composer.py:964-994.

  • The two inject_stereo_from_locant_map call sites (composer.py:1301) are part of this composite per internal notes + a phase layering.

  • assemble_ion_name pre-pool bypass (composer.py:751-768) is NOT in this composite — that’s the outer pre-pool path before dispatch_inner runs per internal notes.

IUPAC cite: (principal chain vs ring competition).

orthonym.assembly.handlers.tier_a_ring.name_tier_a_ring(features, mol=None, style='pin')#

Composite handler encoding the Tier-A pool-compete cascade.

Per -02 + internal notes: dispatch_inner cannot natively model pool-compete semantics; this composite encodes the full cascade in one entry while keeping dispatch_inner first-match-wins interface unchanged (internal notes).

Two early-return paths preserved verbatim from composer.py:996-1322: - The lactone safety-net path (composer.py:1126-1136) returns the

lactone name directly.

  • The polycyclic / partial_sat post-rejection fallback paths (composer.py:1083-1110) return their handler name directly.

Byte-identical preservation per DECOMP-03: every pool.add call, the _tier_a_pool_count_before_complex slicing pattern, the del _tier_a_pool._candidates[...] truncation, and the handler-level stereo-injection block are preserved verbatim.

Returns:

NamingResult –

selector chose a candidate OR an early-return

sub-path produced a name.

None: all sub-paths fell through AND the selector rejected the

Tier-A subset (low-ratio rescue did not fire).

Return type:

NamingResult | None