orthonym.assembly.nested_memo#
Note
Internal API. Names and behaviour may change between releases.
Replay-memo for NESTED naming calls (a performance pass, a lever).
A nested name_compound(...) inside an outer name has three side effects the
outer molecule’s tier and abstention decisions read: (1) the provenance ContextVars
(clear_provenance runs only in name_tiered, and general_ring_prefix /
suffix_free_prefix_name / stereo_unexpressed are set-only), (2) the shared
perf/analysis/work budgets (_budget_scope shares them across nested name),
(3) the return value. A plain memo hit would skip (1) and (2) and could flip the outer
tier or move a PerfBudgetExceeded trip.
This helper reproduces (1) EXACTLY via a provenance TOUCHED-log (a performance pass):
it records which vars the call WROTE — not merely which net-CHANGED — so a var written
to a value it already held, or written A->B->A, is still replayed to the value the fresh
call left (a before/after delta would record it as untouched and leave a stale value on a
later hit in a different ambient context). It records (2) the units each budget lost and
replays them. Scope-bound through assembly.memo (fail-open outside a scope; verify
mode recomputes).
- orthonym.assembly.nested_memo.ambient_naming_state()#
The ambient state a re-entrant naming call branches on besides its SMILES: the fragments being named up the stack (the recursion guard of
name_fragment_recursively), the tier flags of the request, every context variable a naming path reads (the scopes of an N-acyl refusal, a peptide attempt, a split probe, the gate’s re-entry, a forced locant, an isotopic naming, the book-forms switch) and whether an alternate-parent rescue is running. A memo of such a call keys on it, so a hit is served only for the state the stored call ran in. They are the ambient components of the key ofsubstituent_naming.name_substituent_fragment(everything but the molecule, the fragment and its stereo labels) with two left out and one added. Left out: the identity of the fragment memo object (a best-effort clean fall-through opens a fresh one for every attempt) and the session depth (a counter of thenameframes; no naming path reads it to decide a name, the recursion guard is the visited set above). Added: whether an alternate-parent rescue is running, which that key lacks.ORTHONYM_MEMO=verifycompares every hit with a fresh naming.
- orthonym.assembly.nested_memo.cached_nested_call(namespace, key, fn, *, replay_budgets=True)#
Return
fn’s result for(namespace, key); on a hit replay the EXACT provenance vars the call touched and its budget units. Exceptions propagate uncached.Only the RESULT is stored under
namespace(soORTHONYM_MEMO=verifycompares names — an honest incomplete-key oracle); the context-relative replay metadata lives in the scope-bound side store, which verify never compares.replay_budgets=False: a hit replays the provenance only and charges no budget unit. The recorded units are the fresh call’s COLD cost; for a memo placed over a whole-pipeline sub-namer (the peptide substitutive attempts) the unmemoised repeat that a hit stands for runs WARM (the scope’s fragment cache and plain memos already hold its sub-results) and costs almost nothing, so replaying the cold cost on every hit charges the budget for work that neither the memoised nor the unmemoised code does. Measured (ChEBI 12-residue peptides, fresh process): the whole-molecule attempt cost 145 analysis calls cold and 0, 0, 0 on its three unmemoised repeats; the replay charged 4 x 145 and more against the 500-call budget, which then aborted the naming (PerfBudgetExceeded -> abstain). A hit does no work, so it spends none; every fresh computation still charges its own work, so the hang budgets still bound the call.