Пример #1
0
        public void QueryMatch()
        {
            BondMatcher matcher = BondMatcher.CreateQueryMatcher();
            var         m_bond1 = new Mock <IQueryBond>(); IQueryBond bond1 = m_bond1.Object;
            var         m_bond2 = new Mock <IBond>(); IBond bond2 = m_bond2.Object;
            var         m_bond3 = new Mock <IBond>(); IBond bond3 = m_bond3.Object;

            m_bond1.Setup(n => n.Matches(bond2)).Returns(true);
            m_bond1.Setup(n => n.Matches(bond3)).Returns(false);
            Assert.IsTrue(matcher.Matches(bond1, bond2));
            Assert.IsFalse(matcher.Matches(bond1, bond3));
        }
Пример #2
0
        public void AliphaticStrictMatch()
        {
            BondMatcher matcher = BondMatcher.CreateStrictOrderMatcher();
            var         m_bond1 = new Mock <IBond>(); IBond bond1 = m_bond1.Object;
            var         m_bond2 = new Mock <IBond>(); IBond bond2 = m_bond2.Object;

            m_bond1.SetupGet(n => n.IsAromatic).Returns(false);
            m_bond2.SetupGet(n => n.IsAromatic).Returns(false);
            m_bond1.SetupGet(n => n.Order).Returns(BondOrder.Single);
            m_bond2.SetupGet(n => n.Order).Returns(BondOrder.Single);
            Assert.IsTrue(matcher.Matches(bond1, bond2));
            Assert.IsTrue(matcher.Matches(bond2, bond1));
        }
Пример #3
0
        public void AnyMatch()
        {
            BondMatcher matcher = BondMatcher.CreateAnyMatcher();
            IBond       bond1   = new Mock <IBond>().Object;
            IBond       bond2   = new Mock <IBond>().Object;
            IBond       bond3   = new Mock <IBond>().Object;

            Assert.IsTrue(matcher.Matches(bond1, bond2));
            Assert.IsTrue(matcher.Matches(bond2, bond1));
            Assert.IsTrue(matcher.Matches(bond1, bond3));
            Assert.IsTrue(matcher.Matches(bond1, null));
            Assert.IsTrue(matcher.Matches(null, null));
        }
Пример #4
0
 /// <summary>
 /// Verify that for every vertex adjacent to n, there should be at least one
 /// feasible candidate adjacent which can be mapped. If no such candidate
 /// exists the mapping of n -> m is not longer valid.
 /// </summary>
 /// <param name="n">query vertex</param>
 /// <param name="m">target vertex</param>
 /// <returns>mapping is still valid</returns>
 private bool Verify(int n, int m)
 {
     foreach (var n_prime in g1[n])
     {
         bool found = false;
         foreach (var m_prime in g2[m])
         {
             if (matrix.Get1(n_prime, m_prime) && bondMatcher.Matches(bond1[n, n_prime], bonds2[m, m_prime]))
             {
                 found = true;
                 break;
             }
         }
         if (!found)
         {
             return(false);
         }
     }
     return(true);
 }
Пример #5
0
        /// <summary>
        /// Check the feasibility of the candidate pair {n, m}.
        /// </summary>
        /// <remarks>
        /// <para>
        /// A candidate pair is
        /// syntactically feasible iff all k-look-ahead rules hold. These look ahead
        /// rules check adjacency relation of the mapping. If an edge is mapped in g1
        /// it should also be mapped in g2 and vise-versa (0-look-ahead). If an edge
        /// in g1 is unmapped but the edge is adjacent to an another mapped vertex
        /// (terminal) then the number of such edges should be less or equal in g1
        /// compared to g2 (1-look-ahead). If the edge is unmapped and non-terminal
        /// then the number of such edges should be less or equal in g1 compared to
        /// g2 (2-look-ahead).
        /// </para>
        /// <para>
        /// The above feasibility rules are for
        /// subgraph-isomorphism and have been adapted for subgraph-monomorphism. For
        /// a monomorphism a mapped edge in g2 does not have to be present in g1. The
        /// 2-look-ahead also requires summing the terminal and remaining counts (or
        /// sorting the vertices).
        /// </para>
        /// <para>
        /// The semantic feasibility verifies that the
        /// labels the label n, m are compatabile and that the label on each matched
        /// edge is compatabile.
        /// </para>
        /// </remarks>
        /// <param name="n">a candidate vertex from g1</param>
        /// <param name="m">a candidate vertex from g2</param>
        /// <returns>the mapping is feasible</returns>
        public override bool Feasible(int n, int m)
        {
            // verify atom semantic feasibility
            if (!atomMatcher.Matches(container1.Atoms[n], container2.Atoms[m]))
            {
                return(false);
            }

            // unmapped terminal vertices n and m are adjacent to
            int nTerminal1 = 0, nTerminal2 = 0;
            // unmapped non-terminal (remaining) vertices n and m are adjacent to
            int nRemain1 = 0, nRemain2 = 0;

            // 0-look-ahead: check each adjacent edge for being mapped, and count
            // terminal or remaining
            foreach (var n_prime in g1[n])
            {
                var m_prime = m1[n_prime];

                // v is already mapped, there should be an edge {m, w} in g2.
                if (m_prime != UNMAPPED)
                {
                    var bond2 = bonds2[m, m_prime];
                    if (bond2 == null) // the bond is not present in the target
                    {
                        return(false);
                    }
                    // verify bond semantic feasibility
                    if (!bondMatcher.Matches(bonds1[n, n_prime], bond2))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (t1[n_prime] > 0)
                    {
                        nTerminal1++;
                    }
                    else
                    {
                        nRemain1++;
                    }
                }
            }

            // monomorphism: each mapped edge in g2 doesn't need to be in g1 so
            // only the terminal and remaining edges are counted
            foreach (var m_prime in g2[m])
            {
                if (m2[m_prime] == UNMAPPED)
                {
                    if (t2[m_prime] > 0)
                    {
                        nTerminal2++;
                    }
                    else
                    {
                        nRemain2++;
                    }
                }
            }

            // 1-look-ahead : the mapping {n, m} is feasible iff the number of
            // terminal vertices (t1) adjacent to n is less than or equal to the
            // number of terminal vertices (t2) adjacent to m.
            //
            // 2-look-ahead: the mapping {n, m} is feasible iff the number of
            // vertices adjacent to n that are neither in m1 or t1 is less than or
            // equal to the number of the number of vertices adjacent to m that
            // are neither in m2 or t2. To allow mapping of monomorphisms we add the
            // number of adjacent terminal vertices.
            return(nTerminal1 <= nTerminal2 && (nRemain1 + nTerminal1) <= (nRemain2 + nTerminal2));
        }
Пример #6
0
        /// <summary>
        /// Check the feasibility of the candidate pair {n, m}. A candidate pair is
        /// syntactically feasible iff all k-look-ahead rules hold. These look ahead
        /// rules check adjacency relation of the mapping. If an edge is mapped in g1
        /// it should also be mapped in g2 and vise-versa (0-look-ahead). If an edge
        /// in g1 is unmapped but the edge is adjacent to an another mapped vertex
        /// (terminal) then the number of such edges should be equal in g1 compared
        /// to g2 (1-look-ahead). If the edge is unmapped and non-terminal then the
        /// number of such edges should be equal in g1 compared to g2 (2-look-ahead).
        /// </summary>
        /// <param name="n">a candidate vertex from g1</param>
        /// <param name="m">a candidate vertex from g2</param>
        /// <returns>the mapping is feasible</returns>
        public override bool Feasible(int n, int m)
        {
            // verify atom semantic feasibility
            if (!atomMatcher.Matches(container1.Atoms[n], container2.Atoms[m]))
            {
                return(false);
            }

            // unmapped terminal vertices n and m are adjacent to
            int nTerminal1 = 0, nTerminal2 = 0;
            // unmapped non-terminal (remaining) vertices n and m are adjacent to
            int nRemain1 = 0, nRemain2 = 0;

            // 0-look-ahead: check each adjacent edge for being mapped, and count
            // terminal or remaining
            foreach (var n_prime in g1[n])
            {
                int m_prime = m1[n_prime];

                // v is already mapped, there should be an edge {m, w} in g2.
                if (m_prime != UNMAPPED)
                {
                    IBond bond2 = bonds2[m, m_prime];
                    // the bond is not present in the target
                    if (bond2 == null)
                    {
                        return(false);
                    }
                    // verify bond semantic feasibility
                    if (!bondMatcher.Matches(bonds1[n, n_prime], bond2))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (t1[n_prime] > 0)
                    {
                        nTerminal1++;
                    }
                    else
                    {
                        nRemain1++;
                    }
                }
            }

            // 0-look-ahead: check each adjacent edge for being mapped, and count
            // terminal or remaining
            foreach (var m_prime in g2[m])
            {
                int n_prime = m2[m_prime];

                if (n_prime != UNMAPPED)
                {
                    IBond bond1 = bonds1[n, n_prime];
                    // the bond is not present in the query
                    if (bond1 == null)
                    {
                        return(false);
                    }
                    // verify bond semantic feasibility
                    if (!bondMatcher.Matches(bond1, bonds2[m, m_prime]))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (t2[m_prime] > 0)
                    {
                        nTerminal2++;
                    }
                    else
                    {
                        nRemain2++;
                    }
                }
            }

            // 1-look-ahead : the mapping {n, m} is feasible iff the number of
            // terminal vertices (t1) adjacent to n is equal to the
            // number of terminal vertices (t2) adjacent to m.
            //
            // 2-look-ahead: the mapping {n, m} is feasible iff the number of
            // vertices adjacent to n that are neither in m1 or t1 is equal to
            // the number of the number of vertices adjacent to m that are neither
            // in m2 or t2.
            return(nTerminal1 == nTerminal2 && nRemain1 == nRemain2);
        }