third_party/inchi/INCHI_BASE/src/ichicans.c
AT_RANK PathsHaveIdenticalKnownParities( sp_ATOM       *at,
                                         AT_RANK       prev1,
                                         AT_RANK       cur1,
                                         AT_RANK       prev2,
                                         AT_RANK       cur2,
                                         AT_RANK       *nVisited1,
                                         AT_RANK       *nVisited2,
                                         const AT_RANK *nRank,
                                         const AT_RANK *nCanonRank,
                                         AT_RANK       nLength )
{
    int k;
    AT_RANK n1, n2;

    nLength++;   /*  number of successfully traversed pairs of atoms */
    nVisited1[cur1] = nLength;
    nVisited2[cur2] = nLength;

    /*  the atoms must be either both stereogenic and have well-defined parities or non-stereogenic at all. */
    if (at[cur1].stereo_atom_parity != at[cur2].stereo_atom_parity ||
         at[cur1].stereo_atom_parity && !PARITY_WELL_DEF( at[cur1].stereo_atom_parity )
          )
    {
        return 0;  /*  Reject: Different or unknown in advance parities */
    }

    if (at[cur1].valence != at[cur2].valence)
    {
        return 0;  /*  program error */ /*   <BRKPT> */
    }

    if (at[cur1].valence == 1)
    {
        return nLength; /*  so far success */
    }


    for (k = 1, n1 = MAX_ATOMS + 1, n2 = MAX_ATOMS + 1; k < at[cur1].valence; k++)
    {
        /*  start from 1: since we do not go back, we have only (at[cur1].valence-1) bonds to try */

        if (!GetAndCheckNextNeighbors( at, cur1, prev1, cur2, prev2,
            &n1, &n2, nVisited1, nVisited2,
            nRank, nCanonRank ))
        {
            return 0; /*  different neighbors                       */
        }

        /*  In a DFS we do not traverse already visited atoms */
        if (!nVisited1[n1])
        {
            /*  recursion */
            if (!( nLength = PathsHaveIdenticalKnownParities( at, cur1, n1, cur2, n2, nVisited1, nVisited2, nRank, nCanonRank, nLength ) ))
            {
                return 0;
            }
        }
    }

    /*  To be on a safe side, recheck after all nVisited[] have been set */
    for (k = 1, n1 = MAX_ATOMS + 1, n2 = MAX_ATOMS + 1; k < at[cur1].valence; k++)
    {
        /*  start from 1: since we do not go back, we have only (at[cur1].valence-1) bonds to try */
        if (!GetAndCheckNextNeighbors( at, cur1, prev1, cur2, prev2,
            &n1, &n2, nVisited1, nVisited2,
            nRank, nCanonRank ))
        {
            return 0; /*  different neighbors */
        }
    }

    return nLength;
}
/********************************************************************************************/
/*  Simultaneously DFS-traverse 2 paths starting at the bonds prev1->cur1 and prev2->cur2   */
/*  The two paths MUST go through the pairs of constitutionally identical atoms,            */
/*  each atom being on one path.                                                            */
/*  Reject if encountered atoms having currently unknown (without breaking ties)            */
/*      parities or having different known or unknown or undefined parities.                */
/*  Save length of the path into nVisited[cur. atom number].                                */
/*  Only one nVisited[] array is sufficient because the paths from the beginning are        */
/*  in different ring systems.                                                              */
/********************************************************************************************/
Simultaneously DFS-traverse 2 paths starting at the bonds prev1->cur1 and prev2->cur2
The two paths MUST go through the pairs of constitutionally identical atoms,
each atom being on one path.
Reject if encountered atoms having currently unknown (without breaking ties)
parities or having different known or unknown or undefined parities.
Save length of the path into nVisited[cur. atom number].
Only one nVisited[] array is sufficient because the paths from the beginning are
in different ring systems.
Simultaneously DFS - traverse 2 paths starting at the bonds prev1 - > cur1 and prev2 - > cur2 The two paths MUST go through the pairs of constitutionally identical atoms each atom being on one path . Reject if encountered atoms having currently unknown ( without breaking ties ) parities or having different known or unknown or undefined parities . Save length of the path into nVisited [ cur . atom number ] . Only one nVisited [] array is sufficient because the paths from the beginning are in different ring systems .
AT_RANK PathsHaveIdenticalKnownParities( sp_ATOM       *at,
                                         AT_RANK       prev1,
                                         AT_RANK       cur1,
                                         AT_RANK       prev2,
                                         AT_RANK       cur2,
                                         AT_RANK       *nVisited1,
                                         AT_RANK       *nVisited2,
                                         const AT_RANK *nRank,
                                         const AT_RANK *nCanonRank,
                                         AT_RANK       nLength )
{
    int k;
    AT_RANK n1, n2;
    nLength++;   
    nVisited1[cur1] = nLength;
    nVisited2[cur2] = nLength;
    if (at[cur1].stereo_atom_parity != at[cur2].stereo_atom_parity ||
         at[cur1].stereo_atom_parity && !PARITY_WELL_DEF( at[cur1].stereo_atom_parity )
          )
    {
        return 0;  
    }
    if (at[cur1].valence != at[cur2].valence)
    {
        return 0;   
    }
    if (at[cur1].valence == 1)
    {
        return nLength; 
    }
    for (k = 1, n1 = MAX_ATOMS + 1, n2 = MAX_ATOMS + 1; k < at[cur1].valence; k++)
    {
        if (!GetAndCheckNextNeighbors( at, cur1, prev1, cur2, prev2,
            &n1, &n2, nVisited1, nVisited2,
            nRank, nCanonRank ))
        {
            return 0; 
        }
        if (!nVisited1[n1])
        {
            if (!( nLength = PathsHaveIdenticalKnownParities( at, cur1, n1, cur2, n2, nVisited1, nVisited2, nRank, nCanonRank, nLength ) ))
            {
                return 0;
            }
        }
    }
    for (k = 1, n1 = MAX_ATOMS + 1, n2 = MAX_ATOMS + 1; k < at[cur1].valence; k++)
    {
        if (!GetAndCheckNextNeighbors( at, cur1, prev1, cur2, prev2,
            &n1, &n2, nVisited1, nVisited2,
            nRank, nCanonRank ))
        {
            return 0; 
        }
    }
    return nLength;
}
AT_RANK PathsHaveIdenticalKnownParities ( sp_ATOM * at , AT_RANK prev1 , AT_RANK cur1 , AT_RANK prev2 , AT_RANK cur2 , AT_RANK * nVisited1 , AT_RANK * nVisited2 , const AT_RANK * nRank , const AT_RANK * nCanonRank , AT_RANK nLength ) { int k ; AT_RANK n1 , n2 ; nLength ++ ; nVisited1 [ cur1 ] = nLength ; nVisited2 [ cur2 ] = nLength ; if ( at [ cur1 ] . stereo_atom_parity != at [ cur2 ] . stereo_atom_parity || at [ cur1 ] . stereo_atom_parity && ! PARITY_WELL_DEF ( at [ cur1 ] . stereo_atom_parity ) ) { return 0 ; } if ( at [ cur1 ] . valence != at [ cur2 ] . valence ) { return 0 ; } if ( at [ cur1 ] . valence == 1 ) { return nLength ; } for ( k = 1 , n1 = MAX_ATOMS + 1 , n2 = MAX_ATOMS + 1 ; k < at [ cur1 ] . valence ; k ++ ) { if ( ! GetAndCheckNextNeighbors ( at , cur1 , prev1 , cur2 , prev2 , & n1 , & n2 , nVisited1 , nVisited2 , nRank , nCanonRank ) ) { return 0 ; } if ( ! nVisited1 [ n1 ] ) { if ( ! ( nLength = PathsHaveIdenticalKnownParities ( at , cur1 , n1 , cur2 , n2 , nVisited1 , nVisited2 , nRank , nCanonRank , nLength ) ) ) { return 0 ; } } } for ( k = 1 , n1 = MAX_ATOMS + 1 , n2 = MAX_ATOMS + 1 ; k < at [ cur1 ] . valence ; k ++ ) { if ( ! GetAndCheckNextNeighbors ( at , cur1 , prev1 , cur2 , prev2 , & n1 , & n2 , nVisited1 , nVisited2 , nRank , nCanonRank ) ) { return 0 ; } } return nLength ; }
Simultaneously DFS-traverse 2 paths starting at the bonds prev1->cur1 and prev2->cur2
The two paths MUST go through the pairs of constitutionally identical atoms,
each atom being on one path.
Simultaneously DFS - traverse 2 paths starting at the bonds prev1 - > cur1 and prev2 - > cur2 The two paths MUST go through the pairs of constitutionally identical atoms each atom being on one path .
/*  number of successfully traversed pairs of atoms */ /*  the atoms must be either both stereogenic and have well-defined parities or non-stereogenic at all. */ /*  Reject: Different or unknown in advance parities */ /*  program error */ /*   <BRKPT> */ /*  so far success */ /*  start from 1: since we do not go back, we have only (at[cur1].valence-1) bonds to try */ /*  different neighbors                       */ /*  In a DFS we do not traverse already visited atoms */ /*  recursion */ /*  To be on a safe side, recheck after all nVisited[] have been set */ /*  start from 1: since we do not go back, we have only (at[cur1].valence-1) bonds to try */ /*  different neighbors */