# FindMoleculeSubstructure fails on SMARTS MoleculePattern, but MoleculePlot is OK?

Background Info: SMARTS is a convention for specifying molecular patterns. It is supported by Mathematica 12's MoleculePattern function.

Problem Setup: Consider MoleculePattern["[!#6;!#1;!H0]"]] This means "match atoms that are not carbon and not hydrogen and have more than zero hydrogens attached."

What seems to work OK: The Molecule["CNO"] has two atoms satisfying that pattern, and indeed, MoleculePlot correctly highlights both the nitrogen and oxygen atoms:

MoleculePlot[
Molecule["CNO"],
MoleculePattern["[!#6;!#1;!H0]"]]


What seems to be a problem: FindMoleculeSubstructure does not find both atoms; it incorrectly only finds the nitrogen (atom 2) but not the oxygen:

FindMoleculeSubstructure[
Molecule["CNO"],
MoleculePattern["[!#6;!#1;!H0]"]]


{<|1 -> 2|>}

(the returned association means "pattern 1 matched by atom 2 in the molecule)

Updated: I think this is an error with the arguments/documentation for FindMoleculeSubstructure. The documentation says that providing no third argument searches for all matches, but if I add the third argument, then I find the correct number of matches. For example:

FindMoleculeSubstructure[
Molecule["CNO"],
MoleculePattern["[!#6;!#1;!H0]"],
10]


{<|1 -> 2|>, <|1 -> 3|>}

(which is correct)

Gratuitous additional examples: This appears to occurs with other MoleculePattern types. The exact same type of problem (two matches correctly found with MoleculePlot, but only one found with FindMoleculeSubstructure) also occurs with MoleculePattern["[C;H3,H4]"]] for Molecule["CCC"], as well as the same "fix".

FindMoleculeSubstructure is modeled after FindGraphIsomorphism, and by default returns only a single match. The third argument controls how many mappings are returned.

In[14]:= FindMoleculeSubstructure[
Molecule @ "CNO",
MoleculePattern @ "[!#6;!#1;!H0]",
All
]

Out[14]= {<|1 -> 2|>, <|1 -> 3|>}


n has to have a default value, it can't be $$\infty$$ because you can easily ask for matches on a very general pattern and get way too many back.

In[12]:= Length@
FindMoleculeSubstructure[
Molecule[Entity["Chemical", "FullereneC60"]],
MoleculePattern["*.*.*"], All]

Out[12]= 34220

• Makes total sense. Perhaps there is an opportunity to clarify the documentation? ?FindMoleculeSubstructure says that "FindMoleculeSubstructure[mol,patt] finds a mapping between the atom indices in mol and all occurrences of patt in mol." – Joshua Schrier Dec 18 '19 at 14:52
• I will change the wording on the usage messages, you are right. – Jason B. Dec 18 '19 at 18:36