/// <inheritdoc/> public override int Contribution(int u, Graph g, ICycle cycle, BitArray cyclic) { if (!cyclic[u]) { return(-1); } IAtom atom = g.GetAtom(u); Element elem = atom.Element; // the element isn't allow to be aromatic (Daylight spec) if (!elem.IsAromatic(Element.AromaticSpecification.Daylight) || elem == Element.Unknown) { return(-1); } // count cyclic and acyclic double bonds int nCyclic = 0, nAcyclic = 0; int deg = g.Degree(u) + g.ImplHCount(u); Edge acyclic = null; int sum = 0; foreach (var e in g.GetEdges(u)) { sum += e.Bond.Order; if (e.Bond.Order == 2) { if (!cyclic[e.Other(u)]) { nAcyclic++; acyclic = e; } else { nCyclic++; } } } int charge = atom.Charge; int valence = sum + g.ImplHCount(u); if (!atom.Element.Verify(valence, charge)) { return(-1); } if (deg > 3) { return(-1); } if (nCyclic > 1) { return(-1); } if (nCyclic == 1 && nAcyclic == 1) { // [P|N](=O)(=*)* - note arsenic not allowed if ((elem == Nitrogen || elem == Phosphorus) && g.GetAtom(acyclic.Other(u)).Element == Oxygen) { return(1); } return(-1); } else if (nCyclic == 1 && nAcyclic == 0) { // any element (except Arsenic) with a single cyclic double bond // contributes 1 p electron return(elem != Arsenic ? 1 : -1); } else if (nCyclic == 0 && nAcyclic == 1) { // a cyclic exo-cyclic double bond - how many electrons determine // by AcyclicContribution() return(AcyclicContribution(atom, g.GetAtom(acyclic.Other(u)), charge)); } else if (nCyclic == 0 && nAcyclic == 0 && charge > -3) { // no double bonds - do we have any lone pairs to contribute? int v = Valence(elem, charge); if (v - sum >= 2 && charge <= 0) { return(2); } if (charge == 1 && atom.Element == Carbon) { return(0); } } return(-1); }