orthonym.validation.reconstruct#
Note
Internal API. Names and behaviour may change between releases.
Wave 0: OPSIN-free structural verifier.
- Two 0-wrong layers (a structural reconstruction verifier):
has_unverifiable_atoms— the wildcard fail-close predicate (this task).reconstruct_and_verify/verify_or_none— a sound-over-complete name->graph reconstructor + dual oracle (Tasks 2–4).
SOUNDNESS CONTRACT (load-bearing): the reconstructor NEVER falsely CONFIRMs, and
it rebuilds ONLY from name-level facts (NameFacts) that a producer derives
from NAME TOKENS — parent length, replacement/unsaturation locants, the
principal-group key, substituent NAMES. It must NEVER read the input graph to
populate a fact; that would make the compare circular and defeat the point.
On anything it does not model it returns ABSTAINED, never CONFIRMED.
- orthonym.validation.reconstruct.has_unverifiable_atoms(mol)#
True iff mol carries an atom no oracle can verify.
Wave 0 scope: a dummy/wildcard atom (atomic number 0, SMILES
*). Such an atom makes the input InChIKey uncomputable, so the /OPSIN round-trip oracle has no reference and FAILS OPEN — a wildcard input then ships a WRONG molecule (CC*->ethane). Callers must fail closed (abstain) when this returns True. Wave 0 is wildcard only, matchingerrors.classify_scope_limit.
- class orthonym.validation.reconstruct.Verdict(*values)#
Bases:
str,Enum- CONFIRMED = 'confirmed'#
- ABSTAINED = 'abstained'#
- MISMATCH = 'mismatch'#
- ERROR = 'error'#
- class orthonym.validation.reconstruct.ReconResult(verdict: 'Verdict', reason: 'str', reconstructed_smiles: 'Optional[str]' = None)#
Bases:
object- reason: str#
- reconstructed_smiles: str | None = None#
- class orthonym.validation.reconstruct.NameFacts(parent_kind: 'str', parent_length: 'int', replacements: 'tuple' = (), unsaturations: 'tuple' = (), principal_group: 'Optional[tuple]' = None, substituents: 'tuple' = (), indicated_h: 'tuple' = (), net_charge: 'int' = 0, isotopes: 'bool' = False)#
Bases:
object- parent_kind: str#
- parent_length: int#
- replacements: tuple = ()#
- unsaturations: tuple = ()#
- principal_group: tuple | None = None#
- substituents: tuple = ()#
- indicated_h: tuple = ()#
- net_charge: int = 0#
- isotopes: bool = False#
- orthonym.validation.reconstruct.reconstruct_and_verify(name_facts, input_mol)#
Rebuild an RDKit graph from name-facts ALONE and compare constitution.
CONFIRMED only on a full canonical-SMILES byte-match (stereo removed both sides); a constitution difference is MISMATCH; any unmodeled construct raises _Abstain -> ABSTAINED; a top-level exception -> ERROR. NEVER falsely CONFIRMs, NEVER raises.
- orthonym.validation.reconstruct.verify_or_none(name, input_smiles, name_facts=None)#
Dual 0-wrong oracle: return
nameiff it is verified, elseNone.OPSIN-RT, STRICT: if OPSIN parses
nameand its parse-back has the SAME FULL InChIKey as the input (all layers – constitution AND stereo AND charge/tautomer), the name is verified. Full-key, NOT the skeleton block: a skeleton match confirms a neutralised or wrong-enantiomer name (measured), which would be a 0-wrong hole. Strict => a name that omits stereo the input asserts returns None (a safe false-negative, never a false CONFIRM).OPSIN cannot parse
nameANDname_factssupplied: run the reconstructor; CONFIRMED -> verified. This branch is CONSTITUTION-ONLY (Wave-0NameFactshas no stereo fields and_normalizestrips stereo both sides) – it abstains whenever the input asserts defined stereochemistry, since it cannot check what the name claims about it.Otherwise -> None (fail closed). A wildcard input is never verifiable.