Beispiel #1
0
            /// <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);
            }